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

difftreelog

Merge branch 'develop' into fix/scheduler-benchmarks

str-mv2022-06-09parents: #c6fcdce #bb7c8cc.patch.diff
in: master

117 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6329,13 +6329,16 @@
 name = "pallet-rmrk-core"
 version = "0.1.0"
 dependencies = [
+ "derivative",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-common",
  "pallet-evm",
  "pallet-nonfungible",
+ "pallet-structure",
  "parity-scale-codec 3.1.2",
+ "rmrk-traits",
  "scale-info",
  "sp-core",
  "sp-runtime",
@@ -6355,6 +6358,7 @@
  "pallet-nonfungible",
  "pallet-rmrk-core",
  "parity-scale-codec 3.1.2",
+ "rmrk-traits",
  "scale-info",
  "sp-core",
  "sp-runtime",
@@ -8577,6 +8581,7 @@
  "pallet-randomness-collective-flip",
  "pallet-refungible",
  "pallet-rmrk-core",
+ "pallet-rmrk-equip",
  "pallet-structure",
  "pallet-sudo",
  "pallet-template-transaction-payment",
@@ -8997,15 +9002,24 @@
 version = "0.0.1"
 dependencies = [
  "parity-scale-codec 2.3.1",
+ "rmrk-traits",
  "serde",
  "sp-api",
  "sp-core",
  "sp-runtime",
  "sp-std",
- "up-data-structs",
 ]
 
 [[package]]
+name = "rmrk-traits"
+version = "0.1.0"
+dependencies = [
+ "parity-scale-codec 3.1.2",
+ "scale-info",
+ "serde",
+]
+
+[[package]]
 name = "rocksdb"
 version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12620,6 +12634,7 @@
  "pallet-randomness-collective-flip",
  "pallet-refungible",
  "pallet-rmrk-core",
+ "pallet-rmrk-equip",
  "pallet-structure",
  "pallet-sudo",
  "pallet-template-transaction-payment",
@@ -12721,6 +12736,7 @@
  "frame-system",
  "pallet-evm",
  "parity-scale-codec 3.1.2",
+ "rmrk-traits",
  "scale-info",
  "serde",
  "sp-core",
modifiedMakefilediffbeforeafterboth
--- a/Makefile
+++ b/Makefile
@@ -105,5 +105,9 @@
 bench-scheduler:
 	make _bench2 PALLET=unq-scheduler PALLET_DIR=scheduler
 
+.PHONY: bench-rmrk-core
+bench-rmrk-core:
+	make _bench PALLET=proxy-rmrk-core
+
 .PHONY: bench
-bench: bench-evm-migration bench-unique bench-structure bench-fungible bench-refungible bench-nonfungible bench-scheduler
+bench: bench-evm-migration bench-unique bench-structure bench-fungible bench-refungible bench-nonfungible bench-scheduler bench-rmrk-core
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -276,14 +276,15 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<ResourceInfo>>;
 
-		#[method(name = "rmrk_nftResourcePriorities")]
-		/// Get NFT resource priorities
-		fn nft_resource_priorities(
+		#[method(name = "rmrk_nftResourcePriority")]
+		/// Get NFT resource priority
+		fn nft_resource_priority(
 			&self,
 			collection_id: RmrkCollectionId,
 			nft_id: RmrkNftId,
+			resource_id: RmrkResourceId,
 			at: Option<BlockHash>,
-		) -> Result<Vec<RmrkResourceId>>;
+		) -> Result<Option<u32>>;
 
 		#[method(name = "rmrk_base")]
 		/// Get base info
@@ -325,6 +326,20 @@
 	}
 }
 
+pub struct Rmrk<C, P> {
+	client: Arc<C>,
+	_marker: std::marker::PhantomData<P>,
+}
+
+impl<C, P> Rmrk<C, P> {
+	pub fn new(client: Arc<C>) -> Self {
+		Self {
+			client,
+			_marker: Default::default(),
+		}
+	}
+}
+
 macro_rules! pass_method {
 	(
 		$method_name:ident(
@@ -473,7 +488,7 @@
 		BaseInfo,
 		PartType,
 		Theme,
-	> for Unique<C, Block>
+	> for Rmrk<C, Block>
 where
 	C: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
 	C::Api: RmrkRuntimeApi<
@@ -522,7 +537,7 @@
 		rmrk_api
 	);
 	pass_method!(nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Vec<ResourceInfo>, rmrk_api);
-	pass_method!(nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Vec<RmrkResourceId>, rmrk_api);
+	pass_method!(nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Option<u32>, rmrk_api);
 	pass_method!(base(base_id: RmrkBaseId) -> Option<BaseInfo>, rmrk_api);
 	pass_method!(base_parts(base_id: RmrkBaseId) -> Vec<PartType>, rmrk_api);
 	pass_method!(theme_names(base_id: RmrkBaseId) -> Vec<RmrkThemeName>, rmrk_api);
modifiedcrates/evm-coder/src/solidity.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity.rs
+++ b/crates/evm-coder/src/solidity.rs
@@ -455,7 +455,7 @@
 	}
 }
 
-#[impl_for_tuples(0, 12)]
+#[impl_for_tuples(0, 24)]
 impl SolidityFunctions for Tuple {
 	for_tuples!( where #( Tuple: SolidityFunctions ),* );
 
modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -187,21 +187,33 @@
 	}};
 }
 
-pub fn development_config() -> OpalChainSpec {
+pub fn development_config() -> DefaultChainSpec {
 	let mut properties = Map::new();
-	properties.insert("tokenSymbol".into(), opal_runtime::TOKEN_SYMBOL.into());
+	properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());
 	properties.insert("tokenDecimals".into(), 18.into());
-	properties.insert("ss58Format".into(), opal_runtime::SS58Prefix::get().into());
+	properties.insert(
+		"ss58Format".into(),
+		default_runtime::SS58Prefix::get().into(),
+	);
 
-	OpalChainSpec::from_genesis(
+	DefaultChainSpec::from_genesis(
 		// Name
-		"OPAL by UNIQUE",
+		format!(
+			"{}{}",
+			default_runtime::RUNTIME_NAME.to_uppercase(),
+			if cfg!(feature = "unique-runtime") {
+				""
+			} else {
+				" by UNIQUE"
+			}
+		)
+		.as_str(),
 		// ID
-		"opal_dev",
+		format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),
 		ChainType::Local,
 		move || {
 			testnet_genesis!(
-				opal_runtime,
+				default_runtime,
 				// Sudo account
 				get_account_id_from_seed::<sr25519::Public>("Alice"),
 				vec![
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -66,10 +66,10 @@
 use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};
 
 // RMRK
-/* TODO free RMRK! use up_data_structs::{
+use up_data_structs::{
 	RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
 	RmrkPartType, RmrkTheme,
-};*/
+};
 
 /// Unique native executor instance.
 #[cfg(feature = "unique-runtime")]
@@ -354,7 +354,6 @@
 		+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
 		+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
 		+ up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
-		/* TODO free RMRK!
 		+ rmrk_rpc::RmrkApi<
 			Block,
 			AccountId,
@@ -365,8 +364,7 @@
 			RmrkBaseInfo<AccountId>,
 			RmrkPartType,
 			RmrkTheme,
-		>*/
-		+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+		> + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
 		+ sp_api::Metadata<Block>
 		+ sp_offchain::OffchainWorkerApi<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>,
@@ -661,7 +659,6 @@
 		+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
 		+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
 		+ up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
-		/* TODO free RMRK!
 		+ rmrk_rpc::RmrkApi<
 			Block,
 			AccountId,
@@ -672,8 +669,7 @@
 			RmrkBaseInfo<AccountId>,
 			RmrkPartType,
 			RmrkTheme,
-		>*/
-		+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+		> + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
 		+ sp_api::Metadata<Block>
 		+ sp_offchain::OffchainWorkerApi<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>
@@ -807,7 +803,6 @@
 		+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
 		+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
 		+ up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
-		/* TODO free RMRK!
 		+ rmrk_rpc::RmrkApi<
 			Block,
 			AccountId,
@@ -818,8 +813,7 @@
 			RmrkBaseInfo<AccountId>,
 			RmrkPartType,
 			RmrkTheme,
-		>*/
-		+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+		> + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
 		+ sp_api::Metadata<Block>
 		+ sp_offchain::OffchainWorkerApi<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -44,10 +44,10 @@
 	Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,
 };
 // RMRK
-/* TODO free RMRK! use up_data_structs::{
+use up_data_structs::{
 	RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
 	RmrkPartType, RmrkTheme,
-};*/
+};
 
 /// Extra dependencies for GRANDPA
 pub struct GrandpaDeps<B> {
@@ -146,7 +146,6 @@
 	C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
 	C::Api: fp_rpc::ConvertTransactionRuntimeApi<Block>,
 	C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,
-	/* TODO free RMRK!
 	C::Api: rmrk_rpc::RmrkApi<
 		Block,
 		AccountId,
@@ -157,7 +156,7 @@
 		RmrkBaseInfo<AccountId>,
 		RmrkPartType,
 		RmrkTheme,
-	>,*/
+	>,
 	B: sc_client_api::Backend<Block> + Send + Sync + 'static,
 	B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
 	P: TransactionPool<Block = Block> + 'static,
@@ -170,7 +169,7 @@
 		Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub,
 		EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer,
 	};
-	use uc_rpc::{UniqueApiServer, Unique};
+	use uc_rpc::{UniqueApiServer, Unique, RmrkApiServer, Rmrk};
 	// use pallet_contracts_rpc::{Contracts, ContractsApi};
 	use pallet_transaction_payment_rpc::{TransactionPaymentRpc, TransactionPaymentApiServer};
 	use substrate_frame_rpc_system::{SystemRpc, SystemApiServer};
@@ -223,10 +222,8 @@
 		.into_rpc(),
 	)?;
 
-	// todo look into
-	//let unique = Unique::new(client.clone());
 	io.merge(Unique::new(client.clone()).into_rpc())?;
-	// TODO free RMRK! io.extend_with(RmrkApi::to_delegate(Unique::new(client.clone())));
+	io.merge(Rmrk::new(client.clone()).into_rpc())?;
 
 	if let Some(filter_pool) = filter_pool {
 		io.merge(
modifiedpallets/common/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/common/src/benchmarking.rs
+++ b/pallets/common/src/benchmarking.rs
@@ -109,7 +109,7 @@
 	create_collection_raw(
 		owner,
 		CollectionMode::NFT,
-		|owner, data| <Pallet<T>>::init_collection(owner, data),
+		|owner, data| <Pallet<T>>::init_collection(owner, data, true),
 		|h| h,
 	)
 }
modifiedpallets/common/src/dispatch.rsdiffbeforeafterboth
--- a/pallets/common/src/dispatch.rs
+++ b/pallets/common/src/dispatch.rs
@@ -11,7 +11,7 @@
 use crate::{pallet::Config, CommonCollectionOperations, CollectionHandle};
 
 // TODO: move to benchmarking
-/// Price of [`dispatch_call`] call with noop `call` argument
+/// Price of [`dispatch_tx`] call with noop `call` argument
 pub fn dispatch_weight<T: Config>() -> Weight {
 	// Read collection
 	<T as frame_system::Config>::DbWeight::get().reads(1)
@@ -21,7 +21,7 @@
 }
 
 /// Helper function to implement substrate calls for common collection methods
-pub fn dispatch_call<
+pub fn dispatch_tx<
 	T: Config,
 	C: FnOnce(&dyn CommonCollectionOperations<T>) -> DispatchResultWithPostInfo,
 >(
@@ -36,6 +36,15 @@
 			},
 			error,
 		})?;
+	handle
+		.check_is_internal()
+		.map_err(|error| DispatchErrorWithPostInfo {
+			post_info: PostDispatchInfo {
+				actual_weight: Some(dispatch_weight::<T>()),
+				pays_fee: Pays::Yes,
+			},
+			error,
+		})?;
 	let dispatched = T::CollectionDispatch::dispatch(handle);
 	let mut result = call(dispatched.as_dyn());
 	match &mut result {
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -22,7 +22,7 @@
 pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
 use pallet_evm_coder_substrate::dispatch_to_evm;
 use sp_std::vec::Vec;
-use up_data_structs::{Property, SponsoringRateLimit};
+use up_data_structs::{Property, SponsoringRateLimit, NestingRule, OwnerRestrictedSet, AccessMode};
 use alloc::format;
 
 use crate::{Pallet, CollectionHandle, Config, CollectionProperties};
@@ -46,7 +46,10 @@
 }
 
 #[solidity_interface(name = "Collection")]
-impl<T: Config> CollectionHandle<T> {
+impl<T: Config> CollectionHandle<T>
+// where
+// 	T::AccountId: From<H256>
+{
 	fn set_collection_property(&mut self, caller: caller, key: string, value: bytes) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let key = <Vec<u8>>::from(key)
@@ -79,25 +82,27 @@
 		Ok(prop.to_vec())
 	}
 
-	fn eth_set_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
+	fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
 		check_is_owner(caller, self)?;
 
 		let sponsor = T::CrossAccountId::from_eth(sponsor);
-		self.set_sponsor(sponsor.as_sub().clone());
-		save(self);
-		Ok(())
+		self.set_sponsor(sponsor.as_sub().clone())
+			.map_err(dispatch_to_evm::<T>)?;
+		save(self)
 	}
 
-	fn eth_confirm_sponsorship(&mut self, caller: caller) -> Result<void> {
+	fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {
 		let caller = T::CrossAccountId::from_eth(caller);
-		if !self.confirm_sponsorship(caller.as_sub()) {
+		if !self
+			.confirm_sponsorship(caller.as_sub())
+			.map_err(dispatch_to_evm::<T>)?
+		{
 			return Err(Error::Revert("Caller is not set as sponsor".into()));
 		}
-		save(self);
-		Ok(())
+		save(self)
 	}
 
-	#[solidity(rename_selector = "setLimit")]
+	#[solidity(rename_selector = "setCollectionLimit")]
 	fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {
 		check_is_owner(caller, self)?;
 		let mut limits = self.limits.clone();
@@ -130,11 +135,10 @@
 		}
 		self.limits = <Pallet<T>>::clamp_limits(self.mode.clone(), &self.limits, limits)
 			.map_err(dispatch_to_evm::<T>)?;
-		save(self);
-		Ok(())
+		save(self)
 	}
 
-	#[solidity(rename_selector = "setLimit")]
+	#[solidity(rename_selector = "setCollectionLimit")]
 	fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {
 		check_is_owner(caller, self)?;
 		let mut limits = self.limits.clone();
@@ -158,16 +162,140 @@
 		}
 		self.limits = <Pallet<T>>::clamp_limits(self.mode.clone(), &self.limits, limits)
 			.map_err(dispatch_to_evm::<T>)?;
-		save(self);
-		Ok(())
+		save(self)
 	}
 
 	fn contract_address(&self, _caller: caller) -> Result<address> {
 		Ok(crate::eth::collection_id_to_address(self.id))
 	}
+
+	// fn add_admin_substrate(&self, caller: caller, new_admin: uint256) -> Result<void> {
+	// 	let mut new_admin_h256 = H256::default();
+	// 	new_admin.to_little_endian(&mut new_admin_h256.0);
+	// 	let account_id = T::AccountId::from(new_admin_h256);
+	// 	let caller = T::CrossAccountId::from_eth(caller);
+	// 	let new_admin = T::CrossAccountId::from_sub(account_id);
+	// 	<Pallet<T>>::toggle_admin(&self, &caller, &new_admin, true)
+	// 		.map_err(dispatch_to_evm::<T>)?;
+	// 	Ok(())
+	// }
+
+	// fn remove_admin_substrate(&self, caller: caller, new_admin: uint256) -> Result<void> {
+	// 	let mut new_admin_h256 = H256::default();
+	// 	new_admin.to_little_endian(&mut new_admin_h256.0);
+	// 	let account_id = T::AccountId::from(new_admin_h256);
+	// 	let caller = T::CrossAccountId::from_eth(caller);
+	// 	let new_admin = T::CrossAccountId::from_sub(account_id);
+	// 	<Pallet<T>>::toggle_admin(&self, &caller, &new_admin, false)
+	// 		.map_err(dispatch_to_evm::<T>)?;
+	// 	Ok(())
+	// }
+
+	fn add_collection_admin(&self, caller: caller, new_admin: address) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		self.check_is_owner_or_admin(&caller)
+			.map_err(dispatch_to_evm::<T>)?;
+		let new_admin = T::CrossAccountId::from_eth(new_admin);
+		<Pallet<T>>::toggle_admin(&self, &caller, &new_admin, true)
+			.map_err(dispatch_to_evm::<T>)?;
+		Ok(())
+	}
+
+	fn remove_collection_admin(&self, caller: caller, admin: address) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		self.check_is_owner_or_admin(&caller)
+			.map_err(dispatch_to_evm::<T>)?;
+		let admin = T::CrossAccountId::from_eth(admin);
+		<Pallet<T>>::toggle_admin(&self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
+		Ok(())
+	}
+
+	#[solidity(rename_selector = "setCollectionNesting")]
+	fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		self.check_is_owner_or_admin(&caller)
+			.map_err(dispatch_to_evm::<T>)?;
+		self.collection.permissions.nesting = Some(match enable {
+			false => NestingRule::Disabled,
+			true => NestingRule::Owner,
+		});
+		save(self)?;
+		Ok(())
+	}
+
+	#[solidity(rename_selector = "setCollectionNesting")]
+	fn set_nesting(
+		&mut self,
+		caller: caller,
+		enable: bool,
+		collections: Vec<address>,
+	) -> Result<void> {
+		if collections.is_empty() {
+			return Err("No addresses provided".into());
+		}
+		if collections.len() >= OwnerRestrictedSet::bound() {
+			return Err(Error::Revert(format!(
+				"Out of bound: {} >= {}",
+				collections.len(),
+				OwnerRestrictedSet::bound()
+			)));
+		}
+		let caller = T::CrossAccountId::from_eth(caller);
+		self.check_is_owner_or_admin(&caller)
+			.map_err(dispatch_to_evm::<T>)?;
+		self.collection.permissions.nesting = Some(match enable {
+			false => NestingRule::Disabled,
+			true => {
+				let mut bv = OwnerRestrictedSet::new();
+				for i in collections {
+					bv.try_insert(crate::eth::map_eth_to_id(&i).ok_or(Error::Revert(
+						"Can't convert address into collection id".into(),
+					))?)
+					.map_err(|e| Error::Revert(format!("{:?}", e)))?;
+				}
+				NestingRule::OwnerRestricted(bv)
+			}
+		});
+		save(self)?;
+		Ok(())
+	}
+
+	fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		self.check_is_owner_or_admin(&caller)
+			.map_err(dispatch_to_evm::<T>)?;
+		self.collection.permissions.access = Some(match mode {
+			0 => AccessMode::Normal,
+			1 => AccessMode::AllowList,
+			_ => return Err("Not supported access mode".into()),
+		});
+		save(self)?;
+		Ok(())
+	}
+
+	fn add_to_collection_allow_list(&self, caller: caller, user: address) -> Result<void> {
+		let caller = check_is_owner_or_admin(caller, self)?;
+		let user = T::CrossAccountId::from_eth(user);
+		<Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
+		Ok(())
+	}
+
+	fn remove_from_collection_allow_list(&self, caller: caller, user: address) -> Result<void> {
+		let caller = check_is_owner_or_admin(caller, self)?;
+		let user = T::CrossAccountId::from_eth(user);
+		<Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
+		Ok(())
+	}
+
+	fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {
+		check_is_owner_or_admin(caller, self)?;
+		self.collection.permissions.mint_mode = Some(mode);
+		save(self)?;
+		Ok(())
+	}
 }
 
-fn check_is_owner<T: Config>(caller: caller, collection: &CollectionHandle<T>) -> Result<()> {
+fn check_is_owner<T: Config>(caller: caller, collection: &CollectionHandle<T>) -> Result<void> {
 	let caller = T::CrossAccountId::from_eth(caller);
 	collection
 		.check_is_owner(&caller)
@@ -175,8 +303,24 @@
 	Ok(())
 }
 
-fn save<T: Config>(collection: &CollectionHandle<T>) {
+fn check_is_owner_or_admin<T: Config>(
+	caller: caller,
+	collection: &CollectionHandle<T>,
+) -> Result<T::CrossAccountId> {
+	let caller = T::CrossAccountId::from_eth(caller);
+	collection
+		.check_is_owner_or_admin(&caller)
+		.map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
+	Ok(caller)
+}
+
+fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {
+	// TODO possibly delete for the lack of transaction
+	collection
+		.check_is_internal()
+		.map_err(dispatch_to_evm::<T>)?;
 	<crate::CollectionById<T>>::insert(collection.id, collection.collection.clone());
+	Ok(())
 }
 
 pub fn token_uri_key() -> up_data_structs::PropertyKey {
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -126,9 +126,11 @@
 	pub fn new(id: CollectionId) -> Option<Self> {
 		Self::new_with_gas_limit(id, u64::MAX)
 	}
+
 	pub fn try_get(id: CollectionId) -> Result<Self, DispatchError> {
 		Ok(Self::new(id).ok_or(<Error<T>>::CollectionNotFound)?)
 	}
+
 	pub fn consume_store_reads(&self, reads: u64) -> evm_coder::execution::Result<()> {
 		self.recorder
 			.consume_gas(T::GasWeightMapping::weight_to_gas(
@@ -137,6 +139,7 @@
 					.saturating_mul(reads),
 			))
 	}
+
 	pub fn consume_store_writes(&self, writes: u64) -> evm_coder::execution::Result<()> {
 		self.recorder
 			.consume_gas(T::GasWeightMapping::weight_to_gas(
@@ -145,24 +148,46 @@
 					.saturating_mul(writes),
 			))
 	}
-	pub fn save(self) -> DispatchResult {
+	pub fn save(self) -> Result<(), DispatchError> {
 		<CollectionById<T>>::insert(self.id, self.collection);
 		Ok(())
 	}
 
-	pub fn set_sponsor(&mut self, sponsor: T::AccountId) {
+	pub fn set_sponsor(&mut self, sponsor: T::AccountId) -> DispatchResult {
 		self.collection.sponsorship = SponsorshipState::Unconfirmed(sponsor);
+		Ok(())
 	}
 
-	pub fn confirm_sponsorship(&mut self, sender: &T::AccountId) -> bool {
+	pub fn confirm_sponsorship(&mut self, sender: &T::AccountId) -> Result<bool, DispatchError> {
 		if self.collection.sponsorship.pending_sponsor() != Some(sender) {
-			return false;
-		};
+			return Ok(false);
+		}
 
 		self.collection.sponsorship = SponsorshipState::Confirmed(sender.clone());
-		true
+		Ok(true)
+	}
+
+	/// Checks that the collection was created with, and must be operated upon through **Unique API**.
+	/// Now check only the `external_collection` flag and if it's **true**, then return `CollectionIsExternal` error.
+	pub fn check_is_internal(&self) -> DispatchResult {
+		if self.external_collection {
+			return Err(<Error<T>>::CollectionIsExternal)?;
+		}
+
+		Ok(())
 	}
+
+	/// Checks that the collection was created with, and must be operated upon through an **assimilated API**.
+	/// Now check only the `external_collection` flag and if it's **false**, then return `CollectionIsInternal` error.
+	pub fn check_is_external(&self) -> DispatchResult {
+		if !self.external_collection {
+			return Err(<Error<T>>::CollectionIsInternal)?;
+		}
+
+		Ok(())
+	}
 }
+
 impl<T: Config> Deref for CollectionHandle<T> {
 	type Target = Collection<T::AccountId>;
 
@@ -402,7 +427,7 @@
 		/// Target collection doesn't supports this operation
 		UnsupportedOperation,
 
-		/// Not sufficient founds to perform action
+		/// Not sufficient funds to perform action
 		NotSufficientFounds,
 
 		/// Collection has nesting disabled
@@ -429,6 +454,12 @@
 
 		/// Empty property keys are forbidden
 		EmptyPropertyKey,
+
+		/// Tried to access an external collection with an internal API
+		CollectionIsExternal,
+
+		/// Tried to access an internal collection with an external API
+		CollectionIsInternal,
 	}
 
 	#[pallet::storage]
@@ -664,6 +695,7 @@
 			sponsorship,
 			limits,
 			permissions,
+			external_collection,
 		} = <CollectionById<T>>::get(collection)?;
 
 		let token_property_permissions = <CollectionPropertyPermissions<T>>::get(collection)
@@ -693,6 +725,7 @@
 			permissions,
 			token_property_permissions,
 			properties,
+			read_only: external_collection,
 		})
 	}
 }
@@ -730,6 +763,7 @@
 	pub fn init_collection(
 		owner: T::CrossAccountId,
 		data: CreateCollectionData<T::AccountId>,
+		is_external: bool,
 	) -> Result<CollectionId, DispatchError> {
 		{
 			ensure!(
@@ -773,6 +807,7 @@
 					Self::clamp_permissions(data.mode.clone(), &Default::default(), permissions)
 				})
 				.unwrap_or_else(|| Ok(CollectionPermissions::default()))?,
+			external_collection: is_external,
 		};
 
 		let mut collection_properties = up_data_structs::CollectionProperties::get();
@@ -1097,7 +1132,7 @@
 		user: &T::CrossAccountId,
 		admin: bool,
 	) -> DispatchResult {
-		collection.check_is_owner_or_admin(sender)?;
+		collection.check_is_owner(sender)?;
 
 		let was_admin = <IsAdmin<T>>::get((collection.id, user));
 		if was_admin == admin {
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -137,7 +137,7 @@
 		owner: T::CrossAccountId,
 		data: CreateCollectionData<T::AccountId>,
 	) -> Result<CollectionId, DispatchError> {
-		<PalletCommon<T>>::init_collection(owner, data)
+		<PalletCommon<T>>::init_collection(owner, data, false)
 	}
 	pub fn destroy_collection(
 		collection: FungibleHandle<T>,
modifiedpallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -51,7 +51,7 @@
 	create_collection_raw(
 		owner,
 		CollectionMode::NFT,
-		<Pallet<T>>::init_collection,
+		|owner, data| <Pallet<T>>::init_collection(owner, data, true),
 		NonfungibleHandle::cast,
 	)
 }
@@ -99,7 +99,7 @@
 			sender: cross_from_sub(owner); burner: cross_sub;
 		};
 		let item = create_max_item(&collection, &sender, burner.clone())?;
-	}: {<Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)}
+	}: {<Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)?}
 
 	burn_recursively_breadth_plus_self_plus_self_per_each_raw {
 		let b in 0..200;
@@ -111,7 +111,7 @@
 		for i in 0..b {
 			create_max_item(&collection, &sender, T::CrossTokenAddressMapping::token_to_address(collection.id, item))?;
 		}
-	}: {<Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)}
+	}: {<Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)?}
 
 	transfer {
 		bench_init!{
@@ -183,7 +183,7 @@
 			value: property_value(),
 		}).collect::<Vec<_>>();
 		let item = create_max_item(&collection, &owner, owner.clone())?;
-	}: {<Pallet<T>>::set_token_properties(&collection, &owner, item, props)?}
+	}: {<Pallet<T>>::set_token_properties(&collection, &owner, item, props, false)?}
 
 	delete_token_properties {
 		let b in 0..MAX_PROPERTIES_PER_ITEM;
@@ -205,7 +205,7 @@
 			value: property_value(),
 		}).collect::<Vec<_>>();
 		let item = create_max_item(&collection, &owner, owner.clone())?;
-		<Pallet<T>>::set_token_properties(&collection, &owner, item, props)?;
+		<Pallet<T>>::set_token_properties(&collection, &owner, item, props, false)?;
 		let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();
 	}: {<Pallet<T>>::delete_token_properties(&collection, &owner, item, to_delete)?}
 }
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -223,7 +223,7 @@
 		let weight = <CommonWeights<T>>::set_token_properties(properties.len() as u32);
 
 		with_weight(
-			<Pallet<T>>::set_token_properties(self, &sender, token_id, properties),
+			<Pallet<T>>::set_token_properties(self, &sender, token_id, properties, false),
 			weight,
 		)
 	}
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -82,8 +82,14 @@
 			.map_err(|_| "key too long")?;
 		let value = value.try_into().map_err(|_| "value too long")?;
 
-		<Pallet<T>>::set_token_property(self, &caller, TokenId(token_id), Property { key, value })
-			.map_err(dispatch_to_evm::<T>)
+		<Pallet<T>>::set_token_property(
+			self,
+			&caller,
+			TokenId(token_id),
+			Property { key, value },
+			false,
+		)
+		.map_err(dispatch_to_evm::<T>)
 	}
 
 	fn delete_property(&mut self, token_id: uint256, caller: caller, key: string) -> Result<()> {
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -304,8 +304,9 @@
 	pub fn init_collection(
 		owner: T::CrossAccountId,
 		data: CreateCollectionData<T::AccountId>,
+		is_external: bool,
 	) -> Result<CollectionId, DispatchError> {
-		<PalletCommon<T>>::init_collection(owner, data)
+		<PalletCommon<T>>::init_collection(owner, data, is_external)
 	}
 	pub fn destroy_collection(
 		collection: NonfungibleHandle<T>,
@@ -447,8 +448,15 @@
 		sender: &T::CrossAccountId,
 		token_id: TokenId,
 		property: Property,
+		is_token_create: bool,
 	) -> DispatchResult {
-		Self::check_token_change_permission(collection, sender, token_id, &property.key)?;
+		Self::check_token_change_permission(
+			collection,
+			sender,
+			token_id,
+			&property.key,
+			is_token_create,
+		)?;
 
 		<TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {
 			let property = property.clone();
@@ -471,9 +479,10 @@
 		sender: &T::CrossAccountId,
 		token_id: TokenId,
 		properties: Vec<Property>,
+		is_token_create: bool,
 	) -> DispatchResult {
 		for property in properties {
-			Self::set_token_property(collection, sender, token_id, property)?;
+			Self::set_token_property(collection, sender, token_id, property, is_token_create)?;
 		}
 
 		Ok(())
@@ -485,7 +494,7 @@
 		token_id: TokenId,
 		property_key: PropertyKey,
 	) -> DispatchResult {
-		Self::check_token_change_permission(collection, sender, token_id, &property_key)?;
+		Self::check_token_change_permission(collection, sender, token_id, &property_key, false)?;
 
 		<TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {
 			properties.remove(&property_key)
@@ -506,6 +515,7 @@
 		sender: &T::CrossAccountId,
 		token_id: TokenId,
 		property_key: &PropertyKey,
+		is_token_create: bool,
 	) -> DispatchResult {
 		let permission = <PalletCommon<T>>::property_permissions(collection.id)
 			.get(property_key)
@@ -534,6 +544,11 @@
 				token_owner,
 				..
 			} => {
+				//TODO: investigate threats during public minting.
+				if is_token_create && (collection_admin || token_owner) {
+					return Ok(());
+				}
+
 				let mut check_result = Err(<CommonError<T>>::NoPermission.into());
 
 				if collection_admin {
@@ -772,6 +787,7 @@
 					sender,
 					TokenId(token),
 					data.properties.clone().into_inner(),
+					true,
 				) {
 					return TransactionOutcome::Rollback(Err(e));
 				}
@@ -889,6 +905,7 @@
 		if let Some(spender) = spender {
 			<PalletCommon<T>>::ensure_correct_receiver(spender)?;
 		}
+
 		let token_data =
 			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;
 		if &token_data.owner != sender {
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -297,40 +297,7 @@
 	}
 }
 
-// Selector: 780e9d63
-contract ERC721Enumerable is Dummy, ERC165 {
-	// Selector: tokenByIndex(uint256) 4f6ccce7
-	function tokenByIndex(uint256 index) public view returns (uint256) {
-		require(false, stub_error);
-		index;
-		dummy;
-		return 0;
-	}
-
-	// Not implemented
-	//
-	// Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
-	function tokenOfOwnerByIndex(address owner, uint256 index)
-		public
-		view
-		returns (uint256)
-	{
-		require(false, stub_error);
-		owner;
-		index;
-		dummy;
-		return 0;
-	}
-
-	// Selector: totalSupply() 18160ddd
-	function totalSupply() public view returns (uint256) {
-		require(false, stub_error);
-		dummy;
-		return 0;
-	}
-}
-
-// Selector: c894dc35
+// Selector: 6aea9834
 contract Collection is Dummy, ERC165 {
 	// Selector: setCollectionProperty(string,bytes) 2f073f66
 	function setCollectionProperty(string memory key, bytes memory value)
@@ -363,29 +330,29 @@
 		return hex"";
 	}
 
-	// Selector: ethSetSponsor(address) 8f9af356
-	function ethSetSponsor(address sponsor) public {
+	// Selector: setCollectionSponsor(address) 7623402e
+	function setCollectionSponsor(address sponsor) public {
 		require(false, stub_error);
 		sponsor;
 		dummy = 0;
 	}
 
-	// Selector: ethConfirmSponsorship() a8580d1a
-	function ethConfirmSponsorship() public {
+	// Selector: confirmCollectionSponsorship() 3c50e97a
+	function confirmCollectionSponsorship() public {
 		require(false, stub_error);
 		dummy = 0;
 	}
 
-	// Selector: setLimit(string,uint32) 68db30ca
-	function setLimit(string memory limit, uint32 value) public {
+	// Selector: setCollectionLimit(string,uint32) 6a3841db
+	function setCollectionLimit(string memory limit, uint32 value) public {
 		require(false, stub_error);
 		limit;
 		value;
 		dummy = 0;
 	}
 
-	// Selector: setLimit(string,bool) ea67e4c2
-	function setLimit(string memory limit, bool value) public {
+	// Selector: setCollectionLimit(string,bool) 993b7fba
+	function setCollectionLimit(string memory limit, bool value) public {
 		require(false, stub_error);
 		limit;
 		value;
@@ -398,6 +365,98 @@
 		dummy;
 		return 0x0000000000000000000000000000000000000000;
 	}
+
+	// Selector: addCollectionAdmin(address) 92e462c7
+	function addCollectionAdmin(address newAdmin) public view {
+		require(false, stub_error);
+		newAdmin;
+		dummy;
+	}
+
+	// Selector: removeCollectionAdmin(address) fafd7b42
+	function removeCollectionAdmin(address admin) public view {
+		require(false, stub_error);
+		admin;
+		dummy;
+	}
+
+	// Selector: setCollectionNesting(bool) 112d4586
+	function setCollectionNesting(bool enable) public {
+		require(false, stub_error);
+		enable;
+		dummy = 0;
+	}
+
+	// Selector: setCollectionNesting(bool,address[]) 64872396
+	function setCollectionNesting(bool enable, address[] memory collections)
+		public
+	{
+		require(false, stub_error);
+		enable;
+		collections;
+		dummy = 0;
+	}
+
+	// Selector: setCollectionAccess(uint8) 41835d4c
+	function setCollectionAccess(uint8 mode) public {
+		require(false, stub_error);
+		mode;
+		dummy = 0;
+	}
+
+	// Selector: addToCollectionAllowList(address) 67844fe6
+	function addToCollectionAllowList(address user) public view {
+		require(false, stub_error);
+		user;
+		dummy;
+	}
+
+	// Selector: removeFromCollectionAllowList(address) 85c51acb
+	function removeFromCollectionAllowList(address user) public view {
+		require(false, stub_error);
+		user;
+		dummy;
+	}
+
+	// Selector: setCollectionMintMode(bool) 00018e84
+	function setCollectionMintMode(bool mode) public {
+		require(false, stub_error);
+		mode;
+		dummy = 0;
+	}
+}
+
+// Selector: 780e9d63
+contract ERC721Enumerable is Dummy, ERC165 {
+	// Selector: tokenByIndex(uint256) 4f6ccce7
+	function tokenByIndex(uint256 index) public view returns (uint256) {
+		require(false, stub_error);
+		index;
+		dummy;
+		return 0;
+	}
+
+	// Not implemented
+	//
+	// Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
+	function tokenOfOwnerByIndex(address owner, uint256 index)
+		public
+		view
+		returns (uint256)
+	{
+		require(false, stub_error);
+		owner;
+		index;
+		dummy;
+		return 0;
+	}
+
+	// Selector: totalSupply() 18160ddd
+	function totalSupply() public view returns (uint256) {
+		require(false, stub_error);
+		dummy;
+		return 0;
+	}
 }
 
 // Selector: d74d154f
modifiedpallets/proxy-rmrk-core/Cargo.tomldiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/Cargo.toml
+++ b/pallets/proxy-rmrk-core/Cargo.toml
@@ -18,10 +18,13 @@
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" }
 pallet-common = { default-features = false, path = '../common' }
 pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
+pallet-structure = { default-features = false, path = "../../pallets/structure" }
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.22" }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" }
+rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
 scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
+derivative = { version = "2.2.0", features = ["use_core"] }
 
 [features]
 default = ["std"]
@@ -31,8 +34,10 @@
     "sp-runtime/std",
     "sp-std/std",
     "up-data-structs/std",
+    "rmrk-traits/std",
     "pallet-common/std",
     "pallet-nonfungible/std",
+    "pallet-structure/std",
     "pallet-evm/std",
     'frame-benchmarking/std',
 ]
addedpallets/proxy-rmrk-core/src/benchmarking.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/proxy-rmrk-core/src/benchmarking.rs
@@ -0,0 +1,26 @@
+use sp_std::vec;
+
+use frame_benchmarking::{benchmarks, account};
+use frame_system::RawOrigin;
+use frame_support::{
+	traits::{Currency, Get},
+	BoundedVec,
+};
+
+use crate::{Config, Pallet, Call};
+
+const SEED: u32 = 1;
+
+fn create_data<S: Get<u32>>() -> BoundedVec<u8, S> {
+	vec![0; S::get() as usize].try_into().expect("size == S")
+}
+
+benchmarks! {
+	create_collection {
+		let caller = account("caller", 0, SEED);
+		<T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
+		let metadata = create_data();
+		// TODO: Fix CollectionTokenPrefixLimitExceeded with create_data
+		let symbol = vec![].try_into().expect("0 <= x");
+	}: _(RawOrigin::Signed(caller), metadata, None, symbol)
+}
modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/lib.rs
+++ b/pallets/proxy-rmrk-core/src/lib.rs
@@ -20,24 +20,33 @@
 use frame_system::{pallet_prelude::*, ensure_signed};
 use sp_runtime::{DispatchError, Permill, traits::StaticLookup};
 use sp_std::vec::Vec;
-use up_data_structs::*;
+use up_data_structs::{*, mapping::TokenAddressMapping};
 use pallet_common::{
 	Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,
 };
 use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};
+use pallet_structure::{Pallet as PalletStructure, Error as StructureError};
 use pallet_evm::account::CrossAccountId;
 use core::convert::AsRef;
 
 pub use pallet::*;
 
+#[cfg(feature = "runtime-benchmarks")]
+pub mod benchmarking;
 pub mod misc;
 pub mod property;
+pub mod weights;
+
+pub type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
+use weights::WeightInfo;
 use misc::*;
 pub use property::*;
 
 use RmrkProperty::*;
 
+const NESTING_BUDGET: u32 = 5;
+
 #[frame_support::pallet]
 pub mod pallet {
 	use super::*;
@@ -48,12 +57,21 @@
 		frame_system::Config + pallet_common::Config + pallet_nonfungible::Config + account::Config
 	{
 		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
+		type WeightInfo: WeightInfo;
 	}
 
 	#[pallet::storage]
 	#[pallet::getter(fn collection_index)]
 	pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;
 
+	#[pallet::storage]
+	pub type UniqueCollectionId<T: Config> =
+		StorageMap<_, Twox64Concat, RmrkCollectionId, CollectionId, ValueQuery>;
+
+	#[pallet::storage]
+	pub type RmrkInernalCollectionId<T: Config> =
+		StorageMap<_, Twox64Concat, CollectionId, RmrkCollectionId, ValueQuery>;
+
 	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
 	pub struct Pallet<T>(_);
@@ -87,12 +105,50 @@
 			owner: T::AccountId,
 			nft_id: RmrkNftId,
 		},
+		NFTSent {
+			sender: T::AccountId,
+			recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,
+			collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+			approval_required: bool,
+		},
+		NFTAccepted {
+			sender: T::AccountId,
+			recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,
+			collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+		},
+		NFTRejected {
+			sender: T::AccountId,
+			collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+		},
 		PropertySet {
 			collection_id: RmrkCollectionId,
 			maybe_nft_id: Option<RmrkNftId>,
 			key: RmrkKeyString,
 			value: RmrkValueString,
 		},
+		ResourceAdded {
+			nft_id: RmrkNftId,
+			resource_id: RmrkResourceId,
+		},
+		ResourceRemoval {
+			nft_id: RmrkNftId,
+			resource_id: RmrkResourceId,
+		},
+		ResourceAccepted {
+			nft_id: RmrkNftId,
+			resource_id: RmrkResourceId,
+		},
+		ResourceRemovalAccepted {
+			nft_id: RmrkNftId,
+			resource_id: RmrkResourceId,
+		},
+		PrioritySet {
+			collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+		},
 	}
 
 	#[pallet::error]
@@ -109,13 +165,20 @@
 		NoAvailableNftId,
 		CollectionUnknown,
 		NoPermission,
+		NonTransferable,
 		CollectionFullOrLocked,
+		ResourceDoesntExist,
+		CannotSendToDescendentOrSelf,
+		CannotAcceptNonOwnedNft,
+		CannotRejectNonOwnedNft,
+		ResourceNotPending,
 	}
 
 	#[pallet::call]
 	impl<T: Config> Pallet<T> {
-		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		/// Create a collection
 		#[transactional]
+		#[pallet::weight(<SelfWeightOf<T>>::create_collection())]
 		pub fn create_collection(
 			origin: OriginFor<T>,
 			metadata: RmrkString,
@@ -136,38 +199,38 @@
 					.into_inner()
 					.try_into()
 					.map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
+				permissions: Some(CollectionPermissions {
+					nesting: Some(NestingRule::Owner),
+					..Default::default()
+				}),
 				..Default::default()
 			};
-
-			let collection_id_res =
-				<PalletNft<T>>::init_collection(T::CrossAccountId::from_sub(sender.clone()), data);
-
-			if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
-				return Err(<Error<T>>::NoAvailableCollectionId.into());
-			}
 
-			let collection_id = collection_id_res?;
-
-			<PalletCommon<T>>::set_scoped_collection_properties(
-				collection_id,
-				PropertyScope::Rmrk,
+			let unique_collection_id = Self::init_collection(
+				T::CrossAccountId::from_sub(sender.clone()),
+				data,
 				[
 					Self::rmrk_property(Metadata, &metadata)?,
 					Self::rmrk_property(CollectionType, &misc::CollectionType::Regular)?,
 				]
 				.into_iter(),
 			)?;
+			let rmrk_collection_id = <CollectionIndex<T>>::get();
+
+			<UniqueCollectionId<T>>::insert(rmrk_collection_id, unique_collection_id);
+			<RmrkInernalCollectionId<T>>::insert(unique_collection_id, rmrk_collection_id);
 
 			<CollectionIndex<T>>::mutate(|n| *n += 1);
 
 			Self::deposit_event(Event::CollectionCreated {
 				issuer: sender,
-				collection_id: collection_id.0,
+				collection_id: rmrk_collection_id,
 			});
 
 			Ok(())
 		}
 
+		/// destroy collection
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn destroy_collection(
@@ -177,20 +240,14 @@
 			let sender = ensure_signed(origin)?;
 			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
-			let unique_collection_id = collection_id.into();
-
 			let collection = Self::get_typed_nft_collection(
-				unique_collection_id,
+				Self::unique_collection_id(collection_id)?,
 				misc::CollectionType::Regular,
 			)?;
-
-			ensure!(
-				collection.total_supply() == 0,
-				<Error<T>>::CollectionNotEmpty
-			);
+			collection.check_is_external()?;
 
 			<PalletNft<T>>::destroy_collection(collection, &cross_sender)
-				.map_err(Self::map_common_err_to_proxy)?;
+				.map_err(Self::map_unique_err_to_proxy)?;
 
 			Self::deposit_event(Event::CollectionDestroyed {
 				issuer: sender,
@@ -200,6 +257,12 @@
 			Ok(())
 		}
 
+		/// Change the issuer of a collection
+		///
+		/// Parameters:
+		/// - `origin`: sender of the transaction
+		/// - `collection_id`: collection id of the nft to change issuer of
+		/// - `new_issuer`: Collection's new issuer
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn change_collection_issuer(
@@ -209,10 +272,13 @@
 		) -> DispatchResult {
 			let sender = ensure_signed(origin)?;
 
+			let collection = Self::get_nft_collection(Self::unique_collection_id(collection_id)?)?;
+			collection.check_is_external()?;
+
 			let new_issuer = T::Lookup::lookup(new_issuer)?;
 
 			Self::change_collection_owner(
-				collection_id.into(),
+				Self::unique_collection_id(collection_id)?,
 				misc::CollectionType::Regular,
 				sender.clone(),
 				new_issuer.clone(),
@@ -227,6 +293,7 @@
 			Ok(())
 		}
 
+		/// lock collection
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn lock_collection(
@@ -237,9 +304,10 @@
 			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
 			let collection = Self::get_typed_nft_collection(
-				collection_id.into(),
+				Self::unique_collection_id(collection_id)?,
 				misc::CollectionType::Regular,
 			)?;
+			collection.check_is_external()?;
 
 			Self::check_collection_owner(&collection, &cross_sender)?;
 
@@ -257,6 +325,16 @@
 			Ok(())
 		}
 
+		/// Mints an NFT in the specified collection
+		/// Sets metadata and the royalty attribute
+		///
+		/// Parameters:
+		/// - `collection_id`: The class of the asset to be minted.
+		/// - `nft_id`: The nft value of the asset to be minted.
+		/// - `recipient`: Receiver of the royalty
+		/// - `royalty`: Permillage reward from each trade for the Recipient
+		/// - `metadata`: Arbitrary data about an nft, e.g. IPFS hash
+		/// - `transferable`: Ability to transfer this NFT
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn mint_nft(
@@ -266,38 +344,55 @@
 			recipient: Option<T::AccountId>,
 			royalty_amount: Option<Permill>,
 			metadata: RmrkString,
+			transferable: bool,
 		) -> DispatchResult {
 			let sender = ensure_signed(origin)?;
 			let sender = T::CrossAccountId::from_sub(sender);
 			let cross_owner = T::CrossAccountId::from_sub(owner.clone());
 
-			let royalty_info = royalty_amount.map(|amount| rmrk::RoyaltyInfo {
-				recipient: recipient.unwrap_or_else(|| owner.clone()),
-				amount,
-			});
-
 			let collection = Self::get_typed_nft_collection(
-				collection_id.into(),
+				Self::unique_collection_id(collection_id)?,
 				misc::CollectionType::Regular,
 			)?;
+			collection.check_is_external()?;
 
+			let royalty_info = royalty_amount.map(|amount| rmrk_traits::RoyaltyInfo {
+				recipient: recipient.unwrap_or_else(|| owner.clone()),
+				amount,
+			});
+
 			let nft_id = Self::create_nft(
 				&sender,
 				&cross_owner,
 				&collection,
-				NftType::Regular,
 				[
+					Self::rmrk_property(TokenType, &NftType::Regular)?,
+					Self::rmrk_property(Transferable, &transferable)?,
+					Self::rmrk_property(PendingNftAccept, &false)?,
 					Self::rmrk_property(RoyaltyInfo, &royalty_info)?,
 					Self::rmrk_property(Metadata, &metadata)?,
 					Self::rmrk_property(Equipped, &false)?,
-					Self::rmrk_property(ResourceCollection, &None::<CollectionId>)?,
+					Self::rmrk_property(
+						ResourceCollection,
+						&Self::init_collection(
+							sender.clone(),
+							CreateCollectionData {
+								..Default::default()
+							},
+							[Self::rmrk_property(
+								CollectionType,
+								&misc::CollectionType::Resource,
+							)?]
+							.into_iter(),
+						)?,
+					)?, // todo possibly add limits to the collection if rmrk warrants them
 					Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,
 				]
 				.into_iter(),
 			)
 			.map_err(|err| match err {
 				DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),
-				err => Self::map_common_err_to_proxy(err),
+				err => Self::map_unique_err_to_proxy(err),
 			})?;
 
 			Self::deposit_event(Event::NftMinted {
@@ -309,6 +404,7 @@
 			Ok(())
 		}
 
+		/// burn nft
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn burn_nft(
@@ -319,12 +415,18 @@
 			let sender = ensure_signed(origin)?;
 			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
+			let collection = Self::get_typed_nft_collection(
+				Self::unique_collection_id(collection_id)?,
+				misc::CollectionType::Regular,
+			)?;
+			collection.check_is_external()?;
+
 			Self::destroy_nft(
 				cross_sender,
-				collection_id.into(),
-				misc::CollectionType::Regular,
+				Self::unique_collection_id(collection_id)?,
 				nft_id.into(),
-			)?;
+			)
+			.map_err(Self::map_unique_err_to_proxy)?;
 
 			Self::deposit_event(Event::NFTBurned {
 				owner: sender,
@@ -334,8 +436,354 @@
 			Ok(())
 		}
 
+		/// Transfers a NFT from an Account or NFT A to another Account or NFT B
+		///
+		/// Parameters:
+		/// - `origin`: sender of the transaction
+		/// - `rmrk_collection_id`: collection id of the nft to be transferred
+		/// - `rmrk_nft_id`: nft id of the nft to be transferred
+		/// - `new_owner`: new owner of the nft which can be either an account or a NFT
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
+		pub fn send(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			rmrk_nft_id: RmrkNftId,
+			new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin.clone())?;
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let nft_id = rmrk_nft_id.into();
+
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let token_data =
+				<TokenData<T>>::get((collection_id, nft_id)).ok_or(<Error<T>>::NoAvailableNftId)?;
+
+			let from = token_data.owner;
+
+			ensure!(
+				Self::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Transferable)?,
+				<Error<T>>::NonTransferable
+			);
+
+			ensure!(
+				!Self::get_nft_property_decoded(
+					collection_id,
+					nft_id,
+					RmrkProperty::PendingNftAccept
+				)?,
+				<Error<T>>::NoPermission
+			);
+
+			let target_owner;
+			let approval_required;
+
+			match new_owner {
+				RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {
+					target_owner = T::CrossAccountId::from_sub(account_id.clone());
+					approval_required = false;
+				}
+				RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(
+					target_collection_id,
+					target_nft_id,
+				) => {
+					let target_collection_id = Self::unique_collection_id(target_collection_id)?;
+
+					let target_nft_budget = budget::Value::new(NESTING_BUDGET);
+
+					let target_nft_owner = <PalletStructure<T>>::get_checked_topmost_owner(
+						target_collection_id,
+						target_nft_id.into(),
+						Some((collection_id, nft_id)),
+						&target_nft_budget,
+					)
+					.map_err(Self::map_unique_err_to_proxy)?;
+
+					approval_required = cross_sender != target_nft_owner;
+
+					if approval_required {
+						target_owner = target_nft_owner;
+
+						<PalletNft<T>>::set_scoped_token_property(
+							collection.id,
+							nft_id,
+							PropertyScope::Rmrk,
+							Self::rmrk_property(PendingNftAccept, &approval_required)?,
+						)?;
+					} else {
+						target_owner = T::CrossTokenAddressMapping::token_to_address(
+							target_collection_id,
+							target_nft_id.into(),
+						);
+					}
+				}
+			}
+
+			let src_nft_budget = budget::Value::new(NESTING_BUDGET);
+
+			<PalletNft<T>>::transfer_from(
+				&collection,
+				&cross_sender,
+				&from,
+				&target_owner,
+				nft_id,
+				&src_nft_budget,
+			)
+			.map_err(Self::map_unique_err_to_proxy)?;
+
+			Self::deposit_event(Event::NFTSent {
+				sender,
+				recipient: new_owner,
+				collection_id: rmrk_collection_id,
+				nft_id: rmrk_nft_id,
+				approval_required,
+			});
+
+			Ok(())
+		}
+
+		/// Accepts an NFT sent from another account to self or owned NFT
+		///
+		/// Parameters:
+		/// - `origin`: sender of the transaction
+		/// - `rmrk_collection_id`: collection id of the nft to be accepted
+		/// - `rmrk_nft_id`: nft id of the nft to be accepted
+		/// - `new_owner`: either origin's account ID or origin-owned NFT, whichever the NFT was
+		///   sent to
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn accept_nft(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			rmrk_nft_id: RmrkNftId,
+			new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin.clone())?;
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let nft_id = rmrk_nft_id.into();
+
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let new_cross_owner = match new_owner {
+				RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {
+					T::CrossAccountId::from_sub(account_id.clone())
+				}
+				RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(
+					target_collection_id,
+					target_nft_id,
+				) => {
+					let target_collection_id = Self::unique_collection_id(target_collection_id)?;
+
+					T::CrossTokenAddressMapping::token_to_address(
+						target_collection_id,
+						TokenId(target_nft_id),
+					)
+				}
+			};
+
+			let budget = budget::Value::new(NESTING_BUDGET);
+
+			<PalletNft<T>>::transfer(
+				&collection,
+				&cross_sender,
+				&new_cross_owner,
+				nft_id,
+				&budget,
+			)
+			.map_err(|err| {
+				if err == <CommonError<T>>::OnlyOwnerAllowedToNest.into() {
+					<Error<T>>::CannotAcceptNonOwnedNft.into()
+				} else {
+					Self::map_unique_err_to_proxy(err)
+				}
+			})?;
+
+			<PalletNft<T>>::set_scoped_token_property(
+				collection.id,
+				nft_id,
+				PropertyScope::Rmrk,
+				Self::rmrk_property(PendingNftAccept, &false)?,
+			)?;
+
+			Self::deposit_event(Event::NFTAccepted {
+				sender,
+				recipient: new_owner,
+				collection_id: rmrk_collection_id,
+				nft_id: rmrk_nft_id,
+			});
+
+			Ok(())
+		}
+
+		/// Rejects an NFT sent from another account to self or owned NFT
+		///
+		/// Parameters:
+		/// - `origin`: sender of the transaction
+		/// - `rmrk_collection_id`: collection id of the nft to be accepted
+		/// - `rmrk_nft_id`: nft id of the nft to be accepted
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn reject_nft(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			rmrk_nft_id: RmrkNftId,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin)?;
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let nft_id = rmrk_nft_id.into();
+
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			Self::destroy_nft(cross_sender, collection_id, nft_id).map_err(|err| {
+				if err == <CommonError<T>>::NoPermission.into()
+					|| err == <CommonError<T>>::ApprovedValueTooLow.into()
+				{
+					<Error<T>>::CannotRejectNonOwnedNft.into()
+				} else {
+					Self::map_unique_err_to_proxy(err)
+				}
+			})?;
+
+			Self::deposit_event(Event::NFTRejected {
+				sender,
+				collection_id: rmrk_collection_id,
+				nft_id: rmrk_nft_id,
+			});
+
+			Ok(())
+		}
+
+		/// accept the addition of a new resource to an existing NFT
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn accept_resource(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			rmrk_nft_id: RmrkNftId,
+			rmrk_resource_id: RmrkResourceId,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin)?;
+			let cross_sender = T::CrossAccountId::from_sub(sender);
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)
+				.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let nft_id = rmrk_nft_id.into();
+			let resource_id = rmrk_resource_id.into();
+
+			let budget = budget::Value::new(NESTING_BUDGET);
+
+			let nft_owner =
+				<PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)
+					.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+
+			let resource_collection_id: CollectionId =
+				Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)
+					.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+
+			let is_pending: bool = Self::get_nft_property_decoded(
+				resource_collection_id,
+				resource_id,
+				PendingResourceAccept,
+			)
+			.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+
+			ensure!(is_pending, <Error<T>>::ResourceNotPending);
+
+			ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);
+
+			<PalletNft<T>>::set_scoped_token_property(
+				resource_collection_id,
+				rmrk_resource_id.into(),
+				PropertyScope::Rmrk,
+				Self::rmrk_property(PendingResourceAccept, &false)?,
+			)?;
+
+			Self::deposit_event(Event::<T>::ResourceAccepted {
+				nft_id: rmrk_nft_id,
+				resource_id: rmrk_resource_id,
+			});
+
+			Ok(())
+		}
+
+		/// accept the removal of a resource of an existing NFT
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn accept_resource_removal(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			rmrk_nft_id: RmrkNftId,
+			rmrk_resource_id: RmrkResourceId,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin)?;
+			let cross_sender = T::CrossAccountId::from_sub(sender);
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)
+				.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let nft_id = rmrk_nft_id.into();
+			let resource_id = rmrk_resource_id.into();
+
+			let budget = budget::Value::new(NESTING_BUDGET);
+
+			let nft_owner =
+				<PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)
+					.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+
+			ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);
+
+			let resource_collection_id: CollectionId =
+				Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)
+					.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+
+			let is_pending: bool = Self::get_nft_property_decoded(
+				resource_collection_id,
+				resource_id,
+				PendingResourceRemoval,
+			)
+			.map_err(|_| <Error<T>>::ResourceDoesntExist)?;
+
+			ensure!(is_pending, <Error<T>>::ResourceNotPending);
+
+			let resource_collection = Self::get_typed_nft_collection(
+				resource_collection_id,
+				misc::CollectionType::Resource,
+			)?;
+
+			<PalletNft<T>>::burn(&resource_collection, &cross_sender, rmrk_resource_id.into())
+				.map_err(Self::map_unique_err_to_proxy)?;
+
+			Self::deposit_event(Event::<T>::ResourceRemovalAccepted {
+				nft_id: rmrk_nft_id,
+				resource_id: rmrk_resource_id,
+			});
+
+			Ok(())
+		}
+
+		/// set a custom value on an NFT
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
 		pub fn set_property(
 			origin: OriginFor<T>,
 			#[pallet::compact] rmrk_collection_id: RmrkCollectionId,
@@ -346,14 +794,19 @@
 			let sender = ensure_signed(origin)?;
 			let sender = T::CrossAccountId::from_sub(sender);
 
-			let collection_id: CollectionId = rmrk_collection_id.into();
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let budget = budget::Value::new(NESTING_BUDGET);
 
 			match maybe_nft_id {
 				Some(nft_id) => {
 					let token_id: TokenId = nft_id.into();
 
-					Self::ensure_nft_owner(collection_id, token_id, &sender)?;
 					Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;
+					Self::ensure_nft_owner(collection_id, token_id, &sender, &budget)?;
 
 					<PalletNft<T>>::set_scoped_token_property(
 						collection_id,
@@ -387,6 +840,189 @@
 
 			Ok(())
 		}
+
+		/// set a different order of resource priority
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn set_priority(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			rmrk_nft_id: RmrkNftId,
+			priorities: BoundedVec<RmrkResourceId, RmrkMaxPriorities>,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin)?;
+			let sender = T::CrossAccountId::from_sub(sender);
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let nft_id = rmrk_nft_id.into();
+
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let budget = budget::Value::new(NESTING_BUDGET);
+
+			Self::ensure_nft_type(collection_id, nft_id, NftType::Regular)?;
+			Self::ensure_nft_owner(collection_id, nft_id, &sender, &budget)?;
+
+			<PalletNft<T>>::set_scoped_token_property(
+				collection_id,
+				nft_id,
+				PropertyScope::Rmrk,
+				Self::rmrk_property(ResourcePriorities, &priorities.into_inner())?,
+			)?;
+
+			Self::deposit_event(Event::<T>::PrioritySet {
+				collection_id: rmrk_collection_id,
+				nft_id: rmrk_nft_id,
+			});
+
+			Ok(())
+		}
+
+		/// Create basic resource
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn add_basic_resource(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+			resource: RmrkBasicResource,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin.clone())?;
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let resource_id = Self::resource_add(
+				sender,
+				collection_id,
+				nft_id.into(),
+				[
+					Self::rmrk_property(TokenType, &NftType::Resource)?,
+					Self::rmrk_property(ResourceType, &misc::ResourceType::Basic)?,
+					Self::rmrk_property(Src, &resource.src)?,
+					Self::rmrk_property(Metadata, &resource.metadata)?,
+					Self::rmrk_property(License, &resource.license)?,
+					Self::rmrk_property(Thumb, &resource.thumb)?,
+				]
+				.into_iter(),
+			)?;
+
+			Self::deposit_event(Event::ResourceAdded {
+				nft_id,
+				resource_id,
+			});
+			Ok(())
+		}
+
+		/// Create composable resource
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn add_composable_resource(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+			_resource_id: RmrkBoundedResource,
+			resource: RmrkComposableResource,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin.clone())?;
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let resource_id = Self::resource_add(
+				sender,
+				collection_id,
+				nft_id.into(),
+				[
+					Self::rmrk_property(TokenType, &NftType::Resource)?,
+					Self::rmrk_property(ResourceType, &misc::ResourceType::Composable)?,
+					Self::rmrk_property(Parts, &resource.parts)?,
+					Self::rmrk_property(Base, &resource.base)?,
+					Self::rmrk_property(Src, &resource.src)?,
+					Self::rmrk_property(Metadata, &resource.metadata)?,
+					Self::rmrk_property(License, &resource.license)?,
+					Self::rmrk_property(Thumb, &resource.thumb)?,
+				]
+				.into_iter(),
+			)?;
+
+			Self::deposit_event(Event::ResourceAdded {
+				nft_id,
+				resource_id,
+			});
+			Ok(())
+		}
+
+		/// Create slot resource
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn add_slot_resource(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+			resource: RmrkSlotResource,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin.clone())?;
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			let resource_id = Self::resource_add(
+				sender,
+				collection_id,
+				nft_id.into(),
+				[
+					Self::rmrk_property(TokenType, &NftType::Resource)?,
+					Self::rmrk_property(ResourceType, &misc::ResourceType::Slot)?,
+					Self::rmrk_property(Base, &resource.base)?,
+					Self::rmrk_property(Src, &resource.src)?,
+					Self::rmrk_property(Metadata, &resource.metadata)?,
+					Self::rmrk_property(Slot, &resource.slot)?,
+					Self::rmrk_property(License, &resource.license)?,
+					Self::rmrk_property(Thumb, &resource.thumb)?,
+				]
+				.into_iter(),
+			)?;
+
+			Self::deposit_event(Event::ResourceAdded {
+				nft_id,
+				resource_id,
+			});
+			Ok(())
+		}
+
+		/// remove resource
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
+		pub fn remove_resource(
+			origin: OriginFor<T>,
+			rmrk_collection_id: RmrkCollectionId,
+			nft_id: RmrkNftId,
+			resource_id: RmrkResourceId,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin.clone())?;
+
+			let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+			let collection =
+				Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+			collection.check_is_external()?;
+
+			Self::resource_remove(sender, collection_id, nft_id.into(), resource_id.into())?;
+
+			Self::deposit_event(Event::ResourceRemoval {
+				nft_id,
+				resource_id,
+			});
+			Ok(())
+		}
 	}
 }
 
@@ -401,6 +1037,7 @@
 		Ok(scoped_key)
 	}
 
+	// todo think about renaming these
 	pub fn rmrk_property<E: Encode>(
 		rmrk_key: RmrkProperty,
 		value: &E,
@@ -417,20 +1054,51 @@
 		Ok(property)
 	}
 
+	pub fn decode_property<D: Decode>(vec: PropertyValue) -> Result<D, DispatchError> {
+		vec.decode()
+			.map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())
+	}
+
+	pub fn rebind<L, S>(vec: &BoundedVec<u8, L>) -> Result<BoundedVec<u8, S>, DispatchError>
+	where
+		BoundedVec<u8, S>: TryFrom<Vec<u8>>,
+	{
+		vec.rebind()
+			.map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())
+	}
+
+	fn init_collection(
+		sender: T::CrossAccountId,
+		data: CreateCollectionData<T::AccountId>,
+		properties: impl Iterator<Item = Property>,
+	) -> Result<CollectionId, DispatchError> {
+		let collection_id = <PalletNft<T>>::init_collection(sender, data, true);
+
+		if let Err(DispatchError::Arithmetic(_)) = &collection_id {
+			return Err(<Error<T>>::NoAvailableCollectionId.into());
+		}
+
+		<PalletCommon<T>>::set_scoped_collection_properties(
+			collection_id?,
+			PropertyScope::Rmrk,
+			properties,
+		)?;
+
+		collection_id
+	}
+
 	pub fn create_nft(
 		sender: &T::CrossAccountId,
 		owner: &T::CrossAccountId,
 		collection: &NonfungibleHandle<T>,
-		nft_type: NftType,
 		properties: impl Iterator<Item = Property>,
 	) -> Result<TokenId, DispatchError> {
-		todo!("store nft type");
 		let data = CreateNftExData {
 			properties: BoundedVec::default(),
 			owner: owner.clone(),
 		};
 
-		let budget = budget::Value::new(2);
+		let budget = budget::Value::new(NESTING_BUDGET);
 
 		<PalletNft<T>>::create_item(collection, sender, data, &budget)?;
 
@@ -449,13 +1117,101 @@
 	fn destroy_nft(
 		sender: T::CrossAccountId,
 		collection_id: CollectionId,
-		collection_type: misc::CollectionType,
 		token_id: TokenId,
 	) -> DispatchResult {
-		let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;
+		let collection =
+			Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+
+		let token_data =
+			<TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;
+
+		let from = token_data.owner;
+
+		let budget = budget::Value::new(NESTING_BUDGET);
+
+		<PalletNft<T>>::burn_from(&collection, &sender, &from, token_id, &budget)
+	}
+
+	fn resource_add(
+		sender: T::AccountId,
+		collection_id: CollectionId,
+		token_id: TokenId,
+		resource_properties: impl Iterator<Item = Property>,
+	) -> Result<RmrkResourceId, DispatchError> {
+		let collection =
+			Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+		ensure!(collection.owner == sender, Error::<T>::NoPermission);
+
+		let sender = T::CrossAccountId::from_sub(sender);
+		let budget = budget::Value::new(NESTING_BUDGET);
+
+		let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, token_id, &budget)
+			.map_err(Self::map_unique_err_to_proxy)?;
+
+		let pending = sender != nft_owner;
+
+		let resource_collection_id: CollectionId =
+			Self::get_nft_property_decoded(collection_id, token_id, ResourceCollection)?;
+		let resource_collection =
+			Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;
+
+		// todo probably add extra connections to bases, slots, etc., when RMRK starts to use them
+
+		let resource_id = Self::create_nft(
+			&sender,
+			&nft_owner,
+			&resource_collection,
+			resource_properties.chain(
+				[
+					Self::rmrk_property(PendingResourceAccept, &pending)?,
+					Self::rmrk_property(PendingResourceRemoval, &false)?,
+				]
+				.into_iter(),
+			),
+		)
+		.map_err(|err| match err {
+			DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),
+			err => Self::map_unique_err_to_proxy(err),
+		})?;
+
+		Ok(resource_id.0)
+	}
+
+	fn resource_remove(
+		sender: T::AccountId,
+		collection_id: CollectionId,
+		nft_id: TokenId,
+		resource_id: TokenId,
+	) -> DispatchResult {
+		let collection =
+			Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
+		ensure!(collection.owner == sender, Error::<T>::NoPermission);
 
-		<PalletNft<T>>::burn(&collection, &sender, token_id)
-			.map_err(Self::map_common_err_to_proxy)?;
+		let resource_collection_id: CollectionId =
+			Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)?;
+		let resource_collection =
+			Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;
+		ensure!(
+			<PalletNft<T>>::token_exists(&resource_collection, resource_id),
+			Error::<T>::ResourceDoesntExist
+		);
+
+		let budget = up_data_structs::budget::Value::new(10);
+		let topmost_owner =
+			<PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)?;
+
+		let sender = T::CrossAccountId::from_sub(sender);
+		if topmost_owner == sender {
+			<PalletNft<T>>::burn(&resource_collection, &sender, resource_id)
+				.map_err(Self::map_unique_err_to_proxy)?;
+		} else {
+			<PalletNft<T>>::set_scoped_token_property(
+				resource_collection_id,
+				resource_id,
+				PropertyScope::Rmrk,
+				Self::rmrk_property(PendingResourceRemoval, &true)?,
+			)?;
+		}
 
 		Ok(())
 	}
@@ -481,13 +1237,27 @@
 	) -> DispatchResult {
 		collection
 			.check_is_owner(account)
-			.map_err(Self::map_common_err_to_proxy)
+			.map_err(Self::map_unique_err_to_proxy)
 	}
 
 	pub fn last_collection_idx() -> RmrkCollectionId {
 		<CollectionIndex<T>>::get()
 	}
 
+	pub fn unique_collection_id(
+		rmrk_collection_id: RmrkCollectionId,
+	) -> Result<CollectionId, DispatchError> {
+		<UniqueCollectionId<T>>::try_get(rmrk_collection_id)
+			.map_err(|_| <Error<T>>::CollectionUnknown.into())
+	}
+
+	pub fn rmrk_collection_id(
+		unique_collection_id: CollectionId,
+	) -> Result<RmrkCollectionId, DispatchError> {
+		<RmrkInernalCollectionId<T>>::try_get(unique_collection_id)
+			.map_err(|_| <Error<T>>::CollectionUnknown.into())
+	}
+
 	pub fn get_nft_collection(
 		collection_id: CollectionId,
 	) -> Result<NonfungibleHandle<T>, DispatchError> {
@@ -502,10 +1272,6 @@
 
 	pub fn collection_exists(collection_id: CollectionId) -> bool {
 		<CollectionHandle<T>>::try_get(collection_id).is_ok()
-	}
-
-	pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
-		<TokenData<T>>::contains_key((collection_id, nft_id))
 	}
 
 	pub fn get_collection_property(
@@ -520,14 +1286,17 @@
 		Ok(collection_property)
 	}
 
+	pub fn get_collection_property_decoded<V: Decode>(
+		collection_id: CollectionId,
+		key: RmrkProperty,
+	) -> Result<V, DispatchError> {
+		Self::decode_property(Self::get_collection_property(collection_id, key)?)
+	}
+
 	pub fn get_collection_type(
 		collection_id: CollectionId,
 	) -> Result<misc::CollectionType, DispatchError> {
-		let value = Self::get_collection_property(collection_id, CollectionType)?;
-
-		let mut value = value.as_slice();
-
-		misc::CollectionType::decode(&mut value)
+		Self::get_collection_property_decoded(collection_id, CollectionType)
 			.map_err(|_| <Error<T>>::CorruptedCollectionType.into())
 	}
 
@@ -544,6 +1313,29 @@
 		Ok(())
 	}
 
+	pub fn get_typed_nft_collection(
+		collection_id: CollectionId,
+		collection_type: misc::CollectionType,
+	) -> Result<NonfungibleHandle<T>, DispatchError> {
+		Self::ensure_collection_type(collection_id, collection_type)?;
+
+		Self::get_nft_collection(collection_id)
+	}
+
+	pub fn get_typed_nft_collection_mapped(
+		rmrk_collection_id: RmrkCollectionId,
+		collection_type: misc::CollectionType,
+	) -> Result<(NonfungibleHandle<T>, CollectionId), DispatchError> {
+		let unique_collection_id = match collection_type {
+			misc::CollectionType::Regular => Self::unique_collection_id(rmrk_collection_id)?,
+			_ => rmrk_collection_id.into(),
+		};
+
+		let collection = Self::get_typed_nft_collection(unique_collection_id, collection_type)?;
+
+		Ok((collection, unique_collection_id))
+	}
+
 	pub fn get_nft_property(
 		collection_id: CollectionId,
 		nft_id: TokenId,
@@ -551,17 +1343,30 @@
 	) -> Result<PropertyValue, DispatchError> {
 		let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))
 			.get(&Self::rmrk_property_key(key)?)
-			.ok_or(<Error<T>>::NoAvailableNftId)?
+			.ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error?
 			.clone();
 
 		Ok(nft_property)
 	}
 
+	pub fn get_nft_property_decoded<V: Decode>(
+		collection_id: CollectionId,
+		nft_id: TokenId,
+		key: RmrkProperty,
+	) -> Result<V, DispatchError> {
+		Self::decode_property(Self::get_nft_property(collection_id, nft_id, key)?)
+	}
+
+	pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
+		<TokenData<T>>::contains_key((collection_id, nft_id))
+	}
+
 	pub fn get_nft_type(
-		_collection_id: CollectionId,
-		_token_id: TokenId,
+		collection_id: CollectionId,
+		token_id: TokenId,
 	) -> Result<NftType, DispatchError> {
-		todo!("should get it from properties?")
+		Self::get_nft_property_decoded(collection_id, token_id, TokenType)
+			.map_err(|_| <Error<T>>::NoAvailableNftId.into())
 	}
 
 	pub fn ensure_nft_type(
@@ -579,14 +1384,18 @@
 		collection_id: CollectionId,
 		token_id: TokenId,
 		possible_owner: &T::CrossAccountId,
+		nesting_budget: &dyn budget::Budget,
 	) -> DispatchResult {
-		let token_data =
-			<TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;
+		let is_owned = <PalletStructure<T>>::check_indirectly_owned(
+			possible_owner.clone(),
+			collection_id,
+			token_id,
+			None,
+			nesting_budget,
+		)
+		.map_err(Self::map_unique_err_to_proxy)?;
 
-		ensure!(
-			token_data.owner == *possible_owner,
-			<Error<T>>::NoPermission
-		);
+		ensure!(is_owned, <Error<T>>::NoPermission);
 
 		Ok(())
 	}
@@ -610,18 +1419,17 @@
 						let key: Key = key.try_into().ok()?;
 
 						let value = match token_id {
-							Some(token_id) => Self::get_nft_property(
+							Some(token_id) => Self::get_nft_property_decoded(
 								collection_id,
 								token_id,
 								UserProperty(key.as_ref()),
 							),
-							None => Self::get_collection_property(
+							None => Self::get_collection_property_decoded(
 								collection_id,
 								UserProperty(key.as_ref()),
 							),
 						}
-						.ok()?
-						.decode_or_default();
+						.ok()?;
 
 						Some(mapper(key, value))
 					})
@@ -658,7 +1466,7 @@
 			let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
 
 			let key: Key = key.to_vec().try_into().ok()?;
-			let value: Value = value.decode_or_default();
+			let value: Value = value.decode().ok()?;
 
 			Some(mapper(key, value))
 		});
@@ -666,22 +1474,17 @@
 		Ok(properties)
 	}
 
-	pub fn get_typed_nft_collection(
-		collection_id: CollectionId,
-		collection_type: misc::CollectionType,
-	) -> Result<NonfungibleHandle<T>, DispatchError> {
-		Self::ensure_collection_type(collection_id, collection_type)?;
-
-		Self::get_nft_collection(collection_id)
-	}
-
-	fn map_common_err_to_proxy(err: DispatchError) -> DispatchError {
-		map_common_err_to_proxy! {
+	fn map_unique_err_to_proxy(err: DispatchError) -> DispatchError {
+		map_unique_err_to_proxy! {
 			match err {
-				NoPermission => NoPermission,
-				CollectionTokenLimitExceeded => CollectionFullOrLocked,
-				PublicMintingNotAllowed => NoPermission,
-				TokenNotFound => NoAvailableNftId
+				CommonError::NoPermission => NoPermission,
+				CommonError::CollectionTokenLimitExceeded => CollectionFullOrLocked,
+				CommonError::PublicMintingNotAllowed => NoPermission,
+				CommonError::TokenNotFound => NoAvailableNftId,
+				CommonError::ApprovedValueTooLow => NoPermission,
+				CommonError::CantDestroyNotEmptyCollection => CollectionNotEmpty,
+				StructureError::TokenNotFound => NoAvailableNftId,
+				StructureError::OuroborosDetected => CannotSendToDescendentOrSelf,
 			}
 		}
 	}
modifiedpallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/misc.rs
+++ b/pallets/proxy-rmrk-core/src/misc.rs
@@ -1,11 +1,27 @@
+// 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 super::*;
-use codec::{Encode, Decode};
+use codec::{Encode, Decode, Error};
 
 #[macro_export]
-macro_rules! map_common_err_to_proxy {
-    (match $err:ident { $($common_err:ident => $proxy_err:ident),+ }) => {
+macro_rules! map_unique_err_to_proxy {
+    (match $err:ident { $($unique_err_ty:ident :: $unique_err:ident => $proxy_err:ident),+ $(,)? }) => {
         $(
-            if $err == <CommonError<T>>::$common_err.into() {
+            if $err == <$unique_err_ty<T>>::$unique_err.into() {
                 return <Error<T>>::$proxy_err.into()
             } else
         )+ {
@@ -14,28 +30,31 @@
     };
 }
 
-pub trait RmrkDecode<T: Decode + Default, S> {
-	fn decode_or_default(&self) -> T;
+// Utilize the RmrkCore pallet for access to Runtime errors.
+pub trait RmrkDecode<T: Decode, S> {
+	fn decode(&self) -> Result<T, Error>;
 }
 
-impl<T: Decode + Default, S> RmrkDecode<T, S> for BoundedVec<u8, S> {
-	fn decode_or_default(&self) -> T {
+impl<T: Decode, S> RmrkDecode<T, S> for BoundedVec<u8, S> {
+	fn decode(&self) -> Result<T, Error> {
 		let mut value = self.as_slice();
 
-		T::decode(&mut value).unwrap_or_default()
+		T::decode(&mut value)
 	}
 }
 
+// Utilize the RmrkCore pallet for access to Runtime errors.
 pub trait RmrkRebind<T, S> {
-	fn rebind(&self) -> BoundedVec<u8, S>;
+	fn rebind(&self) -> Result<BoundedVec<u8, S>, Error>;
 }
 
 impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>
 where
 	BoundedVec<u8, S>: TryFrom<Vec<u8>>,
 {
-	fn rebind(&self) -> BoundedVec<u8, S> {
-		BoundedVec::<u8, S>::try_from(self.clone().into_inner()).unwrap_or_default()
+	fn rebind(&self) -> Result<BoundedVec<u8, S>, Error> {
+		BoundedVec::<u8, S>::try_from(self.clone().into_inner())
+			.map_err(|_| "BoundedVec exceeds its limit".into())
 	}
 }
 
@@ -54,3 +73,10 @@
 	SlotPart,
 	Theme,
 }
+
+#[derive(Encode, Decode, PartialEq, Eq)]
+pub enum ResourceType {
+	Basic,
+	Composable,
+	Slot,
+}
modifiedpallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/property.rs
+++ b/pallets/proxy-rmrk-core/src/property.rs
@@ -1,14 +1,33 @@
+// 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 super::*;
 use core::convert::AsRef;
 
 pub enum RmrkProperty<'r> {
 	Metadata,
 	CollectionType,
+	TokenType,
+	Transferable,
 	RoyaltyInfo,
 	Equipped,
 	ResourceCollection,
 	ResourcePriorities,
 	ResourceType,
+	PendingNftAccept,
 	PendingResourceAccept,
 	PendingResourceRemoval,
 	Parts,
@@ -47,13 +66,16 @@
 		match self {
 			Self::Metadata => key!("metadata"),
 			Self::CollectionType => key!("collection-type"),
+			Self::TokenType => key!("token-type"),
+			Self::Transferable => key!("transferable"),
 			Self::RoyaltyInfo => key!("royalty-info"),
 			Self::Equipped => key!("equipped"),
 			Self::ResourceCollection => key!("resource-collection"),
 			Self::ResourcePriorities => key!("resource-priorities"),
 			Self::ResourceType => key!("resource-type"),
-			Self::PendingResourceAccept => key!("pending-accept"),
-			Self::PendingResourceRemoval => key!("pending-removal"),
+			Self::PendingNftAccept => key!("pending-nft-accept"),
+			Self::PendingResourceAccept => key!("pending-resource-accept"),
+			Self::PendingResourceRemoval => key!("pending-resource-removal"),
 			Self::Parts => key!("parts"),
 			Self::Base => key!("base"),
 			Self::Src => key!("src"),
addedpallets/proxy-rmrk-core/src/weights.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/proxy-rmrk-core/src/weights.rs
@@ -0,0 +1,74 @@
+// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
+
+//! Autogenerated weights for pallet_proxy_rmrk_core
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2022-06-09, STEPS: `50`, REPEAT: 200, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
+
+// Executed Command:
+// target/release/unique-collator
+// benchmark
+// pallet
+// --pallet
+// pallet-proxy-rmrk-core
+// --wasm-execution
+// compiled
+// --extrinsic
+// *
+// --template
+// .maintain/frame-weight-template.hbs
+// --steps=50
+// --repeat=200
+// --heap-pages=4096
+// --output=./pallets/proxy-rmrk-core/src/weights.rs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(clippy::unnecessary_cast)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weight functions needed for pallet_proxy_rmrk_core.
+pub trait WeightInfo {
+	fn create_collection() -> Weight;
+}
+
+/// Weights for pallet_proxy_rmrk_core using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	// Storage: Common CreatedCollectionCount (r:1 w:1)
+	// Storage: Common DestroyedCollectionCount (r:1 w:0)
+	// Storage: System Account (r:2 w:2)
+	// Storage: RmrkCore CollectionIndex (r:1 w:1)
+	// Storage: Common CollectionPropertyPermissions (r:0 w:1)
+	// Storage: Common CollectionProperties (r:0 w:1)
+	// Storage: Common CollectionById (r:0 w:1)
+	// Storage: RmrkCore UniqueCollectionId (r:0 w:1)
+	// Storage: RmrkCore RmrkInernalCollectionId (r:0 w:1)
+	fn create_collection() -> Weight {
+		(76_647_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(5 as Weight))
+			.saturating_add(T::DbWeight::get().writes(9 as Weight))
+	}
+}
+
+// For backwards compatibility and tests
+impl WeightInfo for () {
+	// Storage: Common CreatedCollectionCount (r:1 w:1)
+	// Storage: Common DestroyedCollectionCount (r:1 w:0)
+	// Storage: System Account (r:2 w:2)
+	// Storage: RmrkCore CollectionIndex (r:1 w:1)
+	// Storage: Common CollectionPropertyPermissions (r:0 w:1)
+	// Storage: Common CollectionProperties (r:0 w:1)
+	// Storage: Common CollectionById (r:0 w:1)
+	// Storage: RmrkCore UniqueCollectionId (r:0 w:1)
+	// Storage: RmrkCore RmrkInernalCollectionId (r:0 w:1)
+	fn create_collection() -> Weight {
+		(76_647_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(5 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(9 as Weight))
+	}
+}
modifiedpallets/proxy-rmrk-equip/Cargo.tomldiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/Cargo.toml
+++ b/pallets/proxy-rmrk-equip/Cargo.toml
@@ -21,6 +21,7 @@
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.22" }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" }
+rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
 scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
 pallet-rmrk-core = { default-features = false, path = "../proxy-rmrk-core" }
 
@@ -32,6 +33,7 @@
     "sp-runtime/std",
     "sp-std/std",
     "up-data-structs/std",
+    "rmrk-traits/std",
     "pallet-common/std",
     "pallet-nonfungible/std",
     "pallet-rmrk-core/std",
modifiedpallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/src/lib.rs
+++ b/pallets/proxy-rmrk-equip/src/lib.rs
@@ -74,6 +74,15 @@
 
 	#[pallet::call]
 	impl<T: Config> Pallet<T> {
+		/// Creates a new Base.
+		/// Modeled after [base interaction](https://github.com/rmrk-team/rmrk-spec/blob/master/standards/rmrk2.0.0/interactions/base.md)
+		///
+		/// Parameters:
+		/// - origin: Caller, will be assigned as the issuer of the Base
+		/// - base_type: media type, e.g. "svg"
+		/// - symbol: arbitrary client-chosen symbol
+		/// - parts: array of Fixed and Slot parts composing the base, confined in length by
+		///   RmrkPartsLimit
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn create_base(
@@ -94,7 +103,8 @@
 				..Default::default()
 			};
 
-			let collection_id_res = <PalletNft<T>>::init_collection(cross_sender.clone(), data);
+			let collection_id_res =
+				<PalletNft<T>>::init_collection(cross_sender.clone(), data, true);
 
 			if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
 				return Err(<Error<T>>::NoAvailableBaseId.into());
@@ -136,6 +146,19 @@
 			Ok(())
 		}
 
+		/// Adds a Theme to a Base.
+		/// Modeled after [themeadd interaction](https://github.com/rmrk-team/rmrk-spec/blob/master/standards/rmrk2.0.0/interactions/themeadd.md)
+		/// Themes are stored in the Themes storage
+		/// A Theme named "default" is required prior to adding other Themes.
+		///
+		/// Parameters:
+		/// - origin: The caller of the function, must be issuer of the base
+		/// - base_id: The Base containing the Theme to be updated
+		/// - theme: The Theme to add to the Base.  A Theme has a name and properties, which are an
+		///   array of [key, value, inherit].
+		///   - key: arbitrary BoundedString, defined by client
+		///   - value: arbitrary BoundedString, defined by client
+		///   - inherit: optional bool
 		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn theme_add(
@@ -155,6 +178,7 @@
 				misc::CollectionType::Base,
 			)
 			.map_err(|_| <Error<T>>::BaseDoesntExist)?;
+			collection.check_is_external()?;
 
 			if theme.name.as_slice() == b"default" {
 				<BaseHasDefaultTheme<T>>::insert(collection_id, true);
@@ -166,8 +190,8 @@
 				&sender,
 				owner,
 				&collection,
-				NftType::Theme,
 				[
+					<PalletCore<T>>::rmrk_property(TokenType, &NftType::Theme)?,
 					<PalletCore<T>>::rmrk_property(ThemeName, &theme.name)?,
 					<PalletCore<T>>::rmrk_property(ThemeInherit, &theme.inherit)?,
 				]
@@ -212,8 +236,8 @@
 			sender,
 			owner,
 			collection,
-			nft_type,
 			[
+				<PalletCore<T>>::rmrk_property(TokenType, &nft_type)?,
 				<PalletCore<T>>::rmrk_property(Src, &src)?,
 				<PalletCore<T>>::rmrk_property(ZIndex, &z_index)?,
 			]
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -200,7 +200,7 @@
 		owner: T::CrossAccountId,
 		data: CreateCollectionData<T::AccountId>,
 	) -> Result<CollectionId, DispatchError> {
-		<PalletCommon<T>>::init_collection(owner, data)
+		<PalletCommon<T>>::init_collection(owner, data, false)
 	}
 	pub fn destroy_collection(
 		collection: RefungibleHandle<T>,
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -149,19 +149,12 @@
 		})
 	}
 
-	/// Check if token indirectly owned by specified user
-	pub fn check_indirectly_owned(
-		user: T::CrossAccountId,
+	pub fn get_checked_topmost_owner(
 		collection: CollectionId,
 		token: TokenId,
 		for_nest: Option<(CollectionId, TokenId)>,
 		budget: &dyn Budget,
-	) -> Result<bool, DispatchError> {
-		let target_parent = match T::CrossTokenAddressMapping::address_to_token(&user) {
-			Some((collection, token)) => Self::find_topmost_owner(collection, token, budget)?,
-			None => user,
-		};
-
+	) -> Result<T::CrossAccountId, DispatchError> {
 		// Tried to nest token in itself
 		if Some((collection, token)) == for_nest {
 			return Err(<Error<T>>::OuroborosDetected.into());
@@ -173,10 +166,8 @@
 				Parent::Token(collection, token) if Some((collection, token)) == for_nest => {
 					return Err(<Error<T>>::OuroborosDetected.into())
 				}
-				// Found needed parent, token is indirecty owned
-				Parent::User(user) if user == target_parent => return Ok(true),
 				// Token is owned by other user
-				Parent::User(_) => return Ok(false),
+				Parent::User(user) => return Ok(user),
 				Parent::TokenNotFound => return Err(<Error<T>>::TokenNotFound.into()),
 				// Continue parent chain
 				Parent::Token(_, _) => {}
@@ -199,6 +190,23 @@
 		dispatch.burn_item_recursively(from.clone(), token, self_budget, breadth_budget)
 	}
 
+	/// Check if token indirectly owned by specified user
+	pub fn check_indirectly_owned(
+		user: T::CrossAccountId,
+		collection: CollectionId,
+		token: TokenId,
+		for_nest: Option<(CollectionId, TokenId)>,
+		budget: &dyn Budget,
+	) -> Result<bool, DispatchError> {
+		let target_parent = match T::CrossTokenAddressMapping::address_to_token(&user) {
+			Some((collection, token)) => Self::find_topmost_owner(collection, token, budget)?,
+			None => user,
+		};
+
+		Self::get_checked_topmost_owner(collection, token, for_nest, budget)
+			.map(|indirect_owner| indirect_owner == target_parent)
+	}
+
 	pub fn check_nesting(
 		from: T::CrossAccountId,
 		under: &T::CrossAccountId,
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -92,8 +92,9 @@
 			..Default::default()
 		};
 
-		let collection_id = <pallet_nonfungible::Pallet<T>>::init_collection(caller.clone(), data)
-			.map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
+		let collection_id =
+			<pallet_nonfungible::Pallet<T>>::init_collection(caller.clone(), data, false)
+				.map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
 
 		let address = pallet_common::eth::collection_id_to_address(collection_id);
 		Ok(address)
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -44,7 +44,7 @@
 };
 use pallet_evm::account::CrossAccountId;
 use pallet_common::{
-	CollectionHandle, Pallet as PalletCommon, CommonWeightInfo, dispatch::dispatch_call,
+	CollectionHandle, Pallet as PalletCommon, CommonWeightInfo, dispatch::dispatch_tx,
 	dispatch::CollectionDispatch,
 };
 pub mod eth;
@@ -304,6 +304,7 @@
 		pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			collection.check_is_internal()?;
 
 			// =========
 
@@ -338,6 +339,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			collection.check_is_internal()?;
 
 			<PalletCommon<T>>::toggle_allowlist(
 				&collection,
@@ -372,6 +374,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			collection.check_is_internal()?;
 
 			<PalletCommon<T>>::toggle_allowlist(
 				&collection,
@@ -406,6 +409,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			target_collection.check_is_internal()?;
 			target_collection.check_is_owner(&sender)?;
 
 			target_collection.owner = new_owner.clone();
@@ -435,6 +439,7 @@
 		pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			collection.check_is_internal()?;
 
 			<Pallet<T>>::deposit_event(Event::<T>::CollectionAdminAdded(
 				collection_id,
@@ -461,6 +466,7 @@
 		pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			collection.check_is_internal()?;
 
 			<Pallet<T>>::deposit_event(Event::<T>::CollectionAdminRemoved(
 				collection_id,
@@ -486,8 +492,9 @@
 
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
 			target_collection.check_is_owner(&sender)?;
+			target_collection.check_is_internal()?;
 
-			target_collection.set_sponsor(new_sponsor.clone());
+			target_collection.set_sponsor(new_sponsor.clone())?;
 
 			<Pallet<T>>::deposit_event(Event::<T>::CollectionSponsorSet(
 				collection_id,
@@ -510,8 +517,9 @@
 			let sender = ensure_signed(origin)?;
 
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			target_collection.check_is_internal()?;
 			ensure!(
-				target_collection.confirm_sponsorship(&sender),
+				target_collection.confirm_sponsorship(&sender)?,
 				Error::<T>::ConfirmUnsetSponsorFail
 			);
 
@@ -538,6 +546,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			target_collection.check_is_internal()?;
 			target_collection.check_is_owner(&sender)?;
 
 			target_collection.sponsorship = SponsorshipState::Disabled;
@@ -572,7 +581,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let budget = budget::Value::new(NESTING_BUDGET);
 
-			dispatch_call::<T, _>(collection_id, |d| d.create_item(sender, owner, data, &budget))
+			dispatch_tx::<T, _>(collection_id, |d| d.create_item(sender, owner, data, &budget))
 		}
 
 		/// This method creates multiple items in a collection created with CreateCollection method.
@@ -600,7 +609,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let budget = budget::Value::new(NESTING_BUDGET);
 
-			dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data, &budget))
+			dispatch_tx::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data, &budget))
 		}
 
 		#[weight = T::CommonWeightInfo::set_collection_properties(properties.len() as u32)]
@@ -614,7 +623,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			dispatch_call::<T, _>(collection_id, |d| d.set_collection_properties(sender, properties))
+			dispatch_tx::<T, _>(collection_id, |d| d.set_collection_properties(sender, properties))
 		}
 
 		#[weight = T::CommonWeightInfo::delete_collection_properties(property_keys.len() as u32)]
@@ -628,7 +637,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			dispatch_call::<T, _>(collection_id, |d| d.delete_collection_properties(&sender, property_keys))
+			dispatch_tx::<T, _>(collection_id, |d| d.delete_collection_properties(&sender, property_keys))
 		}
 
 		#[weight = T::CommonWeightInfo::set_token_properties(properties.len() as u32)]
@@ -643,7 +652,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			dispatch_call::<T, _>(collection_id, |d| d.set_token_properties(sender, token_id, properties))
+			dispatch_tx::<T, _>(collection_id, |d| d.set_token_properties(sender, token_id, properties))
 		}
 
 		#[weight = T::CommonWeightInfo::delete_token_properties(property_keys.len() as u32)]
@@ -658,7 +667,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			dispatch_call::<T, _>(collection_id, |d| d.delete_token_properties(sender, token_id, property_keys))
+			dispatch_tx::<T, _>(collection_id, |d| d.delete_token_properties(sender, token_id, property_keys))
 		}
 
 		#[weight = T::CommonWeightInfo::set_property_permissions(property_permissions.len() as u32)]
@@ -672,7 +681,7 @@
 
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			dispatch_call::<T, _>(collection_id, |d| d.set_property_permissions(&sender, property_permissions))
+			dispatch_tx::<T, _>(collection_id, |d| d.set_property_permissions(&sender, property_permissions))
 		}
 
 		#[weight = T::CommonWeightInfo::create_multiple_items_ex(&data)]
@@ -681,7 +690,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let budget = budget::Value::new(NESTING_BUDGET);
 
-			dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data, &budget))
+			dispatch_tx::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data, &budget))
 		}
 
 		// TODO! transaction weight
@@ -702,6 +711,7 @@
 		pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			target_collection.check_is_internal()?;
 			target_collection.check_is_owner(&sender)?;
 
 			// =========
@@ -728,7 +738,7 @@
 		pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			let post_info = dispatch_call::<T, _>(collection_id, |d| d.burn_item(sender, item_id, value))?;
+			let post_info = dispatch_tx::<T, _>(collection_id, |d| d.burn_item(sender, item_id, value))?;
 			if value == 1 {
 				<NftTransferBasket<T>>::remove(collection_id, item_id);
 				<NftApproveBasket<T>>::remove(collection_id, item_id);
@@ -761,7 +771,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let budget = budget::Value::new(NESTING_BUDGET);
 
-			dispatch_call::<T, _>(collection_id, |d| d.burn_from(sender, from, item_id, value, &budget))
+			dispatch_tx::<T, _>(collection_id, |d| d.burn_from(sender, from, item_id, value, &budget))
 		}
 
 		/// Change ownership of the token.
@@ -793,7 +803,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let budget = budget::Value::new(NESTING_BUDGET);
 
-			dispatch_call::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value, &budget))
+			dispatch_tx::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value, &budget))
 		}
 
 		/// Set, change, or remove approved address to transfer the ownership of the NFT.
@@ -816,7 +826,7 @@
 		pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
-			dispatch_call::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))
+			dispatch_tx::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))
 		}
 
 		/// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.
@@ -844,7 +854,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let budget = budget::Value::new(NESTING_BUDGET);
 
-			dispatch_call::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value, &budget))
+			dispatch_tx::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value, &budget))
 		}
 
 		#[weight = <SelfWeightOf<T>>::set_collection_limits()]
@@ -856,6 +866,7 @@
 		) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			target_collection.check_is_internal()?;
 			target_collection.check_is_owner(&sender)?;
 			let old_limit = &target_collection.limits;
 
@@ -877,6 +888,7 @@
 		) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
+			target_collection.check_is_internal()?;
 			target_collection.check_is_owner(&sender)?;
 			let old_limit = &target_collection.permissions;
 
modifiedprimitives/data-structs/Cargo.tomldiffbeforeafterboth
--- a/primitives/data-structs/Cargo.toml
+++ b/primitives/data-structs/Cargo.toml
@@ -26,6 +26,7 @@
 derivative = { version = "2.2.0", features = ["use_core"] }
 struct-versioning = { path = "../../crates/struct-versioning" }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.22" }
+rmrk-traits = { default-features = false, path = "../rmrk-traits" }
 
 [features]
 default = ["std"]
@@ -39,7 +40,8 @@
   "sp-core/std",
   "sp-std/std",
   "pallet-evm/std",
+  "rmrk-traits/std",
 ]
 serde1 = ["serde/alloc"]
 limit-testing = []
-runtime-benchmarks = []
\ No newline at end of file
+runtime-benchmarks = []
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -36,21 +36,18 @@
 use derivative::Derivative;
 use scale_info::TypeInfo;
 
-pub mod rmrk;
-
 // RMRK
-use rmrk::{
+use rmrk_traits::{
 	CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme, ThemeProperty,
+	ResourceTypes, BasicResource, ComposableResource, SlotResource,
 };
-pub use rmrk::{
+pub use rmrk_traits::{
 	primitives::{
 		CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId,
 		PartId as RmrkPartId, ResourceId as RmrkResourceId,
 	},
 	NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
 	FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart, EquippableList as RmrkEquippableList,
-	BasicResource as RmrkBasicResource, ComposableResource as RmrkComposableResource,
-	SlotResource as RmrkSlotResource,
 };
 
 mod bounded;
@@ -317,6 +314,10 @@
 	#[version(2.., upper(Default::default()))]
 	pub permissions: CollectionPermissions,
 
+	/// Marks that this collection is not "unique", and managed from external.
+	#[version(2.., upper(false))]
+	pub external_collection: bool,
+
 	#[version(..2)]
 	pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,
 
@@ -341,6 +342,7 @@
 	pub permissions: CollectionPermissions,
 	pub token_property_permissions: Vec<PropertyKeyPermission>,
 	pub properties: Vec<Property>,
+	pub read_only: bool,
 }
 
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Derivative, MaxEncodedLen)]
@@ -455,6 +457,8 @@
 	}
 }
 
+pub type OwnerRestrictedSet = BoundedBTreeSet<CollectionId, ConstU32<16>>;
+
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
@@ -467,7 +471,7 @@
 	OwnerRestricted(
 		#[cfg_attr(feature = "serde1", serde(with = "bounded::set_serde"))]
 		#[derivative(Debug(format_with = "bounded::set_debug"))]
-		BoundedBTreeSet<CollectionId, ConstU32<16>>,
+		OwnerRestrictedSet,
 	),
 	/// Used for tests
 	Permissive,
@@ -925,6 +929,8 @@
 	pub const RmrkMaxCollectionsEquippablePerPart: u32 = 100;
 	#[derive(PartialEq)]
 	pub const RmrkPartsLimit: u32 = 3;
+	#[derive(PartialEq)]
+	pub const RmrkMaxPriorities: u32 = 3;
 }
 
 impl From<RmrkCollectionId> for CollectionId {
@@ -942,23 +948,26 @@
 pub type RmrkCollectionInfo<AccountId> =
 	CollectionInfo<RmrkString, RmrkCollectionSymbol, AccountId>;
 pub type RmrkInstanceInfo<AccountId> = NftInfo<AccountId, Permill, RmrkString>;
-pub type RmrkResourceInfo = ResourceInfo<RmrkBoundedResource, RmrkString, RmrkBoundedParts>;
+pub type RmrkResourceInfo = ResourceInfo<RmrkString, RmrkBoundedParts>;
 pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
 pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
 pub type RmrkPartType =
 	PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;
 pub type RmrkThemeProperty = ThemeProperty<RmrkString>;
 pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;
+pub type RmrkResourceTypes = ResourceTypes<RmrkString, RmrkBoundedParts>;
+
+pub type RmrkBasicResource = BasicResource<RmrkString>;
+pub type RmrkComposableResource = ComposableResource<RmrkString, RmrkBoundedParts>;
+pub type RmrkSlotResource = SlotResource<RmrkString>;
 
+pub type RmrkString = BoundedVec<u8, RmrkStringLimit>;
 pub type RmrkCollectionSymbol = BoundedVec<u8, RmrkCollectionSymbolLimit>;
 pub type RmrkKeyString = BoundedVec<u8, RmrkKeyLimit>;
 pub type RmrkValueString = BoundedVec<u8, RmrkValueLimit>;
-
-type RmrkBoundedResource = BoundedVec<u8, RmrkResourceSymbolLimit>;
-type RmrkBoundedParts = BoundedVec<RmrkPartId, RmrkPartsLimit>;
+pub type RmrkBoundedResource = BoundedVec<u8, RmrkResourceSymbolLimit>;
+pub type RmrkBoundedParts = BoundedVec<RmrkPartId, RmrkPartsLimit>; // todo make sure it is needed
 
 pub type RmrkRpcString = Vec<u8>;
 pub type RmrkThemeName = RmrkRpcString;
 pub type RmrkPropertyKey = RmrkRpcString;
-
-pub type RmrkString = BoundedVec<u8, RmrkStringLimit>;
deletedprimitives/data-structs/src/rmrk.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/rmrk.rs
+++ /dev/null
@@ -1,444 +0,0 @@
-use codec::{Decode, Encode, MaxEncodedLen};
-use scale_info::TypeInfo;
-
-use derivative::Derivative;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-use primitives::*;
-
-pub mod primitives {
-	pub type CollectionId = u32;
-	pub type ResourceId = u32;
-	pub type NftId = u32;
-	pub type BaseId = u32;
-	pub type SlotId = u32;
-	pub type PartId = u32;
-	pub type ZIndex = u32;
-}
-
-#[cfg(feature = "std")]
-mod serialize {
-	use core::convert::AsRef;
-	use serde::ser::{self, Serialize};
-
-	pub mod vec {
-		use super::*;
-
-		pub fn serialize<D, V, C>(value: &C, serializer: D) -> Result<D::Ok, D::Error>
-		where
-			D: ser::Serializer,
-			V: Serialize,
-			C: AsRef<[V]>,
-		{
-			value.as_ref().serialize(serializer)
-		}
-	}
-
-	pub mod opt_vec {
-		use super::*;
-
-		pub fn serialize<D, V, C>(value: &Option<C>, serializer: D) -> Result<D::Ok, D::Error>
-		where
-			D: ser::Serializer,
-			V: Serialize,
-			C: AsRef<[V]>,
-		{
-			match value {
-				Some(value) => super::vec::serialize(value, serializer),
-				None => serializer.serialize_none(),
-			}
-		}
-	}
-}
-
-/// Collection info.
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			AccountId: Serialize,
-			BoundedString: AsRef<[u8]>,
-			BoundedSymbol: AsRef<[u8]>
-		"#)
-)]
-pub struct CollectionInfo<BoundedString, BoundedSymbol, AccountId> {
-	/// Current bidder and bid price.
-	pub issuer: AccountId,
-
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub metadata: BoundedString,
-	pub max: Option<u32>,
-
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub symbol: BoundedSymbol,
-	pub nfts_count: u32,
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-pub enum AccountIdOrCollectionNftTuple<AccountId> {
-	AccountId(AccountId),
-	CollectionAndNftTuple(CollectionId, NftId),
-}
-
-/// Royalty information (recipient and amount)
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-pub struct RoyaltyInfo<AccountId, RoyaltyAmount> {
-	/// Recipient (AccountId) of the royalty
-	pub recipient: AccountId,
-	/// Amount (Permill) of the royalty
-	pub amount: RoyaltyAmount,
-}
-
-/// Nft info.
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			AccountId: Serialize,
-			RoyaltyAmount: Serialize,
-			BoundedString: AsRef<[u8]>
-		"#)
-)]
-pub struct NftInfo<AccountId, RoyaltyAmount, BoundedString> {
-	/// The owner of the NFT, can be either an Account or a tuple (CollectionId, NftId)
-	pub owner: AccountIdOrCollectionNftTuple<AccountId>,
-	/// Royalty (optional)
-	pub royalty: Option<RoyaltyInfo<AccountId, RoyaltyAmount>>,
-
-	/// Arbitrary data about an instance, e.g. IPFS hash
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub metadata: BoundedString,
-
-	/// Equipped state
-	pub equipped: bool,
-	/// Pending state (if sent to NFT)
-	pub pending: bool,
-}
-
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
-pub struct NftChild {
-	pub collection_id: CollectionId,
-	pub nft_id: NftId,
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, PartialEq, TypeInfo)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedKey: AsRef<[u8]>,
-			BoundedValue: AsRef<[u8]>
-		"#)
-)]
-pub struct PropertyInfo<BoundedKey, BoundedValue> {
-	/// Key of the property
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub key: BoundedKey,
-
-	/// Value of the property
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub value: BoundedValue,
-}
-
-#[derive(Encode, Decode, Default, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct BasicResource<BoundedString> {
-	/// If the resource is Media, the base property is absent. Media src should be a URI like an
-	/// IPFS hash.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub src: Option<BoundedString>,
-
-	/// Reference to IPFS location of metadata
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub metadata: Option<BoundedString>,
-
-	/// Optional location or identier of license
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub license: Option<BoundedString>,
-
-	/// If the resource has the thumb property, this will be a URI to a thumbnail of the given
-	/// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
-	/// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
-	/// another bird, showing the full render of one bird inside the other's inventory might be a
-	/// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
-	/// image that is lighter and faster to load but representative of this resource.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub thumb: Option<BoundedString>,
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedString: AsRef<[u8]>,
-			BoundedParts: AsRef<[PartId]>
-		"#)
-)]
-pub struct ComposableResource<BoundedString, BoundedParts> {
-	/// If a resource is composed, it will have an array of parts that compose it
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub parts: BoundedParts,
-
-	/// A Base is uniquely identified by the combination of the word `base`, its minting block
-	/// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
-	/// base-4477293-kanaria_superbird.
-	pub base: BaseId,
-
-	/// If the resource is Media, the base property is absent. Media src should be a URI like an
-	/// IPFS hash.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub src: Option<BoundedString>,
-
-	/// Reference to IPFS location of metadata
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub metadata: Option<BoundedString>,
-
-	/// If the resource has the slot property, it was designed to fit into a specific Base's slot.
-	/// The baseslot will be composed of two dot-delimited values, like so:
-	/// "base-4477293-kanaria_superbird.machine_gun_scope". This means: "This resource is
-	/// compatible with the machine_gun_scope slot of base base-4477293-kanaria_superbird
-
-	/// Optional location or identier of license
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub license: Option<BoundedString>,
-
-	/// If the resource has the thumb property, this will be a URI to a thumbnail of the given
-	/// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
-	/// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
-	/// another bird, showing the full render of one bird inside the other's inventory might be a
-	/// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
-	/// image that is lighter and faster to load but representative of this resource.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub thumb: Option<BoundedString>,
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct SlotResource<BoundedString> {
-	/// A Base is uniquely identified by the combination of the word `base`, its minting block
-	/// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
-	/// base-4477293-kanaria_superbird.
-	pub base: BaseId,
-
-	/// If the resource is Media, the base property is absent. Media src should be a URI like an
-	/// IPFS hash.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub src: Option<BoundedString>,
-
-	/// Reference to IPFS location of metadata
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub metadata: Option<BoundedString>,
-
-	/// If the resource has the slot property, it was designed to fit into a specific Base's slot.
-	/// The baseslot will be composed of two dot-delimited values, like so:
-	/// "base-4477293-kanaria_superbird.machine_gun_scope". This means: "This resource is
-	/// compatible with the machine_gun_scope slot of base base-4477293-kanaria_superbird
-	pub slot: SlotId,
-
-	/// The license field, if present, should contain a link to a license (IPFS or static HTTP
-	/// url), or an identifier, like RMRK_nocopy or ipfs://ipfs/someHashOfLicense.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub license: Option<BoundedString>,
-
-	/// If the resource has the thumb property, this will be a URI to a thumbnail of the given
-	/// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
-	/// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
-	/// another bird, showing the full render of one bird inside the other's inventory might be a
-	/// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
-	/// image that is lighter and faster to load but representative of this resource.
-	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
-	pub thumb: Option<BoundedString>,
-}
-
-#[derive(Encode, Decode, Derivative, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedString: AsRef<[u8]>,
-			BoundedParts: AsRef<[PartId]>
-		"#)
-)]
-#[derivative(Default(bound = ""))]
-pub enum ResourceTypes<BoundedString: Default, BoundedParts> {
-	#[derivative(Default)]
-	Basic(BasicResource<BoundedString>),
-	Composable(ComposableResource<BoundedString, BoundedParts>),
-	Slot(SlotResource<BoundedString>),
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedResource: AsRef<[u8]>,
-			BoundedString: AsRef<[u8]>,
-			BoundedParts: AsRef<[PartId]>
-		"#)
-)]
-pub struct ResourceInfo<BoundedResource, BoundedString: Default, BoundedParts> {
-	/// id is a 5-character string of reasonable uniqueness.
-	/// The combination of base ID and resource id should be unique across the entire RMRK
-	/// ecosystem which
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub id: BoundedResource,
-
-	/// Resource
-	pub resource: ResourceTypes<BoundedString, BoundedParts>,
-
-	/// If resource is sent to non-rootowned NFT, pending will be false and need to be accepted
-	pub pending: bool,
-
-	/// If resource removal request is sent by non-rootowned NFT, pending will be true and need to be accepted
-	pub pending_removal: bool,
-}
-
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			AccountId: Serialize,
-			BoundedString: AsRef<[u8]>
-		"#)
-)]
-pub struct BaseInfo<AccountId, BoundedString> {
-	/// Original creator of the Base
-	pub issuer: AccountId,
-
-	/// Specifies how an NFT should be rendered, ie "svg"
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub base_type: BoundedString,
-
-	/// User provided symbol during Base creation
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub symbol: BoundedString,
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct FixedPart<BoundedString> {
-	pub id: PartId,
-	pub z: ZIndex,
-
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub src: BoundedString,
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, Derivative, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = "BoundedCollectionList: AsRef<[CollectionId]>")
-)]
-#[derivative(Default(bound = ""))]
-pub enum EquippableList<BoundedCollectionList> {
-	All,
-
-	#[derivative(Default)]
-	Empty,
-
-	Custom(#[cfg_attr(feature = "std", serde(with = "serialize::vec"))] BoundedCollectionList),
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedString: AsRef<[u8]>,
-			BoundedCollectionList: AsRef<[CollectionId]>
-		"#)
-)]
-pub struct SlotPart<BoundedString, BoundedCollectionList> {
-	pub id: PartId,
-	pub equippable: EquippableList<BoundedCollectionList>,
-
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub src: BoundedString,
-
-	pub z: ZIndex,
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedString: AsRef<[u8]>,
-			BoundedCollectionList: AsRef<[CollectionId]>
-		"#)
-)]
-pub enum PartType<BoundedString, BoundedCollectionList> {
-	FixedPart(FixedPart<BoundedString>),
-	SlotPart(SlotPart<BoundedString, BoundedCollectionList>),
-}
-
-impl<BoundedString, BoundedCollectionList> PartType<BoundedString, BoundedCollectionList> {
-	pub fn id(&self) -> PartId {
-		match self {
-			Self::FixedPart(part) => part.id,
-			Self::SlotPart(part) => part.id,
-		}
-	}
-
-	pub fn src(&self) -> &BoundedString {
-		match self {
-			Self::FixedPart(part) => &part.src,
-			Self::SlotPart(part) => &part.src,
-		}
-	}
-
-	pub fn z_index(&self) -> ZIndex {
-		match self {
-			Self::FixedPart(part) => part.z,
-			Self::SlotPart(part) => part.z,
-		}
-	}
-}
-
-#[cfg_attr(feature = "std", derive(Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = r#"
-			BoundedString: AsRef<[u8]>,
-			PropertyList: AsRef<[ThemeProperty<BoundedString>]>,
-		"#)
-)]
-pub struct Theme<BoundedString, PropertyList> {
-	/// Name of the theme
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub name: BoundedString,
-
-	/// Theme properties
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub properties: PropertyList,
-	/// Inheritability
-	pub inherit: bool,
-}
-
-#[cfg_attr(feature = "std", derive(Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct ThemeProperty<BoundedString> {
-	/// Key of the property
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub key: BoundedString,
-
-	/// Value of the property
-	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-	pub value: BoundedString,
-}
modifiedprimitives/rmrk-rpc/Cargo.tomldiffbeforeafterboth
--- a/primitives/rmrk-rpc/Cargo.toml
+++ b/primitives/rmrk-rpc/Cargo.toml
@@ -11,7 +11,7 @@
 sp-api = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.22' }
 sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.22' }
 serde = { version = "1.0.130", default-features = false, features = ["derive"] }
-up-data-structs = { default-features = false, path = '../data-structs' }
+rmrk-traits = { default-features = false, path = "../rmrk-traits" }
 
 [features]
 default = ["std"]
@@ -22,5 +22,5 @@
 	"sp-api/std",
 	"sp-runtime/std",
 	"serde/std",
-	"up-data-structs/std",
+	"rmrk-traits/std",
 ]
modifiedprimitives/rmrk-rpc/src/lib.rsdiffbeforeafterboth
--- a/primitives/rmrk-rpc/src/lib.rs
+++ b/primitives/rmrk-rpc/src/lib.rs
@@ -1,9 +1,25 @@
+// 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)]
 
 use sp_api::{Encode, Decode};
 use sp_std::vec::Vec;
 use sp_runtime::DispatchError;
-use up_data_structs::rmrk::{primitives::*, NftChild};
+use rmrk_traits::{primitives::*, NftChild};
 
 pub type Result<T> = core::result::Result<T, DispatchError>;
 
@@ -50,7 +66,7 @@
 
 		fn nft_resources(collection_id: CollectionId, nft_id: NftId) -> Result<Vec<ResourceInfo>>;
 
-		fn nft_resource_priorities(collection_id: CollectionId, nft_id: NftId) -> Result<Vec<ResourceId>>;
+		fn nft_resource_priority(collection_id: CollectionId, nft_id: NftId, resource_id: ResourceId) -> Result<Option<u32>>;
 
 		fn base(base_id: BaseId) -> Result<Option<BaseInfo>>;
 
addedprimitives/rmrk-traits/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "rmrk-traits"
+authors = ["Unique Network <support@uniquenetwork.io>"]
+description = "RMRK proxy data structs definitions"
+edition = "2021"
+license = 'GPLv3'
+homepage = "https://unique.network"
+repository = 'https://github.com/UniqueNetwork/unique-chain'
+version = '0.1.0'
+
+[dependencies]
+scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
+codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false, features = ["derive"] }
+serde = { version = "1.0.130", features = ["derive"], default-features = false, optional = true }
+
+[features]
+default = ["std"]
+std = [
+  "serde1",
+  "serde/std",
+  "codec/std",
+]
+serde1 = ["serde/alloc"]
addedprimitives/rmrk-traits/src/base.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/base.rs
@@ -0,0 +1,34 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			AccountId: Serialize,
+			BoundedString: AsRef<[u8]>
+		"#)
+)]
+pub struct BaseInfo<AccountId, BoundedString> {
+	/// Original creator of the Base
+	pub issuer: AccountId,
+
+	/// Specifies how an NFT should be rendered, ie "svg"
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub base_type: BoundedString,
+
+	/// User provided symbol during Base creation
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub symbol: BoundedString,
+}
addedprimitives/rmrk-traits/src/collection.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/collection.rs
@@ -0,0 +1,35 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			AccountId: Serialize,
+			BoundedString: AsRef<[u8]>,
+			BoundedSymbol: AsRef<[u8]>
+		"#)
+)]
+pub struct CollectionInfo<BoundedString, BoundedSymbol, AccountId> {
+	/// Current bidder and bid price.
+	pub issuer: AccountId,
+
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub metadata: BoundedString,
+	pub max: Option<u32>,
+
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub symbol: BoundedSymbol,
+	pub nfts_count: u32,
+}
addedprimitives/rmrk-traits/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/lib.rs
@@ -0,0 +1,33 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub mod base;
+pub mod collection;
+pub mod nft;
+pub mod part;
+pub mod property;
+pub mod resource;
+pub mod theme;
+
+#[cfg(feature = "std")]
+mod serialize;
+
+pub use base::BaseInfo;
+pub use part::{EquippableList, FixedPart, PartType, SlotPart};
+pub use theme::{Theme, ThemeProperty};
+pub use collection::CollectionInfo;
+pub use nft::{AccountIdOrCollectionNftTuple, NftInfo, RoyaltyInfo, NftChild};
+pub use property::PropertyInfo;
+pub use resource::{BasicResource, ComposableResource, ResourceInfo, ResourceTypes, SlotResource};
+pub mod primitives {
+	pub type CollectionId = u32;
+	pub type ResourceId = u32;
+	pub type NftId = u32;
+	pub type BaseId = u32;
+	pub type SlotId = u32;
+	pub type PartId = u32;
+	pub type ZIndex = u32;
+}
addedprimitives/rmrk-traits/src/nft.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/nft.rs
@@ -0,0 +1,65 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+use crate::primitives::*;
+
+#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+pub enum AccountIdOrCollectionNftTuple<AccountId> {
+	AccountId(AccountId),
+	CollectionAndNftTuple(CollectionId, NftId),
+}
+
+/// Royalty information (recipient and amount)
+#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
+pub struct RoyaltyInfo<AccountId, RoyaltyAmount> {
+	/// Recipient (AccountId) of the royalty
+	pub recipient: AccountId,
+	/// Amount (Permill) of the royalty
+	pub amount: RoyaltyAmount,
+}
+
+/// Nft info.
+#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			AccountId: Serialize,
+			RoyaltyAmount: Serialize,
+			BoundedString: AsRef<[u8]>
+		"#)
+)]
+pub struct NftInfo<AccountId, RoyaltyAmount, BoundedString> {
+	/// The owner of the NFT, can be either an Account or a tuple (CollectionId, NftId)
+	pub owner: AccountIdOrCollectionNftTuple<AccountId>,
+	/// Royalty (optional)
+	pub royalty: Option<RoyaltyInfo<AccountId, RoyaltyAmount>>,
+
+	/// Arbitrary data about an instance, e.g. IPFS hash
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub metadata: BoundedString,
+
+	/// Equipped state
+	pub equipped: bool,
+	/// Pending state (if sent to NFT)
+	pub pending: bool,
+}
+
+#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
+#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
+pub struct NftChild {
+	pub collection_id: CollectionId,
+	pub nft_id: NftId,
+}
addedprimitives/rmrk-traits/src/part.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/part.rs
@@ -0,0 +1,93 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+use crate::primitives::*;
+
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
+pub struct FixedPart<BoundedString> {
+	pub id: PartId,
+	pub z: ZIndex,
+
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub src: BoundedString,
+}
+
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = "BoundedCollectionList: AsRef<[CollectionId]>")
+)]
+pub enum EquippableList<BoundedCollectionList> {
+	All,
+	Empty,
+	Custom(#[cfg_attr(feature = "std", serde(with = "serialize::vec"))] BoundedCollectionList),
+}
+
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedString: AsRef<[u8]>,
+			BoundedCollectionList: AsRef<[CollectionId]>
+		"#)
+)]
+pub struct SlotPart<BoundedString, BoundedCollectionList> {
+	pub id: PartId,
+	pub equippable: EquippableList<BoundedCollectionList>,
+
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub src: BoundedString,
+
+	pub z: ZIndex,
+}
+
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedString: AsRef<[u8]>,
+			BoundedCollectionList: AsRef<[CollectionId]>
+		"#)
+)]
+pub enum PartType<BoundedString, BoundedCollectionList> {
+	FixedPart(FixedPart<BoundedString>),
+	SlotPart(SlotPart<BoundedString, BoundedCollectionList>),
+}
+
+impl<BoundedString, BoundedCollectionList> PartType<BoundedString, BoundedCollectionList> {
+	pub fn id(&self) -> PartId {
+		match self {
+			Self::FixedPart(part) => part.id,
+			Self::SlotPart(part) => part.id,
+		}
+	}
+
+	pub fn src(&self) -> &BoundedString {
+		match self {
+			Self::FixedPart(part) => &part.src,
+			Self::SlotPart(part) => &part.src,
+		}
+	}
+
+	pub fn z_index(&self) -> ZIndex {
+		match self {
+			Self::FixedPart(part) => part.z,
+			Self::SlotPart(part) => part.z,
+		}
+	}
+}
addedprimitives/rmrk-traits/src/property.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/property.rs
@@ -0,0 +1,31 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Encode, Decode, PartialEq, TypeInfo)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedKey: AsRef<[u8]>,
+			BoundedValue: AsRef<[u8]>
+		"#)
+)]
+pub struct PropertyInfo<BoundedKey, BoundedValue> {
+	/// Key of the property
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub key: BoundedKey,
+
+	/// Value of the property
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub value: BoundedValue,
+}
addedprimitives/rmrk-traits/src/resource.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/resource.rs
@@ -0,0 +1,168 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+use crate::primitives::*;
+
+#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
+pub struct BasicResource<BoundedString> {
+	/// If the resource is Media, the base property is absent. Media src should be a URI like an
+	/// IPFS hash.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub src: Option<BoundedString>,
+
+	/// Reference to IPFS location of metadata
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub metadata: Option<BoundedString>,
+
+	/// Optional location or identier of license
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub license: Option<BoundedString>,
+
+	/// If the resource has the thumb property, this will be a URI to a thumbnail of the given
+	/// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
+	/// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
+	/// another bird, showing the full render of one bird inside the other's inventory might be a
+	/// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
+	/// image that is lighter and faster to load but representative of this resource.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub thumb: Option<BoundedString>,
+}
+
+#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedString: AsRef<[u8]>,
+			BoundedParts: AsRef<[PartId]>
+		"#)
+)]
+pub struct ComposableResource<BoundedString, BoundedParts> {
+	/// If a resource is composed, it will have an array of parts that compose it
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub parts: BoundedParts,
+
+	/// A Base is uniquely identified by the combination of the word `base`, its minting block
+	/// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
+	/// base-4477293-kanaria_superbird.
+	pub base: BaseId,
+
+	/// If the resource is Media, the base property is absent. Media src should be a URI like an
+	/// IPFS hash.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub src: Option<BoundedString>,
+
+	/// Reference to IPFS location of metadata
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub metadata: Option<BoundedString>,
+
+	/// If the resource has the slot property, it was designed to fit into a specific Base's slot.
+	/// The baseslot will be composed of two dot-delimited values, like so:
+	/// "base-4477293-kanaria_superbird.machine_gun_scope". This means: "This resource is
+	/// compatible with the machine_gun_scope slot of base base-4477293-kanaria_superbird
+
+	/// Optional location or identier of license
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub license: Option<BoundedString>,
+
+	/// If the resource has the thumb property, this will be a URI to a thumbnail of the given
+	/// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
+	/// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
+	/// another bird, showing the full render of one bird inside the other's inventory might be a
+	/// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
+	/// image that is lighter and faster to load but representative of this resource.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub thumb: Option<BoundedString>,
+}
+
+#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
+pub struct SlotResource<BoundedString> {
+	/// A Base is uniquely identified by the combination of the word `base`, its minting block
+	/// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
+	/// base-4477293-kanaria_superbird.
+	pub base: BaseId,
+
+	/// If the resource is Media, the base property is absent. Media src should be a URI like an
+	/// IPFS hash.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub src: Option<BoundedString>,
+
+	/// Reference to IPFS location of metadata
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub metadata: Option<BoundedString>,
+
+	/// If the resource has the slot property, it was designed to fit into a specific Base's slot.
+	/// The baseslot will be composed of two dot-delimited values, like so:
+	/// "base-4477293-kanaria_superbird.machine_gun_scope". This means: "This resource is
+	/// compatible with the machine_gun_scope slot of base base-4477293-kanaria_superbird
+	pub slot: SlotId,
+
+	/// The license field, if present, should contain a link to a license (IPFS or static HTTP
+	/// url), or an identifier, like RMRK_nocopy or ipfs://ipfs/someHashOfLicense.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub license: Option<BoundedString>,
+
+	/// If the resource has the thumb property, this will be a URI to a thumbnail of the given
+	/// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
+	/// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
+	/// another bird, showing the full render of one bird inside the other's inventory might be a
+	/// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
+	/// image that is lighter and faster to load but representative of this resource.
+	#[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
+	pub thumb: Option<BoundedString>,
+}
+
+#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedString: AsRef<[u8]>,
+			BoundedParts: AsRef<[PartId]>
+		"#)
+)]
+pub enum ResourceTypes<BoundedString, BoundedParts> {
+	Basic(BasicResource<BoundedString>),
+	Composable(ComposableResource<BoundedString, BoundedParts>),
+	Slot(SlotResource<BoundedString>),
+}
+
+#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedString: AsRef<[u8]>,
+			BoundedParts: AsRef<[PartId]>
+		"#)
+)]
+pub struct ResourceInfo<BoundedString, BoundedParts> {
+	/// id is a 5-character string of reasonable uniqueness.
+	/// The combination of base ID and resource id should be unique across the entire RMRK
+	/// ecosystem which
+	//#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub id: ResourceId,
+
+	/// Resource
+	pub resource: ResourceTypes<BoundedString, BoundedParts>,
+
+	/// If resource is sent to non-rootowned NFT, pending will be false and need to be accepted
+	pub pending: bool,
+
+	/// If resource removal request is sent by non-rootowned NFT, pending will be true and need to be accepted
+	pub pending_removal: bool,
+}
addedprimitives/rmrk-traits/src/serialize.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/serialize.rs
@@ -0,0 +1,35 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use core::convert::AsRef;
+use serde::ser::{self, Serialize};
+
+pub mod vec {
+	use super::*;
+
+	pub fn serialize<D, V, C>(value: &C, serializer: D) -> Result<D::Ok, D::Error>
+	where
+		D: ser::Serializer,
+		V: Serialize,
+		C: AsRef<[V]>,
+	{
+		value.as_ref().serialize(serializer)
+	}
+}
+
+pub mod opt_vec {
+	use super::*;
+
+	pub fn serialize<D, V, C>(value: &Option<C>, serializer: D) -> Result<D::Ok, D::Error>
+	where
+		D: ser::Serializer,
+		V: Serialize,
+		C: AsRef<[V]>,
+	{
+		match value {
+			Some(value) => super::vec::serialize(value, serializer),
+			None => serializer.serialize_none(),
+		}
+	}
+}
addedprimitives/rmrk-traits/src/theme.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/rmrk-traits/src/theme.rs
@@ -0,0 +1,46 @@
+// Copyright (C) 2021-2022 RMRK
+// This file is part of rmrk-substrate.
+// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
+
+use codec::{Decode, Encode};
+use scale_info::TypeInfo;
+
+#[cfg(feature = "std")]
+use serde::Serialize;
+
+#[cfg(feature = "std")]
+use crate::serialize;
+
+#[cfg_attr(feature = "std", derive(Eq, Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
+#[cfg_attr(
+	feature = "std",
+	serde(bound = r#"
+			BoundedString: AsRef<[u8]>,
+			PropertyList: AsRef<[ThemeProperty<BoundedString>]>,
+		"#)
+)]
+pub struct Theme<BoundedString, PropertyList> {
+	/// Name of the theme
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub name: BoundedString,
+
+	/// Theme properties
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub properties: PropertyList,
+	/// Inheritability
+	pub inherit: bool,
+}
+
+#[cfg_attr(feature = "std", derive(Eq, Serialize))]
+#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
+pub struct ThemeProperty<BoundedString> {
+	/// Key of the property
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub key: BoundedString,
+
+	/// Value of the property
+	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
+	pub value: BoundedString,
+}
modifiedruntime/common/src/constants.rsdiffbeforeafterboth
--- a/runtime/common/src/constants.rs
+++ b/runtime/common/src/constants.rs
@@ -1,3 +1,19 @@
+// 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 sp_runtime::Perbill;
 use frame_support::{
 	parameter_types,
modifiedruntime/common/src/dispatch.rsdiffbeforeafterboth
--- a/runtime/common/src/dispatch.rs
+++ b/runtime/common/src/dispatch.rs
@@ -1,3 +1,19 @@
+// 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 frame_support::{dispatch::DispatchResult, ensure};
 use pallet_evm::{PrecompileHandle, PrecompileResult};
 use sp_core::H160;
@@ -35,7 +51,7 @@
 		data: CreateCollectionData<T::AccountId>,
 	) -> DispatchResult {
 		let _id = match data.mode {
-			CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data)?,
+			CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data, false)?,
 			CollectionMode::Fungible(decimal_points) => {
 				// check params
 				ensure!(
modifiedruntime/common/src/lib.rsdiffbeforeafterboth
--- a/runtime/common/src/lib.rs
+++ b/runtime/common/src/lib.rs
@@ -1,3 +1,19 @@
+// 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)]
 
 pub mod constants;
modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -1,3 +1,19 @@
+// 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/>.
+
 #[macro_export]
 macro_rules! impl_common_runtime_apis {
     (
@@ -128,8 +144,6 @@
                 }
             }
 
-            /*
-            TODO free RMRK!
             impl rmrk_rpc::RmrkApi<
                 Block,
                 AccountId,
@@ -146,90 +160,129 @@
                 }
 
                 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode, RmrkRebind}};
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};
+                    use pallet_common::CommonCollectionOperations;
 
-                    let collection_id = CollectionId(collection_id);
-                    let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(collection_id, CollectionType::Regular) {
                         Ok(c) => c,
                         Err(_) => return Ok(None),
                     };
 
-                    let nfts_count = dispatch_unique_runtime!(collection_id.total_supply())?;
+                    let nfts_count = collection.total_supply();
 
                     Ok(Some(RmrkCollectionInfo {
                         issuer: collection.owner.clone(),
-                        metadata: RmrkCore::get_collection_property(collection_id, RmrkProperty::Metadata)?.decode_or_default(),
+                        metadata: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::Metadata)?,
                         max: collection.limits.token_limit,
-                        symbol: collection.token_prefix.rebind(),
+                        symbol: RmrkCore::rebind(&collection.token_prefix)?,
                         nfts_count
                     }))
                 }
 
                 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
                     use up_data_structs::mapping::TokenAddressMapping;
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::RmrkDecode};
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};
+                    use pallet_common::CommonCollectionOperations;
 
-                    let collection_id = CollectionId(collection_id);
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(collection_id, CollectionType::Regular) {
+                        Ok(c) => c,
+                        Err(_) => return Ok(None),
+                    };
+
                     let nft_id = TokenId(nft_by_id);
                     if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(None); }
 
-                    let owner = match dispatch_unique_runtime!(collection_id.token_owner(nft_id))? {
+                    let owner = match collection.token_owner(nft_id) {
                         Some(owner) => match <Runtime as pallet_common::Config>::CrossTokenAddressMapping::address_to_token(&owner) {
-                            Some((col, tok)) => RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(col.0, tok.0),
+                            Some((col, tok)) => {
+                                let rmrk_collection = RmrkCore::rmrk_collection_id(col)?;
+
+                                RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(rmrk_collection, tok.0)
+                            }
                             None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone())
                         },
                         None => return Ok(None)
                     };
-
-                    let allowance = pallet_nonfungible::Allowance::<Runtime>::get((collection_id, nft_id));
 
                     Ok(Some(RmrkInstanceInfo {
                         owner: owner,
-                        royalty: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?.decode_or_default(),
-                        metadata: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::Metadata)?.decode_or_default(),
-                        equipped: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::Equipped)?.decode_or_default(),
-                        pending: allowance.is_some(),
+                        royalty: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?,
+                        metadata: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Metadata)?,
+                        equipped: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Equipped)?,
+                        pending: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::PendingNftAccept)?,
                     }))
                 }
 
                 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
-                    use pallet_proxy_rmrk_core::misc::CollectionType;
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};
+                    use pallet_common::CommonCollectionOperations;
 
                     let cross_account_id = CrossAccountId::from_sub(account_id);
-                    let collection_id = CollectionId(collection_id);
-                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }
 
-                    Ok(
-                        dispatch_unique_runtime!(collection_id.account_tokens(cross_account_id))?
-                            .into_iter()
-                            .map(|token| token.0)
-                            .collect()
-                    )
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(collection_id, CollectionType::Regular) {
+                        Ok(c) => c,
+                        Err(_) => return Ok(Vec::new()),
+                    };
+
+                    let tokens = collection.account_tokens(cross_account_id)
+                        .into_iter()
+                        .filter(|token| {
+                            let is_pending = RmrkCore::get_nft_property_decoded(
+                                collection_id,
+                                *token,
+                                RmrkProperty::PendingNftAccept
+                            ).unwrap_or(true);
+
+                            !is_pending
+                        })
+                        .map(|token| token.0)
+                        .collect();
+
+                    Ok(tokens)
                 }
 
                 fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
-                    let collection_id = CollectionId(collection_id);
+                    use pallet_proxy_rmrk_core::RmrkProperty;
+
+                    let collection_id = match RmrkCore::unique_collection_id(collection_id) {
+                        Ok(id) => id,
+                        Err(_) => return Ok(Vec::new())
+                    };
                     let nft_id = TokenId(nft_id);
                     if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(Vec::new()); }
 
                     Ok(
                         pallet_nonfungible::TokenChildren::<Runtime>::iter_prefix((collection_id, nft_id))
-                            .filter_map(|(child_id, is_child)|
-                                match is_child {
-                                    true => Some(RmrkNftChild {
-                                        collection_id: child_id.0.0,
-                                        nft_id: child_id.1.0,
-                                    }),
-                                    false => None,
+                            .filter_map(|((child_collection, child_token), _)| {
+                                let is_pending = RmrkCore::get_nft_property_decoded(
+                                    child_collection,
+                                    child_token,
+                                    RmrkProperty::PendingNftAccept
+                                ).ok()?;
+
+                                if is_pending {
+                                    return None;
                                 }
-                            ).collect()
+
+                                let rmrk_child_collection = RmrkCore::rmrk_collection_id(
+                                    child_collection
+                                ).ok()?;
+
+                                Some(RmrkNftChild {
+                                    collection_id: rmrk_child_collection,
+                                    nft_id: child_token.0,
+                                })
+                            }).collect()
                     )
                 }
 
                 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
                     use pallet_proxy_rmrk_core::misc::CollectionType;
 
-                    let collection_id = CollectionId(collection_id);
+                    let collection_id = match RmrkCore::unique_collection_id(collection_id) {
+                        Ok(id) => id,
+                        Err(_) => return Ok(Vec::new())
+                    };
                     if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() {
                         return Ok(Vec::new());
                     }
@@ -250,7 +303,10 @@
                 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
                     use pallet_proxy_rmrk_core::misc::NftType;
 
-                    let collection_id = CollectionId(collection_id);
+                    let collection_id = match RmrkCore::unique_collection_id(collection_id) {
+                        Ok(id) => id,
+                        Err(_) => return Ok(Vec::new())
+                    };
                     let token_id = TokenId(nft_id);
 
                     if RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {
@@ -271,108 +327,121 @@
                 }
 
                 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
-                    use frame_support::BoundedVec;
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, ResourceType}};
+                    use pallet_common::CommonCollectionOperations;
 
-                    let collection_id = CollectionId(collection_id);
-                    if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); } // todo make sure the collection type doesn't matter
+                    let collection_id = match RmrkCore::unique_collection_id(collection_id) {
+                        Ok(id) => id,
+                        Err(_) => return Ok(Vec::new())
+                    };
+                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }
 
                     let nft_id = TokenId(nft_id);
-                    if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Resource).is_err() { return Ok(Vec::new()); }
+                    if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }
 
-                    let resource_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)
-                        .unwrap()
-                        .decode_or_default();
-                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }
+                    let res_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;
+                    let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;
 
-                    let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))
-                        .filter_map(|(resource_id, properties)| Some(RmrkResourceInfo {
-                            id: BoundedVec::default(), // todo ResourceId property
-                            pending: RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::PendingResourceAccept).unwrap().decode_or_default(),
-                            pending_removal: RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::PendingResourceRemoval).unwrap().decode_or_default(),
-                            resource: RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::ResourceType).unwrap().decode_or_default(),/* {
-                                RmrkResourceTypes::Basic(resource) => RmrkResourceTypes::Basic(),/*(RmrkBasicResource {
-                                    src: RmrkCore::get_nft_property_inner(properties, RmrkProperty::Src).unwrap().decode_or_default(),
-                                    metadata: RmrkCore::get_nft_property_inner(properties, RmrkProperty::Metadata).unwrap().decode_or_default(),
-                                    license: RmrkCore::get_nft_property_inner(properties, RmrkProperty::License).unwrap().decode_or_default(),
-                                    thumb: RmrkCore::get_nft_property_inner(properties, RmrkProperty::Thumb).unwrap().decode_or_default(),
-                                },*///BasicResource<BoundedString>)
-                                _ => todo!(), //RmrkResourceTypes::Composable(ComposableResource<BoundedString, BoundedParts>),
-                                //RmrkResourceTypes::Slot(SlotResource<BoundedString>),
-                            },*/
+                    let resources = resource_collection
+                        .collection_tokens()
+                        .iter()
+                        .filter_map(|(res_id)| Some(RmrkResourceInfo {
+                            id: res_id.0,
+                            pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).ok()?,
+                            pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).ok()?,
+                            resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).ok()? {
+                                ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {
+                                    src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
+                                    metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
+                                    license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
+                                    thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
+                                }),
+                                ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {
+                                    parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).ok()?,
+                                    base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).ok()?,
+                                    src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
+                                    metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
+                                    license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
+                                    thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
+                                }),
+                                ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {
+                                    base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).ok()?,
+                                    src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
+                                    metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
+                                    slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).ok()?,
+                                    license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
+                                    thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
+                                }),
+                            },
                         }))
                         .collect();
 
                     Ok(resources)
                 }
 
-                fn nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceId>, DispatchError> {
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};
+                fn nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};
 
-                    let collection_id = CollectionId(collection_id);
-                    if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); } // todo ensure the collection type doesn't matter
+                    let collection_id = match RmrkCore::unique_collection_id(collection_id) {
+                        Ok(id) => id,
+                        Err(_) => return Ok(None)
+                    };
+                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(None); }
 
                     let nft_id = TokenId(nft_id);
-                    if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Resource).is_err() { return Ok(Vec::new()); }
-
-                    /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)
-                        .unwrap()
-                        .decode_or_default();
-                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }
-
-                    let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))
-                        .filter_map(|(resource_id, properties)| Some((
-                            resource_id, // ResourceId property
-                            RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap().decode_or_default(),
-                        )))
-                        .collect()
-                        .sort_by_key(|(_, index)| *index)
-                        .into_iter().map(|(resource_id, _)| resource_id)*/
-                    let priorities = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourcePriorities)?.decode_or_default();
+                    if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(None); }
 
-                    Ok(priorities)
+                    let priorities: Vec<_> = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourcePriorities)?;
+                    Ok(
+                        priorities.into_iter()
+                            .enumerate()
+                            .find(|(_, id)| *id == resource_id)
+                            .map(|(priority, _): (usize, RmrkResourceId)| priority as u32)
+                    )
                 }
 
                 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
                     use pallet_proxy_rmrk_core::{
-                        RmrkProperty, misc::{CollectionType, RmrkDecode, RmrkRebind},
+                        RmrkProperty, misc::{CollectionType},
                     };
 
-                    let collection_id = CollectionId(base_id);
-                    let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Base) {
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(base_id, CollectionType::Base) {
                         Ok(c) => c,
                         Err(_) => return Ok(None),
                     };
 
                     Ok(Some(RmrkBaseInfo {
                         issuer: collection.owner.clone(),
-                        base_type: RmrkCore::get_collection_property(collection_id, RmrkProperty::BaseType)?.decode_or_default(),
-                        symbol: collection.token_prefix.rebind(),
+                        base_type: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::BaseType)?,
+                        symbol: RmrkCore::rebind(&collection.token_prefix)?,
                     }))
                 }
 
                 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};
+                    use pallet_common::CommonCollectionOperations;
 
-                    let collection_id = CollectionId(base_id);
-                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() { return Ok(Vec::new()); }
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(base_id, CollectionType::Base) {
+                        Ok(c) => c,
+                        Err(_) => return Ok(Vec::new()),
+                    };
 
-                    let parts = dispatch_unique_runtime!(collection_id.collection_tokens())?
+                    let parts = collection.collection_tokens()
                         .into_iter()
                         .filter_map(|token_id| {
                             let nft_type = RmrkCore::get_nft_type(collection_id, token_id).ok()?;
 
                             match nft_type {
                                 NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {
-                                    id: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?.decode_or_default(),
-                                    src: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::Src).ok()?.decode_or_default(),
-                                    z: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ZIndex).ok()?.decode_or_default(),
+                                    id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,
+                                    src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,
+                                    z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,
                                 })),
                                 NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {
-                                    id: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?.decode_or_default(),
-                                    src: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::Src).ok()?.decode_or_default(),
-                                    z: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ZIndex).ok()?.decode_or_default(),
-                                    equippable: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::EquippableList).ok()?.decode_or_default(),
+                                    id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,
+                                    src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,
+                                    z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,
+                                    equippable: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::EquippableList).ok()?,
                                 })),
                                 _ => None
                             }
@@ -383,22 +452,21 @@
                 }
 
                 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode}};
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};
+                    use pallet_common::CommonCollectionOperations;
 
-                    let collection_id = CollectionId(base_id);
-                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {
-                        return Ok(Vec::new());
-                    }
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(base_id, CollectionType::Base) {
+                        Ok(c) => c,
+                        Err(_) => return Ok(Vec::new()),
+                    };
 
-                    let theme_names = dispatch_unique_runtime!(collection_id.collection_tokens())?
+                    let theme_names = collection.collection_tokens()
                         .iter()
                         .filter_map(|token_id| {
-                            let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();
+                            let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).ok()?;
 
                             match nft_type {
-                                Theme => Some(
-                                    RmrkCore::get_nft_property(collection_id, *token_id, RmrkProperty::ThemeName).unwrap().decode_or_default()
-                                ),
+                                Theme => RmrkCore::get_nft_property_decoded(collection_id, *token_id, RmrkProperty::ThemeName).ok(),
                                 _ => None
                             }
                         })
@@ -410,22 +478,23 @@
                 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
                     use pallet_proxy_rmrk_core::{
                         RmrkProperty,
-                        misc::{CollectionType, NftType, RmrkDecode}
+                        misc::{CollectionType, NftType}
                     };
+                    use pallet_common::CommonCollectionOperations;
 
-                    let collection_id = CollectionId(base_id);
-                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {
-                        return Ok(None);
-                    }
+                    let (collection, collection_id) = match RmrkCore::get_typed_nft_collection_mapped(base_id, CollectionType::Base) {
+                        Ok(c) => c,
+                        Err(_) => return Ok(None),
+                    };
 
-                    let theme_info = dispatch_unique_runtime!(collection_id.collection_tokens())?
+                    let theme_info = collection.collection_tokens()
                         .into_iter()
                         .find_map(|token_id| {
                             RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;
 
-                            let name: RmrkString = RmrkCore::get_nft_property(
+                            let name: RmrkString = RmrkCore::get_nft_property_decoded(
                                 collection_id, token_id, RmrkProperty::ThemeName
-                            ).ok()?.decode_or_default();
+                            ).ok()?;
 
                             if name == theme_name {
                                 Some((name, token_id))
@@ -449,11 +518,11 @@
                         }
                     )?;
 
-                    let inherit = RmrkCore::get_nft_property(
+                    let inherit = RmrkCore::get_nft_property_decoded(
                         collection_id,
                         theme_id,
                         RmrkProperty::ThemeInherit
-                    )?.decode_or_default();
+                    )?;
 
                     let theme = RmrkTheme {
                         name,
@@ -463,7 +532,7 @@
 
                     Ok(Some(theme))
                 }
-            }*/
+            }
 
             impl sp_api::Core<Block> for Runtime {
                 fn version() -> RuntimeVersion {
@@ -775,6 +844,7 @@
                     list_benchmark!(list, extra, pallet_refungible, Refungible);
                     list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);
                     list_benchmark!(list, extra, pallet_unq_scheduler, Scheduler);
+                    list_benchmark!(list, extra, pallet_proxy_rmrk_core, RmrkCore);
                     // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate);
 
                     let storage_info = AllPalletsReversedWithSystemFirst::storage_info();
@@ -819,7 +889,7 @@
                     add_benchmark!(params, batches, pallet_refungible, Refungible);
                     add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);
                     add_benchmark!(params, batches, pallet_unq_scheduler, Scheduler);
-
+                    add_benchmark!(params, batches, pallet_proxy_rmrk_core, RmrkCore);
                     // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);
 
                     if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
modifiedruntime/common/src/types.rsdiffbeforeafterboth
--- a/runtime/common/src/types.rs
+++ b/runtime/common/src/types.rs
@@ -1,3 +1,19 @@
+// 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 sp_runtime::{
 	traits::{Verify, IdentifyAccount, BlakeTwo256},
 	generic, MultiSignature,
modifiedruntime/opal/src/lib.rsdiffbeforeafterboth
--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -73,7 +73,11 @@
 	CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
 	CollectionStats, RpcCollection,
 	mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
-	TokenChild,
+	TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
+	RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,
+	RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceTypes,
+	RmrkBasicResource, RmrkComposableResource, RmrkSlotResource, RmrkResourceId, RmrkBaseId,
+	RmrkFixedPart, RmrkSlotPart, RmrkString,
 };
 
 // use pallet_contracts::weights::WeightInfo;
@@ -914,15 +918,14 @@
 	type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
 }
 
-/*
-TODO free RMRK!
 impl pallet_proxy_rmrk_core::Config for Runtime {
+	type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
 	type Event = Event;
 }
 
 impl pallet_proxy_rmrk_equip::Config for Runtime {
 	type Event = Event;
-}*/
+}
 
 impl pallet_unique::Config for Runtime {
 	type Event = Event;
@@ -1164,10 +1167,8 @@
 		Refungible: pallet_refungible::{Pallet, Storage} = 68,
 		Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
 		Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
-		/* TODO free RMRK!
 		RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
 		RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
-		*/
 
 		// Frontier
 		EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -34,6 +34,7 @@
     'pallet-refungible/runtime-benchmarks',
     'pallet-nonfungible/runtime-benchmarks',
     'pallet-proxy-rmrk-core/runtime-benchmarks',
+    'pallet-proxy-rmrk-equip/runtime-benchmarks',
     'pallet-unique/runtime-benchmarks',
     'pallet-inflation/runtime-benchmarks',
     'pallet-unq-scheduler/runtime-benchmarks',
@@ -92,6 +93,7 @@
     'pallet-refungible/std',
     'pallet-nonfungible/std',
     'pallet-proxy-rmrk-core/std',
+    'pallet-proxy-rmrk-equip/std',
     'pallet-unique/std',
     'pallet-unq-scheduler/std',
     'pallet-charge-transaction/std',
@@ -417,6 +419,7 @@
 pallet-refungible = { default-features = false, path = "../../pallets/refungible" }
 pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
 pallet-proxy-rmrk-core = { default-features = false, path = "../../pallets/proxy-rmrk-core", package = "pallet-rmrk-core" }
+pallet-proxy-rmrk-equip = { default-features = false, path = "../../pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }
 pallet-unq-scheduler = { path = '../../pallets/scheduler', default-features = false }
 # pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' }
 pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.22", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }
modifiedruntime/quartz/src/lib.rsdiffbeforeafterboth
--- a/runtime/quartz/src/lib.rs
+++ b/runtime/quartz/src/lib.rs
@@ -70,10 +70,14 @@
 };
 use pallet_unq_scheduler::DispatchCall;
 use up_data_structs::{
-	CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits, 
-	CollectionStats, RpcCollection, 
+	CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
+	CollectionStats, RpcCollection,
 	mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
-	TokenChild,
+	TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
+	RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,
+	RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceTypes,
+	RmrkBasicResource, RmrkComposableResource, RmrkSlotResource, RmrkResourceId, RmrkBaseId,
+	RmrkFixedPart, RmrkSlotPart, RmrkString,
 };
 
 // use pallet_contracts::weights::WeightInfo;
@@ -95,7 +99,7 @@
 	},
 	generic::Era,
 	transaction_validity::TransactionValidityError,
-	DispatchErrorWithPostInfo, SaturatedConversion, 
+	DispatchErrorWithPostInfo, SaturatedConversion,
 };
 
 // pub use pallet_timestamp::Call as TimestampCall;
@@ -912,14 +916,15 @@
 impl pallet_nonfungible::Config for Runtime {
 	type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
 }
-/* TODO free RMRK!
+
 impl pallet_proxy_rmrk_core::Config for Runtime {
+	type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
 	type Event = Event;
 }
 
 impl pallet_proxy_rmrk_equip::Config for Runtime {
 	type Event = Event;
-}*/
+}
 
 impl pallet_unique::Config for Runtime {
 	type Event = Event;
@@ -1107,7 +1112,7 @@
 	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 EvmCollectionHelpersAddress: H160 = H160([
 		0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
@@ -1160,9 +1165,8 @@
 		Refungible: pallet_refungible::{Pallet, Storage} = 68,
 		Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
 		Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
-		/* TODO free RMRK!
 		RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
-		RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,*/
+		RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
 
 		// Frontier
 		EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -34,6 +34,7 @@
     'pallet-refungible/runtime-benchmarks',
     'pallet-nonfungible/runtime-benchmarks',
     'pallet-proxy-rmrk-core/runtime-benchmarks',
+    'pallet-proxy-rmrk-equip/runtime-benchmarks',
     'pallet-unique/runtime-benchmarks',
     'pallet-inflation/runtime-benchmarks',
     'pallet-unq-scheduler/runtime-benchmarks',
@@ -93,6 +94,7 @@
     'pallet-refungible/std',
     'pallet-nonfungible/std',
     'pallet-proxy-rmrk-core/std',
+    'pallet-proxy-rmrk-equip/std',
     'pallet-unique/std',
     'pallet-unq-scheduler/std',
     'pallet-charge-transaction/std',
@@ -410,6 +412,7 @@
 pallet-refungible = { default-features = false, path = "../../pallets/refungible" }
 pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
 pallet-proxy-rmrk-core = { default-features = false, path = "../../pallets/proxy-rmrk-core", package = "pallet-rmrk-core" }
+pallet-proxy-rmrk-equip = { default-features = false, path = "../../pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }
 pallet-unq-scheduler = { path = '../../pallets/scheduler', default-features = false }
 # pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' }
 pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.22", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }
modifiedruntime/unique/src/lib.rsdiffbeforeafterboth
--- a/runtime/unique/src/lib.rs
+++ b/runtime/unique/src/lib.rs
@@ -73,7 +73,11 @@
 	CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
 	CollectionStats, RpcCollection,
 	mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
-	TokenChild,
+	TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
+	RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,
+	RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceTypes,
+	RmrkBasicResource, RmrkComposableResource, RmrkSlotResource, RmrkResourceId, RmrkBaseId,
+	RmrkFixedPart, RmrkSlotPart, RmrkString,
 };
 
 // use pallet_contracts::weights::WeightInfo;
@@ -911,14 +915,15 @@
 impl pallet_nonfungible::Config for Runtime {
 	type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
 }
-/* TODO free RMRK!
+
 impl pallet_proxy_rmrk_core::Config for Runtime {
+	type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
 	type Event = Event;
 }
 
 impl pallet_proxy_rmrk_equip::Config for Runtime {
 	type Event = Event;
-}*/
+}
 
 impl pallet_unique::Config for Runtime {
 	type Event = Event;
@@ -1106,7 +1111,7 @@
 	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 EvmCollectionHelpersAddress: H160 = H160([
 		0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
@@ -1159,9 +1164,8 @@
 		Refungible: pallet_refungible::{Pallet, Storage} = 68,
 		Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
 		Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
-		/* TODO free RMRK!
 		RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
-		RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,*/
+		RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
 
 		// Frontier
 		EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -5,7 +5,7 @@
   "main": "",
   "devDependencies": {
     "@polkadot/ts": "0.4.22",
-    "@polkadot/typegen": "8.6.2",
+    "@polkadot/typegen": "8.7.2-11",
     "@types/chai": "^4.3.1",
     "@types/chai-as-promised": "^7.1.5",
     "@types/mocha": "^9.1.1",
@@ -37,6 +37,7 @@
     "testStructure": "mocha --timeout 9999999 -r ts-node/register ./**/nesting/**.test.ts",
     "testProperties": "mocha --timeout 9999999 -r ts-node/register ./**/properties.test.ts",
     "testMigrationStructure": "mocha --timeout 9999999 -r ts-node/register ./**/nesting/migration-check.test.ts",
+    "testRmrk": "mocha --timeout 9999999 -r ts-node/register ./**/rmrk/**.test.ts",
     "testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",
     "testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts",
     "testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts",
@@ -60,6 +61,7 @@
     "testBurnItem": "mocha --timeout 9999999 -r ts-node/register ./**/burnItem.test.ts",
     "testSetMintPermission": "mocha --timeout 9999999 -r ts-node/register ./**/setMintPermission.test.ts",
     "testCreditFeesToTreasury": "mocha --timeout 9999999 -r ts-node/register ./**/creditFeesToTreasury.test.ts",
+    "testContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/contractSponsoring.test.ts",
     "testEnableContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/enableContractSponsoring.test.ts",
     "testRemoveFromContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromContractAllowList.test.ts",
     "testSetContractSponsoringRateLimit": "mocha --timeout 9999999 -r ts-node/register ./**/setContractSponsoringRateLimit.test.ts",
@@ -84,9 +86,9 @@
   "license": "SEE LICENSE IN ../LICENSE",
   "homepage": "",
   "dependencies": {
-    "@polkadot/api": "8.6.2",
-    "@polkadot/api-contract": "8.6.2",
-    "@polkadot/util-crypto": "9.3.1",
+    "@polkadot/api": "8.7.2-11",
+    "@polkadot/api-contract": "8.7.2-11",
+    "@polkadot/util-crypto": "9.4.1",
     "bignumber.js": "^9.0.2",
     "chai-as-promised": "^7.1.1",
     "find-process": "^1.4.7",
deletedtests/src/accounts.tsdiffbeforeafterboth
--- a/tests/src/accounts.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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/>.
-
-export const bobsPublicKey = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty';
-export const alicesPublicKey = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
-export const ferdiesPublicKey = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL';
-export const nullPublicKey = '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM';
\ No newline at end of file
modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/addCollectionAdmin.test.ts
+++ b/tests/src/addCollectionAdmin.test.ts
@@ -40,8 +40,10 @@
       expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
     });
   });
+});
 
-  it('Add admin using added collection admin.', async () => {
+describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
+  it("Not owner can't add collection admin.", async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const collectionId = await createCollectionExpectSuccess();
       const alice = privateKeyWrapper('//Alice');
@@ -51,38 +53,43 @@
       const collection = await queryCollectionExpectSuccess(api, collectionId);
       expect(collection.owner.toString()).to.be.equal(alice.address);
 
-      const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
-      await submitTransactionAsync(alice, changeAdminTx);
-
       const adminListAfterAddAdmin = await getAdminList(api, collectionId);
-      expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
+      expect(adminListAfterAddAdmin).to.be.not.deep.contains(normalizeAccountId(bob.address));
 
       const changeAdminTxCharlie = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));
-      await submitTransactionAsync(bob, changeAdminTxCharlie);
+      await expect(submitTransactionAsync(bob, changeAdminTxCharlie)).to.be.rejected;
+     
       const adminListAfterAddNewAdmin = await getAdminList(api, collectionId);
-      expect(adminListAfterAddNewAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
-      expect(adminListAfterAddNewAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));
+      expect(adminListAfterAddNewAdmin).to.be.not.deep.contains(normalizeAccountId(bob.address));
+      expect(adminListAfterAddNewAdmin).to.be.not.deep.contains(normalizeAccountId(charlie.address));
     });
   });
-});
 
-describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
-  it("Not owner can't add collection admin.", async () => {
+  it("Admin can't add collection admin.", async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const collectionId = await createCollectionExpectSuccess();
       const alice = privateKeyWrapper('//Alice');
-      const nonOwner = privateKeyWrapper('//Bob_stash');
+      const bob = privateKeyWrapper('//Bob');
+      const charlie = privateKeyWrapper('//CHARLIE');
+
+      const collection = await queryCollectionExpectSuccess(api, collectionId);
+      expect(collection.owner.toString()).to.be.equal(alice.address);
 
-      const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(alice.address));
-      await expect(submitTransactionExpectFailAsync(nonOwner, changeAdminTx)).to.be.rejected;
+      const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
+      await submitTransactionAsync(alice, changeAdminTx);
 
       const adminListAfterAddAdmin = await getAdminList(api, collectionId);
-      expect(adminListAfterAddAdmin).not.to.be.deep.contains(normalizeAccountId(alice.address));
+      expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await createCollectionExpectSuccess();
+      const changeAdminTxCharlie = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));
+      await expect(submitTransactionAsync(bob, changeAdminTxCharlie)).to.be.rejected;
+     
+      const adminListAfterAddNewAdmin = await getAdminList(api, collectionId);
+      expect(adminListAfterAddNewAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
+      expect(adminListAfterAddNewAdmin).to.be.not.deep.contains(normalizeAccountId(charlie.address));
     });
   });
+
   it("Can't add collection admin of not existing collection.", async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       // tslint:disable-next-line: no-bitwise
modifiedtests/src/addToContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/addToContractAllowList.test.ts
+++ b/tests/src/addToContractAllowList.test.ts
@@ -32,7 +32,7 @@
   it('Add an address to a contract allow list', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const bob = privateKeyWrapper('//Bob');
-      const [contract, deployer] = await deployFlipper(api);
+      const [contract, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       const allowListedBefore = (await api.query.unique.contractAllowList(contract.address, bob.address)).toJSON();
       const addTx = api.tx.unique.addToContractAllowList(contract.address, bob.address);
@@ -48,7 +48,7 @@
   it('Adding same address to allow list repeatedly should not produce errors', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const bob = privateKeyWrapper('//Bob');
-      const [contract, deployer] = await deployFlipper(api);
+      const [contract, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       const allowListedBefore = (await api.query.unique.contractAllowList(contract.address, bob.address)).toJSON();
       const addTx = api.tx.unique.addToContractAllowList(contract.address, bob.address);
@@ -87,7 +87,7 @@
   it('Add to a contract allow list using a non-owner address', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const bob = privateKeyWrapper('//Bob');
-      const [contract] = await deployFlipper(api);
+      const [contract] = await deployFlipper(api, privateKeyWrapper);
 
       const allowListedBefore = (await api.query.unique.contractAllowList(contract.address, bob.address)).toJSON();
       const addTx = api.tx.unique.addToContractAllowList(contract.address, bob.address);
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -15,7 +15,6 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {Keyring} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import {
   createCollectionExpectSuccess,
@@ -37,10 +36,9 @@
 
 describe('integration test: ext. burnItem():', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
@@ -142,10 +140,9 @@
 
 describe('integration test: ext. burnItem() with admin permissions:', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
@@ -209,10 +206,9 @@
 
 describe('Negative integration test: ext. burnItem():', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
34 getCreatedCollectionCount,34 getCreatedCollectionCount,
35 UNIQUE,35 UNIQUE,
36} from './util/helpers';36} from './util/helpers';
37import {Keyring} from '@polkadot/api';
38import {IKeyringPair} from '@polkadot/types/types';37import {IKeyringPair} from '@polkadot/types/types';
3938
40chai.use(chaiAsPromised);39chai.use(chaiAsPromised);
47describe('integration test: ext. confirmSponsorship():', () => {46describe('integration test: ext. confirmSponsorship():', () => {
4847
49 before(async () => {48 before(async () => {
50 await usingApi(async () => {49 await usingApi(async (api, privateKeyWrapper) => {
51 const keyring = new Keyring({type: 'sr25519'});
52 alice = keyring.addFromUri('//Alice');50 alice = privateKeyWrapper('//Alice');
53 bob = keyring.addFromUri('//Bob');51 bob = privateKeyWrapper('//Bob');
54 charlie = keyring.addFromUri('//Charlie');52 charlie = privateKeyWrapper('//Charlie');
55 });53 });
56 });54 });
5755
78 await setCollectionSponsorExpectSuccess(collectionId, bob.address);76 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
79 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');77 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
8078
81 await usingApi(async (api) => {79 await usingApi(async (api, privateKeyWrapper) => {
82 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();80 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
8381
84 // Find unused address82 // Find unused address
85 const zeroBalance = await findUnusedAddress(api);83 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
8684
87 // Mint token for unused address85 // Mint token for unused address
88 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);86 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
105 await setCollectionSponsorExpectSuccess(collectionId, bob.address);103 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
106 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');104 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
107105
108 await usingApi(async (api) => {106 await usingApi(async (api, privateKeyWrapper) => {
109 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();107 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
110108
111 // Find unused address109 // Find unused address
112 const zeroBalance = await findUnusedAddress(api);110 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
113111
114 // Mint token for unused address112 // Mint token for unused address
115 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);113 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);
131 await setCollectionSponsorExpectSuccess(collectionId, bob.address);129 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
132 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');130 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
133131
134 await usingApi(async (api) => {132 await usingApi(async (api, privateKeyWrapper) => {
135 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();133 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
136134
137 // Find unused address135 // Find unused address
138 const zeroBalance = await findUnusedAddress(api);136 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
139137
140 // Mint token for unused address138 // Mint token for unused address
141 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);139 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);
164 await enablePublicMintingExpectSuccess(alice, collectionId);162 await enablePublicMintingExpectSuccess(alice, collectionId);
165163
166 // Create Item164 // Create Item
167 await usingApi(async (api) => {165 await usingApi(async (api, privateKeyWrapper) => {
168 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();166 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
169167
170 // Find unused address168 // Find unused address
171 const zeroBalance = await findUnusedAddress(api);169 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
172170
173 // Add zeroBalance address to allow list171 // Add zeroBalance address to allow list
174 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);172 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);
187 await setCollectionSponsorExpectSuccess(collectionId, bob.address);185 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
188 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');186 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
189187
190 await usingApi(async (api) => {188 await usingApi(async (api, privateKeyWrapper) => {
191 // Find unused address189 // Find unused address
192 const zeroBalance = await findUnusedAddress(api);190 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
193191
194 // Mint token for alice192 // Mint token for alice
195 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);193 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
226 await setCollectionSponsorExpectSuccess(collectionId, bob.address);224 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
227 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');225 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
228226
229 await usingApi(async (api) => {227 await usingApi(async (api, privateKeyWrapper) => {
230 // Find unused address228 // Find unused address
231 const zeroBalance = await findUnusedAddress(api);229 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
232230
233 // Mint token for unused address231 // Mint token for unused address
234 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);232 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);
259 await setCollectionSponsorExpectSuccess(collectionId, bob.address);257 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
260 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');258 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
261259
262 await usingApi(async (api) => {260 await usingApi(async (api, privateKeyWrapper) => {
263 // Find unused address261 // Find unused address
264 const zeroBalance = await findUnusedAddress(api);262 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
265263
266 // Mint token for alice264 // Mint token for alice
267 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);265 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);
299 // Enable public minting297 // Enable public minting
300 await enablePublicMintingExpectSuccess(alice, collectionId);298 await enablePublicMintingExpectSuccess(alice, collectionId);
301299
302 await usingApi(async (api) => {300 await usingApi(async (api, privateKeyWrapper) => {
303 // Find unused address301 // Find unused address
304 const zeroBalance = await findUnusedAddress(api);302 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
305303
306 // Add zeroBalance address to allow list304 // Add zeroBalance address to allow list
307 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);305 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);
331329
332describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {330describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {
333 before(async () => {331 before(async () => {
334 await usingApi(async () => {332 await usingApi(async (api, privateKeyWrapper) => {
335 const keyring = new Keyring({type: 'sr25519'});
336 alice = keyring.addFromUri('//Alice');333 alice = privateKeyWrapper('//Alice');
337 bob = keyring.addFromUri('//Bob');334 bob = privateKeyWrapper('//Bob');
338 charlie = keyring.addFromUri('//Charlie');335 charlie = privateKeyWrapper('//Charlie');
339 });336 });
340 });337 });
341338
390 await setCollectionSponsorExpectSuccess(collectionId, bob.address);387 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
391 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');388 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
392389
393 await usingApi(async (api) => {390 await usingApi(async (api, privateKeyWrapper) => {
394 // Find unused address391 // Find unused address
395 const ownerZeroBalance = await findUnusedAddress(api);392 const ownerZeroBalance = await findUnusedAddress(api, privateKeyWrapper);
396393
397 // Find another unused address394 // Find another unused address
398 const senderZeroBalance = await findUnusedAddress(api);395 const senderZeroBalance = await findUnusedAddress(api, privateKeyWrapper);
399396
400 // Mint token for an unused address397 // Mint token for an unused address
401 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', ownerZeroBalance.address);398 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', ownerZeroBalance.address);
modifiedtests/src/contracts.test.tsdiffbeforeafterboth
--- a/tests/src/contracts.test.ts
+++ b/tests/src/contracts.test.ts
@@ -50,7 +50,7 @@
 describe.skip('Contracts', () => {
   it('Can deploy smart contract Flipper, instantiate it and call it\'s get and flip messages.', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
-      const [contract, deployer] = await deployFlipper(api);
+      const [contract, deployer] = await deployFlipper(api, privateKeyWrapper);
       const initialGetResponse = await getFlipValue(contract, deployer);
 
       const bob = privateKeyWrapper('//Bob');
@@ -82,7 +82,7 @@
       // Prep work
       const collectionId = await createCollectionExpectSuccess();
       const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
-      const [contract] = await deployTransferContract(api);
+      const [contract] = await deployTransferContract(api, privateKeyWrapper);
       const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, contract.address);
       await submitTransactionAsync(alice, changeAdminTx);
 
@@ -104,7 +104,7 @@
       const bob = privateKeyWrapper('//Bob');
 
       const collectionId = await createCollectionExpectSuccess();
-      const [contract] = await deployTransferContract(api);
+      const [contract] = await deployTransferContract(api, privateKeyWrapper);
       await enablePublicMintingExpectSuccess(alice, collectionId);
       await enableAllowListExpectSuccess(alice, collectionId);
       await addToAllowListExpectSuccess(alice, collectionId, contract.address);
@@ -131,7 +131,7 @@
       const bob = privateKeyWrapper('//Bob');
 
       const collectionId = await createCollectionExpectSuccess();
-      const [contract] = await deployTransferContract(api);
+      const [contract] = await deployTransferContract(api, privateKeyWrapper);
       await enablePublicMintingExpectSuccess(alice, collectionId);
       await enableAllowListExpectSuccess(alice, collectionId);
       await addToAllowListExpectSuccess(alice, collectionId, contract.address);
@@ -173,7 +173,7 @@
       const charlie = privateKeyWrapper('//Charlie');
 
       const collectionId = await createCollectionExpectSuccess();
-      const [contract] = await deployTransferContract(api);
+      const [contract] = await deployTransferContract(api, privateKeyWrapper);
       const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', contract.address.toString());
 
       const transferTx = contract.tx.approve(value, gasLimit, bob.address, collectionId, tokenId, 1);
@@ -192,7 +192,7 @@
       const charlie = privateKeyWrapper('//Charlie');
 
       const collectionId = await createCollectionExpectSuccess();
-      const [contract] = await deployTransferContract(api);
+      const [contract] = await deployTransferContract(api, privateKeyWrapper);
       const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
       await approveExpectSuccess(collectionId, tokenId, bob, contract.address.toString(), 1);
 
@@ -212,7 +212,7 @@
       const bob = privateKeyWrapper('//Bob');
 
       const collectionId = await createCollectionExpectSuccess();
-      const [contract] = await deployTransferContract(api);
+      const [contract] = await deployTransferContract(api, privateKeyWrapper);
       const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, contract.address);
       await submitTransactionAsync(alice, changeAdminTx);
 
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -87,6 +87,18 @@
       expect(collection.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.equal(3);
     });
   });
+
+  it('New collection is not external', async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      const alice = privateKeyWrapper('//Alice');
+      const tx = api.tx.unique.createCollectionEx({ });
+      const events = await submitTransactionAsync(alice, tx);
+      const result = getCreateCollectionResult(events);
+
+      const collection = (await getDetailedCollectionInfo(api, result.collectionId))!;
+      expect(collection.readOnly.toHuman()).to.be.false;
+    });
+  });
 });
 
 describe('(!negative test!) integration test: ext. createCollection():', () => {
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -16,7 +16,6 @@
 
 import {default as usingApi} from './substrate/substrate-api';
 import chai from 'chai';
-import {Keyring} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import {
   createCollectionExpectSuccess,
@@ -33,10 +32,9 @@
 
 describe('integration test: ext. ():', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
@@ -101,10 +99,9 @@
 
 describe('Negative integration test: ext. createItem():', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
modifiedtests/src/creditFeesToTreasury.test.tsdiffbeforeafterboth
--- a/tests/src/creditFeesToTreasury.test.ts
+++ b/tests/src/creditFeesToTreasury.test.ts
@@ -18,7 +18,6 @@
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
 import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {alicesPublicKey, bobsPublicKey} from './accounts';
 import {IKeyringPair} from '@polkadot/types/types';
 import {
   createCollectionExpectSuccess,
@@ -71,17 +70,16 @@
   });
 
   it('Total issuance does not change', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
+    await usingApi(async (api) => {
       await skipInflationBlock(api);
       await waitNewBlocks(api, 1);
 
       const totalBefore = (await api.query.balances.totalIssuance()).toBigInt();
 
-      const alicePrivateKey = privateKeyWrapper('//Alice');
       const amount = 1n;
-      const transfer = api.tx.balances.transfer(bobsPublicKey, amount);
+      const transfer = api.tx.balances.transfer(bob.address, amount);
 
-      const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));
+      const result = getGenericResult(await submitTransactionAsync(alice, transfer));
 
       const totalAfter = (await api.query.balances.totalIssuance()).toBigInt();
 
@@ -91,20 +89,19 @@
   });
 
   it('Sender balance decreased by fee+sent amount, Treasury balance increased by fee', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
+    await usingApi(async (api) => {
       await skipInflationBlock(api);
       await waitNewBlocks(api, 1);
 
-      const alicePrivateKey = privateKeyWrapper('//Alice');
       const treasuryBalanceBefore: bigint = (await api.query.system.account(TREASURY)).data.free.toBigInt();
-      const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceBefore: bigint = (await api.query.system.account(alice.address)).data.free.toBigInt();
 
       const amount = 1n;
-      const transfer = api.tx.balances.transfer(bobsPublicKey, amount);
-      const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));
+      const transfer = api.tx.balances.transfer(bob.address, amount);
+      const result = getGenericResult(await submitTransactionAsync(alice, transfer));
 
       const treasuryBalanceAfter: bigint = (await api.query.system.account(TREASURY)).data.free.toBigInt();
-      const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceAfter: bigint = (await api.query.system.account(alice.address)).data.free.toBigInt();
       const fee = aliceBalanceBefore - aliceBalanceAfter - amount;
       const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;
 
@@ -114,19 +111,18 @@
   });
 
   it('Treasury balance increased by failed tx fee', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
+    await usingApi(async (api) => {
       //await skipInflationBlock(api);
       await waitNewBlocks(api, 1);
 
-      const bobPrivateKey = privateKeyWrapper('//Bob');
       const treasuryBalanceBefore = (await api.query.system.account(TREASURY)).data.free.toBigInt();
-      const bobBalanceBefore = (await api.query.system.account(bobsPublicKey)).data.free.toBigInt();
+      const bobBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
 
-      const badTx = api.tx.balances.setBalance(alicesPublicKey, 0, 0);
-      await expect(submitTransactionExpectFailAsync(bobPrivateKey, badTx)).to.be.rejected;
+      const badTx = api.tx.balances.setBalance(alice.address, 0, 0);
+      await expect(submitTransactionExpectFailAsync(bob, badTx)).to.be.rejected;
 
       const treasuryBalanceAfter = (await api.query.system.account(TREASURY)).data.free.toBigInt();
-      const bobBalanceAfter = (await api.query.system.account(bobsPublicKey)).data.free.toBigInt();
+      const bobBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
       const fee = bobBalanceBefore - bobBalanceAfter;
       const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;
 
@@ -140,12 +136,12 @@
       await waitNewBlocks(api, 1);
 
       const treasuryBalanceBefore = (await api.query.system.account(TREASURY)).data.free.toBigInt();
-      const aliceBalanceBefore = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceBefore = (await api.query.system.account(alice.address)).data.free.toBigInt();
 
       await createCollectionExpectSuccess();
 
       const treasuryBalanceAfter = (await api.query.system.account(TREASURY)).data.free.toBigInt();
-      const aliceBalanceAfter = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceAfter = (await api.query.system.account(alice.address)).data.free.toBigInt();
       const fee = aliceBalanceBefore - aliceBalanceAfter;
       const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;
 
@@ -158,11 +154,11 @@
       await skipInflationBlock(api);
       await waitNewBlocks(api, 1);
 
-      const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceBefore: bigint = (await api.query.system.account(alice.address)).data.free.toBigInt();
 
       await createCollectionExpectSuccess();
 
-      const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceAfter: bigint = (await api.query.system.account(alice.address)).data.free.toBigInt();
       const fee = aliceBalanceBefore - aliceBalanceAfter;
 
       expect(fee / UNIQUE < BigInt(Math.ceil(saneMaximumFee + createCollectionDeposit))).to.be.true;
@@ -178,9 +174,9 @@
       const collectionId = await createCollectionExpectSuccess();
       const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
 
-      const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceBefore: bigint = (await api.query.system.account(alice.address)).data.free.toBigInt();
       await transferExpectSuccess(collectionId, tokenId, alice, bob, 1, 'NFT');
-      const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
+      const aliceBalanceAfter: bigint = (await api.query.system.account(alice.address)).data.free.toBigInt();
 
       const fee = Number(aliceBalanceBefore - aliceBalanceAfter) / Number(UNIQUE);
       const expectedTransferFee = 0.1;
modifiedtests/src/enableContractSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/enableContractSponsoring.test.ts
+++ b/tests/src/enableContractSponsoring.test.ts
@@ -31,10 +31,10 @@
 
 describe.skip('Integration Test enableContractSponsoring', () => {
   it('ensure tx fee is paid from endowment', async () => {
-    await usingApi(async (api) => {
-      const user = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const user = await findUnusedAddress(api, privateKeyWrapper);
 
-      const [flipper, deployer] = await deployFlipper(api);
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
       await setContractSponsoringRateLimitExpectSuccess(deployer, flipper.address, 1);
       await toggleFlipValueExpectSuccess(user, flipper);
@@ -44,8 +44,8 @@
   });
 
   it('ensure it can be enabled twice', async () => {
-    await usingApi(async (api) => {
-      const [flipper, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
@@ -53,8 +53,8 @@
   });
 
   it('ensure it can be disabled twice', async () => {
-    await usingApi(async (api) => {
-      const [flipper, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, false);
@@ -63,8 +63,8 @@
   });
 
   it('ensure it can be re-enabled', async () => {
-    await usingApi(async (api) => {
-      const [flipper, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, false);
@@ -84,16 +84,16 @@
   });
 
   it('fails when called for non-contract address', async () => {
-    await usingApi(async (api) => {
-      const user = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const user = await findUnusedAddress(api, privateKeyWrapper);
 
       await enableContractSponsoringExpectFailure(alice, user.address, true);
     });
   });
 
   it('fails when called by non-owning user', async () => {
-    await usingApi(async (api) => {
-      const [flipper] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper] = await deployFlipper(api, privateKeyWrapper);
 
       await enableContractSponsoringExpectFailure(alice, flipper.address, true);
     });
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
--- a/tests/src/eth/allowlist.test.ts
+++ b/tests/src/eth/allowlist.test.ts
@@ -18,8 +18,8 @@
 import {contractHelpers, createEthAccountWithBalance, deployFlipper, itWeb3} from './util/helpers';
 
 describe('EVM allowlist', () => {
-  itWeb3('Contract allowlist can be toggled', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, owner);
 
     const helpers = contractHelpers(web3, owner);
@@ -36,10 +36,10 @@
     expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;
   });
 
-  itWeb3('Non-allowlisted user can\'t call contract with allowlist enabled', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Non-allowlisted user can\'t call contract with allowlist enabled', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, owner);
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const helpers = contractHelpers(web3, owner);
 
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -174,24 +174,7 @@
 	function finishMinting() external returns (bool);
 }
 
-// Selector: 780e9d63
-interface ERC721Enumerable is Dummy, ERC165 {
-	// Selector: tokenByIndex(uint256) 4f6ccce7
-	function tokenByIndex(uint256 index) external view returns (uint256);
-
-	// Not implemented
-	//
-	// Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
-	function tokenOfOwnerByIndex(address owner, uint256 index)
-		external
-		view
-		returns (uint256);
-
-	// Selector: totalSupply() 18160ddd
-	function totalSupply() external view returns (uint256);
-}
-
-// Selector: c894dc35
+// Selector: 6aea9834
 interface Collection is Dummy, ERC165 {
 	// Selector: setCollectionProperty(string,bytes) 2f073f66
 	function setCollectionProperty(string memory key, bytes memory value)
@@ -208,20 +191,62 @@
 		view
 		returns (bytes memory);
 
-	// Selector: ethSetSponsor(address) 8f9af356
-	function ethSetSponsor(address sponsor) external;
+	// Selector: setCollectionSponsor(address) 7623402e
+	function setCollectionSponsor(address sponsor) external;
 
-	// Selector: ethConfirmSponsorship() a8580d1a
-	function ethConfirmSponsorship() external;
+	// Selector: confirmCollectionSponsorship() 3c50e97a
+	function confirmCollectionSponsorship() external;
 
-	// Selector: setLimit(string,uint32) 68db30ca
-	function setLimit(string memory limit, uint32 value) external;
+	// Selector: setCollectionLimit(string,uint32) 6a3841db
+	function setCollectionLimit(string memory limit, uint32 value) external;
 
-	// Selector: setLimit(string,bool) ea67e4c2
-	function setLimit(string memory limit, bool value) external;
+	// Selector: setCollectionLimit(string,bool) 993b7fba
+	function setCollectionLimit(string memory limit, bool value) external;
 
 	// Selector: contractAddress() f6b4dfb4
 	function contractAddress() external view returns (address);
+
+	// Selector: addCollectionAdmin(address) 92e462c7
+	function addCollectionAdmin(address newAdmin) external view;
+
+	// Selector: removeCollectionAdmin(address) fafd7b42
+	function removeCollectionAdmin(address admin) external view;
+
+	// Selector: setCollectionNesting(bool) 112d4586
+	function setCollectionNesting(bool enable) external;
+
+	// Selector: setCollectionNesting(bool,address[]) 64872396
+	function setCollectionNesting(bool enable, address[] memory collections)
+		external;
+
+	// Selector: setCollectionAccess(uint8) 41835d4c
+	function setCollectionAccess(uint8 mode) external;
+
+	// Selector: addToCollectionAllowList(address) 67844fe6
+	function addToCollectionAllowList(address user) external view;
+
+	// Selector: removeFromCollectionAllowList(address) 85c51acb
+	function removeFromCollectionAllowList(address user) external view;
+
+	// Selector: setCollectionMintMode(bool) 00018e84
+	function setCollectionMintMode(bool mode) external;
+}
+
+// Selector: 780e9d63
+interface ERC721Enumerable is Dummy, ERC165 {
+	// Selector: tokenByIndex(uint256) 4f6ccce7
+	function tokenByIndex(uint256 index) external view returns (uint256);
+
+	// Not implemented
+	//
+	// Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
+	function tokenOfOwnerByIndex(address owner, uint256 index)
+		external
+		view
+		returns (uint256);
+
+	// Selector: totalSupply() 18160ddd
+	function totalSupply() external view returns (uint256);
 }
 
 // Selector: d74d154f
modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
--- a/tests/src/eth/base.test.ts
+++ b/tests/src/eth/base.test.ts
@@ -32,16 +32,16 @@
 import Web3 from 'web3';
 
 describe('Contract calls', () => {
-  itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => {
-    const deployer = await createEthAccountWithBalance(api, web3);
+  itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api, privateKeyWrapper}) => {
+    const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, deployer);
 
     const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer}));
     expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;
   });
 
-  itWeb3('Balance transfer fee is less than 0.2 UNQ', async ({web3, api}) => {
-    const userA = await createEthAccountWithBalance(api, web3);
+  itWeb3('Balance transfer fee is less than 0.2 UNQ', async ({web3, api, privateKeyWrapper}) => {
+    const userA = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const userB = createEthAccount(web3);
 
     const cost = await recordEthFee(api, userA, () => web3.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS}));
@@ -50,7 +50,7 @@
   });
 
   itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api, privateKeyWrapper}) => {
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const receiver = createEthAccount(web3);
 
     const alice = privateKeyWrapper('//Alice');
modifiedtests/src/eth/collectionProperties.test.tsdiffbeforeafterboth
--- a/tests/src/eth/collectionProperties.test.ts
+++ b/tests/src/eth/collectionProperties.test.ts
@@ -7,7 +7,7 @@
 describe('EVM collection properties', () => {
   itWeb3('Can be set', async({web3, api, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
 
     await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
@@ -22,7 +22,7 @@
   });
   itWeb3('Can be deleted', async({web3, api, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
 
     await executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collection, [{key: 'testKey', value: 'testValue'}]));
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/contractSponsoring.test.ts
+++ b/tests/src/eth/contractSponsoring.test.ts
@@ -31,6 +31,7 @@
   evmCollectionHelpers,
   getCollectionAddressFromResult,
   evmCollection,
+  ethBalanceViaSub,
 } from './util/helpers';
 import {
   addCollectionAdminExpectSuccess,
@@ -43,8 +44,8 @@
 import {evmToAddress} from '@polkadot/util-crypto';
 
 describe('Sponsoring EVM contracts', () => {
-  itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, owner);
     const helpers = contractHelpers(web3, owner);
     expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
@@ -52,9 +53,9 @@
     expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
   });
 
-  itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
-    const notOwner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, owner);
     const helpers = contractHelpers(web3, owner);
     expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
@@ -65,8 +66,8 @@
   itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
-    const caller = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const flipper = await deployFlipper(web3, owner);
 
@@ -93,7 +94,7 @@
   itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (allowlisted)', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const caller = createEthAccount(web3);
 
     const flipper = await deployFlipper(web3, owner);
@@ -123,7 +124,7 @@
   itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-allowlisted)', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const caller = createEthAccount(web3);
 
     const flipper = await deployFlipper(web3, owner);
@@ -151,8 +152,8 @@
   itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
-    const caller = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const originalCallerBalance = await web3.eth.getBalance(caller);
 
     const flipper = await deployFlipper(web3, owner);
@@ -180,8 +181,8 @@
   itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
-    const caller = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const originalCallerBalance = await web3.eth.getBalance(caller);
 
     const flipper = await deployFlipper(web3, owner);
@@ -213,119 +214,135 @@
   });
 
   // TODO: Find a way to calculate default rate limit
-  itWeb3('Default rate limit equals 7200', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, owner);
     const helpers = contractHelpers(web3, owner);
     expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');
   });
 
-  //TODO: CORE-302 add eth methods
-  itWeb3.skip('Sponsoring evm address from substrate collection', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Sponsoring collection from evm address via access list', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionHelpers = evmCollectionHelpers(web3, owner);
     let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();
     const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
-    const sponsor = await createEthAccountWithBalance(api, web3);
+    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
-    result = await collectionEvm.methods.ethSetSponsor(sponsor).send();
+    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
     let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
+    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;
     expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;
-    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
-    await expect(collectionEvm.methods.ethConfirmSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
+    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
+    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
 
-    const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
-    await sponsorCollection.methods.ethConfirmSponsorship().send();
+    await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
     collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isConfirmed).to.be.true;
-    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
+    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
 
     const user = createEthAccount(web3);
-    const userContract = evmCollection(web3, user, collectionIdAddress);
-    const nextTokenId = await userContract.methods.nextTokenId().call();
+    let nextTokenId = await collectionEvm.methods.nextTokenId().call();
+    expect(nextTokenId).to.be.equal('1');
 
+    const oldPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
+    expect(oldPermissions.mintMode).to.be.false;
+    expect(oldPermissions.access).to.be.equal('Normal');
+
+    //TODO: change value, when enum generated
+    await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
+    await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
+    await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
+
+    const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
+    expect(newPermissions.mintMode).to.be.true;
+    expect(newPermissions.access).to.be.equal('AllowList');
+
+    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);
+    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);
+
+    nextTokenId = await collectionEvm.methods.nextTokenId().call({from: user});
     expect(nextTokenId).to.be.equal('1');
-    await expect(userContract.methods.mintWithTokenURI(
+    result = await collectionEvm.methods.mintWithTokenURI(
       user,
       nextTokenId,
       'Test URI',
-    ).call()).to.be.rejectedWith('PublicMintingNotAllowed');
-    
-    // TODO: add this methods to eth
-    // {
-    //   const tx = api.tx.unique.setPublicAccessMode(collectionId, 'AllowList');
-    //   const events = await submitTransactionAsync(owner, tx);
-    //   const result = getCreateCollectionResult(events);
-    //   expect(result.success).to.be.true;
-    // }
-    // {
-    //   const tx = api.tx.unique.addToAllowList(collectionId, {Ethereum: userEth});
-    //   const events = await submitTransactionAsync(owner, tx);
-    //   const result = getCreateCollectionResult(events);
-    //   expect(result.success).to.be.true;
-    // }
-    // {
-    //   const tx = api.tx.unique.setMintPermission(collectionId, true);
-    //   const events = await submitTransactionAsync(owner, tx);
-    //   const result = getCreateCollectionResult(events);
-    //   expect(result.success).to.be.true;
-    // }
-
-    // const [alicesBalanceBefore] = await getBalance(api, [alicesPublicKey]);
-
-    {
-      const nextTokenId = await userContract.methods.nextTokenId().call();
-      expect(nextTokenId).to.be.equal('1');
-      const result = await userContract.methods.mintWithTokenURI(
-        user,
-        nextTokenId,
-        'Test URI',
-      ).send();
-      const events = normalizeEvents(result.events);
+    ).send({from: user});
+    const events = normalizeEvents(result.events);
+    events[0].address = events[0].address.toLocaleLowerCase();
 
-      expect(events).to.be.deep.equal([
-        {
-          collectionIdAddress,
-          event: 'Transfer',
-          args: {
-            from: '0x0000000000000000000000000000000000000000',
-            to: user,
-            tokenId: nextTokenId,
-          },
+    expect(events).to.be.deep.equal([
+      {
+        address: collectionIdAddress.toLocaleLowerCase(),
+        event: 'Transfer',
+        args: {
+          from: '0x0000000000000000000000000000000000000000',
+          to: user,
+          tokenId: nextTokenId,
         },
-      ]);
+      },
+    ]);
+
+    expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
 
-      expect(await userContract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
-    }
+    const ownerBalanceAfter = await ethBalanceViaSub(api, owner);
+    expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+    const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);
+    expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
   });
 
-  //TODO: CORE-302 add eth methods
-  itWeb3.skip('Check that transaction via EVM spend money from substrate address', async ({api, web3, privateKeyWrapper}) => {
-    const owner = privateKeyWrapper('//Alice');
-    const user = privateKeyWrapper(`//User/${Date.now()}`);
-    const userEth = subToEth(user.address);
-    const collectionId = await createCollectionExpectSuccess();
-    await addCollectionAdminExpectSuccess(owner, collectionId, {Ethereum: userEth});
-    await transferBalanceTo(api, owner, user.address);
+  itWeb3('Check that transaction via EVM spend money from sponsor address', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const collectionHelpers = evmCollectionHelpers(web3, owner);
+    let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();
+    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
+    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
+    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();
+    let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
+    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;
+    expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;
+    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
+    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
+    const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
+    await sponsorCollection.methods.confirmCollectionSponsorship().send();
+    collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
+    expect(collectionSub.sponsorship.isConfirmed).to.be.true;
+    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
+
+    const user = createEthAccount(web3);
+    await collectionEvm.methods.addCollectionAdmin(user).send();
+    
+    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);
+    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);
+  
+    const userCollectionEvm = evmCollection(web3, user, collectionIdAddress);
+    const nextTokenId = await userCollectionEvm.methods.nextTokenId().call();
+    expect(nextTokenId).to.be.equal('1');
+    result = await userCollectionEvm.methods.mintWithTokenURI(
+      user,
+      nextTokenId,
+      'Test URI',
+    ).send();
 
+    const events = normalizeEvents(result.events);
     const address = collectionIdToAddress(collectionId);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: userEth, ...GAS_ARGS});
 
-    const [userBalanceBefore] = await getBalance(api, [user.address]);
-
-    {
-      const nextTokenId = await contract.methods.nextTokenId().call();
-      expect(nextTokenId).to.be.equal('1');
-      await executeEthTxOnSub(web3, api, user, contract, m => m.mintWithTokenURI(
-        userEth,
-        nextTokenId,
-        'Test URI',
-      ));
-
-      expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
-    }
-
-    const [userBalanceAfter] = await getBalance(api, [user.address]);
-    expect(userBalanceAfter < userBalanceBefore).to.be.true;
+    expect(events).to.be.deep.equal([
+      {
+        address,
+        event: 'Transfer',
+        args: {
+          from: '0x0000000000000000000000000000000000000000',
+          to: user,
+          tokenId: nextTokenId,
+        },
+      },
+    ]);
+    expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+  
+    const ownerBalanceAfter = await ethBalanceViaSub(api, owner);
+    expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+    const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);
+    expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
   });
 });
modifiedtests/src/eth/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createCollection.test.ts
+++ b/tests/src/eth/createCollection.test.ts
@@ -28,67 +28,68 @@
 } from './util/helpers';
 
 describe('Create collection from EVM', () => {
-  itWeb3('Create collection', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
-    const helper = evmCollectionHelpers(web3, owner);
-    const collectionName = 'CollectionEVM';
-    const description = 'Some description';
-    const tokenPrefix = 'token prefix';
+  // itWeb3('Create collection', async ({api, web3, privateKeyWrapper}) => {
+  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  //   const collectionHelper = evmCollectionHelpers(web3, owner);
+  //   const collectionName = 'CollectionEVM';
+  //   const description = 'Some description';
+  //   const tokenPrefix = 'token prefix';
   
-    const collectionCountBefore = await getCreatedCollectionCount(api);
-    const result = await helper.methods
-      .createNonfungibleCollection(collectionName, description, tokenPrefix)
-      .send();
-    const collectionCountAfter = await getCreatedCollectionCount(api);
+  //   const collectionCountBefore = await getCreatedCollectionCount(api);
+  //   const result = await collectionHelper.methods
+  //     .createNonfungibleCollection(collectionName, description, tokenPrefix)
+  //     .send();
+  //   const collectionCountAfter = await getCreatedCollectionCount(api);
   
-    const {collectionId, collection} = await getCollectionAddressFromResult(api, result);
-    expect(collectionCountAfter - collectionCountBefore).to.be.eq(1);
-    expect(collectionId).to.be.eq(collectionCountAfter);
-    expect(collection.name.map(v => String.fromCharCode(v.toNumber())).join('')).to.be.eq(collectionName);
-    expect(collection.description.map(v => String.fromCharCode(v.toNumber())).join('')).to.be.eq(description);
-    expect(collection.tokenPrefix.toHuman()).to.be.eq(tokenPrefix);
-  });
+  //   const {collectionId, collection} = await getCollectionAddressFromResult(api, result);
+  //   expect(collectionCountAfter - collectionCountBefore).to.be.eq(1);
+  //   expect(collectionId).to.be.eq(collectionCountAfter);
+  //   expect(collection.name.map(v => String.fromCharCode(v.toNumber())).join('')).to.be.eq(collectionName);
+  //   expect(collection.description.map(v => String.fromCharCode(v.toNumber())).join('')).to.be.eq(description);
+  //   expect(collection.tokenPrefix.toHuman()).to.be.eq(tokenPrefix);
+  // });
 
-  itWeb3('Check collection address exist', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
-    const collectionHelpers = evmCollectionHelpers(web3, owner);
+  // itWeb3('Check collection address exist', async ({api, web3, privateKeyWrapper}) => {
+  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  //   const collectionHelpers = evmCollectionHelpers(web3, owner);
   
-    const expectedCollectionId = await getCreatedCollectionCount(api) + 1;
-    const expectedCollectionAddress = collectionIdToAddress(expectedCollectionId);
-    expect(await collectionHelpers.methods
-      .isCollectionExist(expectedCollectionAddress)
-      .call()).to.be.false;
+  //   const expectedCollectionId = await getCreatedCollectionCount(api) + 1;
+  //   const expectedCollectionAddress = collectionIdToAddress(expectedCollectionId);
+  //   expect(await collectionHelpers.methods
+  //     .isCollectionExist(expectedCollectionAddress)
+  //     .call()).to.be.false;
 
-    await collectionHelpers.methods
-      .createNonfungibleCollection('A', 'A', 'A')
-      .send();
+  //   await collectionHelpers.methods
+  //     .createNonfungibleCollection('A', 'A', 'A')
+  //     .send();
     
-    expect(await collectionHelpers.methods
-      .isCollectionExist(expectedCollectionAddress)
-      .call()).to.be.true;
-  });
+  //   expect(await collectionHelpers.methods
+  //     .isCollectionExist(expectedCollectionAddress)
+  //     .call()).to.be.true;
+  // });
   
-  itWeb3('Set sponsorship', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Set sponsorship', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionHelpers = evmCollectionHelpers(web3, owner);
     let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();
     const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
-    const sponsor = await createEthAccountWithBalance(api, web3);
+    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
-    result = await collectionEvm.methods.ethSetSponsor(sponsor).send();
+    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();
     let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;
-    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
-    await expect(collectionEvm.methods.ethConfirmSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
+    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;
+    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
+    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
     const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
-    await sponsorCollection.methods.ethConfirmSponsorship().send();
+    await sponsorCollection.methods.confirmCollectionSponsorship().send();
     collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isConfirmed).to.be.true;
-    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
+    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
   });
 
-  itWeb3('Set limits', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Set limits', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionHelpers = evmCollectionHelpers(web3, owner);
     const result = await collectionHelpers.methods.createNonfungibleCollection('Const collection', '5', '5').send();
     const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
@@ -105,15 +106,15 @@
     };
 
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
-    await collectionEvm.methods['setLimit(string,uint32)']('accountTokenOwnershipLimit', limits.accountTokenOwnershipLimit).send();
-    await collectionEvm.methods['setLimit(string,uint32)']('sponsoredDataSize', limits.sponsoredDataSize).send();
-    await collectionEvm.methods['setLimit(string,uint32)']('sponsoredDataRateLimit', limits.sponsoredDataRateLimit).send();
-    await collectionEvm.methods['setLimit(string,uint32)']('tokenLimit', limits.tokenLimit).send();
-    await collectionEvm.methods['setLimit(string,uint32)']('sponsorTransferTimeout', limits.sponsorTransferTimeout).send();
-    await collectionEvm.methods['setLimit(string,uint32)']('sponsorApproveTimeout', limits.sponsorApproveTimeout).send();
-    await collectionEvm.methods['setLimit(string,bool)']('ownerCanTransfer', limits.ownerCanTransfer).send();
-    await collectionEvm.methods['setLimit(string,bool)']('ownerCanDestroy', limits.ownerCanDestroy).send();
-    await collectionEvm.methods['setLimit(string,bool)']('transfersEnabled', limits.transfersEnabled).send();
+    await collectionEvm.methods['setCollectionLimit(string,uint32)']('accountTokenOwnershipLimit', limits.accountTokenOwnershipLimit).send();
+    await collectionEvm.methods['setCollectionLimit(string,uint32)']('sponsoredDataSize', limits.sponsoredDataSize).send();
+    await collectionEvm.methods['setCollectionLimit(string,uint32)']('sponsoredDataRateLimit', limits.sponsoredDataRateLimit).send();
+    await collectionEvm.methods['setCollectionLimit(string,uint32)']('tokenLimit', limits.tokenLimit).send();
+    await collectionEvm.methods['setCollectionLimit(string,uint32)']('sponsorTransferTimeout', limits.sponsorTransferTimeout).send();
+    await collectionEvm.methods['setCollectionLimit(string,uint32)']('sponsorApproveTimeout', limits.sponsorApproveTimeout).send();
+    await collectionEvm.methods['setCollectionLimit(string,bool)']('ownerCanTransfer', limits.ownerCanTransfer).send();
+    await collectionEvm.methods['setCollectionLimit(string,bool)']('ownerCanDestroy', limits.ownerCanDestroy).send();
+    await collectionEvm.methods['setCollectionLimit(string,bool)']('transfersEnabled', limits.transfersEnabled).send();
     
     const collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.eq(limits.accountTokenOwnershipLimit);
@@ -127,8 +128,8 @@
     expect(collectionSub.limits.transfersEnabled.toHuman()).to.be.eq(limits.transfersEnabled);
   });
 
-  itWeb3('Collection address exist', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Collection address exist', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';
     const collectionHelpers = evmCollectionHelpers(web3, owner);
     expect(await collectionHelpers.methods
@@ -144,8 +145,8 @@
 });
 
 describe('(!negative tests!) Create collection from EVM', () => {
-  itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const helper = evmCollectionHelpers(web3, owner);
     {
       const MAX_NAME_LENGHT = 64;
@@ -190,8 +191,8 @@
       .call()).to.be.rejectedWith('NotSufficientFounds');
   });
 
-  itWeb3('(!negative test!) Check owner', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('(!negative test!) Check owner', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const notOwner = await createEthAccount(web3);
     const collectionHelpers = evmCollectionHelpers(web3, owner);
     const result = await collectionHelpers.methods.createNonfungibleCollection('A', 'A', 'A').send();
@@ -199,31 +200,31 @@
     const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress);
     const EXPECTED_ERROR = 'NoPermission';
     {
-      const sponsor = await createEthAccountWithBalance(api, web3);
+      const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
       await expect(contractEvmFromNotOwner.methods
-        .ethSetSponsor(sponsor)
+        .setCollectionSponsor(sponsor)
         .call()).to.be.rejectedWith(EXPECTED_ERROR);
       
       const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
       await expect(sponsorCollection.methods
-        .ethConfirmSponsorship()
+        .confirmCollectionSponsorship()
         .call()).to.be.rejectedWith('Caller is not set as sponsor');
     }
     {
       await expect(contractEvmFromNotOwner.methods
-        .setLimit('account_token_ownership_limit', '1000')
+        .setCollectionLimit('account_token_ownership_limit', '1000')
         .call()).to.be.rejectedWith(EXPECTED_ERROR);
     }
   });
 
-  itWeb3('(!negative test!) Set limits', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('(!negative test!) Set limits', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionHelpers = evmCollectionHelpers(web3, owner);
     const result = await collectionHelpers.methods.createNonfungibleCollection('Schema collection', 'A', 'A').send();
     const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
     await expect(collectionEvm.methods
-      .setLimit('badLimit', 'true')
+      .setCollectionLimit('badLimit', 'true')
       .call()).to.be.rejectedWith('Unknown boolean limit "badLimit"');
   });
 });
\ No newline at end of file
modifiedtests/src/eth/crossTransfer.test.tsdiffbeforeafterboth
--- a/tests/src/eth/crossTransfer.test.ts
+++ b/tests/src/eth/crossTransfer.test.ts
@@ -48,8 +48,8 @@
     });
     const alice = privateKeyWrapper('//Alice');
     const bob = privateKeyWrapper('//Bob');
-    const bobProxy = await createEthAccountWithBalance(api, web3);
-    const aliceProxy = await createEthAccountWithBalance(api, web3);
+    const bobProxy = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const aliceProxy = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, alice.address);
     await transferExpectSuccess(collection, 0, alice, {Ethereum: aliceProxy} , 200, 'Fungible');
@@ -85,8 +85,8 @@
     const alice = privateKeyWrapper('//Alice');
     const bob = privateKeyWrapper('//Bob');
     const charlie = privateKeyWrapper('//Charlie');
-    const bobProxy = await createEthAccountWithBalance(api, web3);
-    const aliceProxy = await createEthAccountWithBalance(api, web3);
+    const bobProxy = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const aliceProxy = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
     await transferExpectSuccess(collection, tokenId, alice, {Ethereum: aliceProxy} , 1, 'NFT');
     const address = collectionIdToAddress(collection);
modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -27,7 +27,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});
 
@@ -45,7 +45,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller});
 
@@ -65,7 +65,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
 
@@ -208,7 +208,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const spender = createEthAccount(web3);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
@@ -226,8 +226,8 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
-    const spender = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
 
@@ -246,7 +246,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const receiver = createEthAccount(web3);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
modifiedtests/src/eth/helpersSmoke.test.tsdiffbeforeafterboth
--- a/tests/src/eth/helpersSmoke.test.ts
+++ b/tests/src/eth/helpersSmoke.test.ts
@@ -18,16 +18,16 @@
 import {createEthAccountWithBalance, deployFlipper, itWeb3, contractHelpers} from './util/helpers';
 
 describe('Helpers sanity check', () => {
-  itWeb3('Contract owner is recorded', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Contract owner is recorded', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const flipper = await deployFlipper(web3, owner);
 
     expect(await contractHelpers(web3, owner).methods.contractOwner(flipper.options.address).call()).to.be.equal(owner);
   });
 
-  itWeb3('Flipper is working', async ({api, web3}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Flipper is working', async ({api, web3, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, owner);
 
     expect(await flipper.methods.getValue().call()).to.be.false;
modifiedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
--- a/tests/src/eth/marketplace/marketplace.test.ts
+++ b/tests/src/eth/marketplace/marketplace.test.ts
@@ -39,7 +39,7 @@
 describe('Matcher contract usage', () => {
   itWeb3('With UNQ', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
       from: matcherOwner,
       ...GAS_ARGS,
@@ -100,8 +100,8 @@
 
   itWeb3('With escrow', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const matcherOwner = await createEthAccountWithBalance(api, web3);
-    const escrow = await createEthAccountWithBalance(api, web3);
+    const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const escrow = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
       from: matcherOwner,
       ...GAS_ARGS,
@@ -171,7 +171,7 @@
 
   itWeb3('Sell tokens from substrate user via EVM contract', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
       from: matcherOwner,
       ...GAS_ARGS,
modifiedtests/src/eth/migration.test.tsdiffbeforeafterboth
--- a/tests/src/eth/migration.test.ts
+++ b/tests/src/eth/migration.test.ts
@@ -54,7 +54,7 @@
     ];
 
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.begin(ADDRESS) as any));
     await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.setData(ADDRESS, DATA as any) as any));
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -26,7 +26,7 @@
       mode: {type: 'NFT'},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
 
@@ -43,7 +43,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum:caller});
     await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
     await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
@@ -61,7 +61,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
 
     const address = collectionIdToAddress(collection);
@@ -73,8 +73,8 @@
 });
 
 describe('NFT: Plain calls', () => {
-  itWeb3('Can perform mint()', async ({web3, api}) => {
-    const owner = await createEthAccountWithBalance(api, web3);
+  itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const helper = evmCollectionHelpers(web3, owner);
     let result = await helper.methods.createNonfungibleCollection('Mint collection', '6', '6').send();
     const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
@@ -119,7 +119,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: caller});
     await submitTransactionAsync(alice, changeAdminTx);
     const receiver = createEthAccount(web3);
@@ -182,7 +182,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
 
@@ -341,7 +341,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const spender = createEthAccount(web3);
 
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
@@ -359,8 +359,8 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
-    const spender = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
 
@@ -379,7 +379,7 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const receiver = createEthAccount(web3);
 
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
@@ -541,12 +541,12 @@
 });
 
 describe('Common metadata', () => {
-  itWeb3('Returns collection name', async ({api, web3}) => {
+  itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {
     const collection = await createCollectionExpectSuccess({
       name: 'token name',
       mode: {type: 'NFT'},
     });
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const address = collectionIdToAddress(collection);
     const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
@@ -555,12 +555,12 @@
     expect(name).to.equal('token name');
   });
 
-  itWeb3('Returns symbol name', async ({api, web3}) => {
+  itWeb3('Returns symbol name', async ({api, web3, privateKeyWrapper}) => {
     const collection = await createCollectionExpectSuccess({
       tokenPrefix: 'TOK',
       mode: {type: 'NFT'},
     });
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const address = collectionIdToAddress(collection);
     const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -82,6 +82,24 @@
   },
   {
     "inputs": [
+      { "internalType": "address", "name": "newAdmin", "type": "address" }
+    ],
+    "name": "addCollectionAdmin",
+    "outputs": [],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "user", "type": "address" }
+    ],
+    "name": "addToCollectionAllowList",
+    "outputs": [],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
       { "internalType": "address", "name": "approved", "type": "address" },
       { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
     ],
@@ -127,6 +145,13 @@
   },
   {
     "inputs": [],
+    "name": "confirmCollectionSponsorship",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "contractAddress",
     "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
     "stateMutability": "view",
@@ -151,22 +176,6 @@
   },
   {
     "inputs": [],
-    "name": "ethConfirmSponsorship",
-    "outputs": [],
-    "stateMutability": "nonpayable",
-    "type": "function"
-  },
-  {
-    "inputs": [
-      { "internalType": "address", "name": "sponsor", "type": "address" }
-    ],
-    "name": "ethSetSponsor",
-    "outputs": [],
-    "stateMutability": "nonpayable",
-    "type": "function"
-  },
-  {
-    "inputs": [],
     "name": "finishMinting",
     "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
     "stateMutability": "nonpayable",
@@ -282,6 +291,24 @@
   },
   {
     "inputs": [
+      { "internalType": "address", "name": "admin", "type": "address" }
+    ],
+    "name": "removeCollectionAdmin",
+    "outputs": [],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "user", "type": "address" }
+    ],
+    "name": "removeFromCollectionAllowList",
+    "outputs": [],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
       { "internalType": "address", "name": "from", "type": "address" },
       { "internalType": "address", "name": "to", "type": "address" },
       { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
@@ -314,11 +341,8 @@
     "type": "function"
   },
   {
-    "inputs": [
-      { "internalType": "string", "name": "key", "type": "string" },
-      { "internalType": "bytes", "name": "value", "type": "bytes" }
-    ],
-    "name": "setCollectionProperty",
+    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
+    "name": "setCollectionAccess",
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
@@ -328,7 +352,7 @@
       { "internalType": "string", "name": "limit", "type": "string" },
       { "internalType": "uint32", "name": "value", "type": "uint32" }
     ],
-    "name": "setLimit",
+    "name": "setCollectionLimit",
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
@@ -338,7 +362,54 @@
       { "internalType": "string", "name": "limit", "type": "string" },
       { "internalType": "bool", "name": "value", "type": "bool" }
     ],
-    "name": "setLimit",
+    "name": "setCollectionLimit",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],
+    "name": "setCollectionMintMode",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],
+    "name": "setCollectionNesting",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "bool", "name": "enable", "type": "bool" },
+      {
+        "internalType": "address[]",
+        "name": "collections",
+        "type": "address[]"
+      }
+    ],
+    "name": "setCollectionNesting",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "string", "name": "key", "type": "string" },
+      { "internalType": "bytes", "name": "value", "type": "bytes" }
+    ],
+    "name": "setCollectionProperty",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "sponsor", "type": "address" }
+    ],
+    "name": "setCollectionSponsor",
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
--- a/tests/src/eth/payable.test.ts
+++ b/tests/src/eth/payable.test.ts
@@ -22,8 +22,8 @@
 import {getBalanceSingle, transferBalanceExpectSuccess} from '../substrate/get-balance';
 
 describe('EVM payable contracts', () => {
-  itWeb3('Evm contract can receive wei from eth account', async ({api, web3}) => {
-    const deployer = await createEthAccountWithBalance(api, web3);
+  itWeb3('Evm contract can receive wei from eth account', async ({api, web3, privateKeyWrapper}) => {
+    const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const contract = await deployCollector(web3, deployer);
 
     await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: '10000', ...GAS_ARGS});
@@ -32,7 +32,7 @@
   });
 
   itWeb3('Evm contract can receive wei from substrate account', async ({api, web3, privateKeyWrapper}) => {
-    const deployer = await createEthAccountWithBalance(api, web3);
+    const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const contract = await deployCollector(web3, deployer);
     const alice = privateKeyWrapper('//Alice');
 
@@ -62,7 +62,7 @@
 
   // We can't handle sending balance to backing storage of evm balance, because evmToAddress operation is irreversible
   itWeb3('Wei sent directly to backing storage of evm contract balance is unaccounted', async({api, web3, privateKeyWrapper}) => {
-    const deployer = await createEthAccountWithBalance(api, web3);
+    const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const contract = await deployCollector(web3, deployer);
     const alice = privateKeyWrapper('//Alice');
 
@@ -75,7 +75,7 @@
     const FEE_BALANCE = 1000n * UNIQUE;
     const CONTRACT_BALANCE = 1n * UNIQUE;
 
-    const deployer = await createEthAccountWithBalance(api, web3);
+    const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const contract = await deployCollector(web3, deployer);
     const alice = privateKeyWrapper('//Alice');
 
modifiedtests/src/eth/proxy/fungibleProxy.test.tsdiffbeforeafterboth
--- a/tests/src/eth/proxy/fungibleProxy.test.ts
+++ b/tests/src/eth/proxy/fungibleProxy.test.ts
@@ -21,10 +21,11 @@
 import {ApiPromise} from '@polkadot/api';
 import Web3 from 'web3';
 import {readFile} from 'fs/promises';
+import {IKeyringPair} from '@polkadot/types/types';
 
-async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {
+async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any, privateKeyWrapper: (account: string) => IKeyringPair) {
   // Proxy owner has no special privilegies, we don't need to reuse them
-  const owner = await createEthAccountWithBalance(api, web3);
+  const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
   const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, {
     from: owner,
     ...GAS_ARGS,
@@ -40,12 +41,12 @@
       mode: {type: 'Fungible', decimalPoints: 0},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const totalSupply = await contract.methods.totalSupply().call();
 
     expect(totalSupply).to.equal('200');
@@ -57,12 +58,12 @@
       mode: {type: 'Fungible', decimalPoints: 0},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller});
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const balance = await contract.methods.balanceOf(caller).call();
 
     expect(balance).to.equal('200');
@@ -76,11 +77,11 @@
       mode: {type: 'Fungible', decimalPoints: 0},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const spender = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: contract.options.address});
 
     {
@@ -112,8 +113,8 @@
       mode: {type: 'Fungible', decimalPoints: 0},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
-    const owner = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
 
@@ -121,7 +122,7 @@
 
     const address = collectionIdToAddress(collection);
     const evmCollection = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
-    const contract = await proxyWrap(api, web3, evmCollection);
+    const contract = await proxyWrap(api, web3, evmCollection, privateKeyWrapper);
 
     await evmCollection.methods.approve(contract.options.address, 100).send({from: owner});
 
@@ -167,11 +168,11 @@
       mode: {type: 'Fungible', decimalPoints: 0},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
-    const receiver = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: contract.options.address});
 
     {
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
--- a/tests/src/eth/proxy/nonFungibleProxy.test.ts
+++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts
@@ -15,17 +15,18 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {createCollectionExpectSuccess, createItemExpectSuccess} from '../../util/helpers';
-import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents} from '../util/helpers';
+import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents} from '../util/helpers';
 import nonFungibleAbi from '../nonFungibleAbi.json';
 import {expect} from 'chai';
 import {submitTransactionAsync} from '../../substrate/substrate-api';
 import Web3 from 'web3';
 import {readFile} from 'fs/promises';
 import {ApiPromise} from '@polkadot/api';
+import {IKeyringPair} from '@polkadot/types/types';
 
-async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {
+async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any, privateKeyWrapper: (account: string) => IKeyringPair) {
   // Proxy owner has no special privilegies, we don't need to reuse them
-  const owner = await createEthAccountWithBalance(api, web3);
+  const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
   const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {
     from: owner,
     ...GAS_ARGS,
@@ -40,12 +41,12 @@
       mode: {type: 'NFT'},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const totalSupply = await contract.methods.totalSupply().call();
 
     expect(totalSupply).to.equal('1');
@@ -57,13 +58,13 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
     await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
     await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const balance = await contract.methods.balanceOf(caller).call();
 
     expect(balance).to.equal('3');
@@ -75,11 +76,11 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const owner = await contract.methods.ownerOf(tokenId).call();
 
     expect(owner).to.equal(caller);
@@ -87,20 +88,19 @@
 });
 
 describe('NFT (Via EVM proxy): Plain calls', () => {
-  //TODO: CORE-302 add eth methods
-  itWeb3.skip('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
-    const collection = await createCollectionExpectSuccess({
-      mode: {type: 'NFT'},
-    });
-    const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+  itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const collectionHelper = evmCollectionHelpers(web3, owner);
+    const result = await collectionHelper.methods
+      .createNonfungibleCollection('A', 'A', 'A')
+      .send();
+    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const receiver = createEthAccount(web3);
-
-    const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
-
-    const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});
-    await submitTransactionAsync(alice, changeAdminTx);
+    const collectionEvmOwned = evmCollection(web3, owner, collectionIdAddress);
+    const collectionEvm = evmCollection(web3, caller, collectionIdAddress);
+    const contract = await proxyWrap(api, web3, collectionEvm, privateKeyWrapper);
+    await collectionEvmOwned.methods.addCollectionAdmin(contract.options.address).send();
 
     {
       const nextTokenId = await contract.methods.nextTokenId().call();
@@ -111,10 +111,11 @@
         'Test URI',
       ).send({from: caller});
       const events = normalizeEvents(result.events);
+      events[0].address = events[0].address.toLocaleLowerCase();
 
       expect(events).to.be.deep.equal([
         {
-          address,
+          address: collectionIdAddress.toLocaleLowerCase(),
           event: 'Transfer',
           args: {
             from: '0x0000000000000000000000000000000000000000',
@@ -135,11 +136,11 @@
     });
     const alice = privateKeyWrapper('//Alice');
 
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const receiver = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});
     await submitTransactionAsync(alice, changeAdminTx);
 
@@ -197,10 +198,10 @@
       mode: {type: 'NFT'},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
 
     const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});
@@ -229,11 +230,11 @@
       mode: {type: 'NFT'},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const spender = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address), privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
 
     {
@@ -259,14 +260,14 @@
       mode: {type: 'NFT'},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
-    const owner = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
 
     const receiver = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
     const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
-    const contract = await proxyWrap(api, web3, evmCollection);
+    const contract = await proxyWrap(api, web3, evmCollection, privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
 
     await evmCollection.methods.approve(contract.options.address, tokenId).send({from: owner});
@@ -303,11 +304,11 @@
       mode: {type: 'NFT'},
     });
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const receiver = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
 
     {
modifiedtests/src/eth/scheduling.test.tsdiffbeforeafterboth
--- a/tests/src/eth/scheduling.test.ts
+++ b/tests/src/eth/scheduling.test.ts
@@ -17,14 +17,13 @@
 import {expect} from 'chai';
 import {createEthAccountWithBalance, deployFlipper, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from './util/helpers';
 import {scheduleExpectSuccess, waitNewBlocks} from '../util/helpers';
-import privateKey from '../substrate/privateKey';
 
 describe('Scheduing EVM smart contracts', () => {
-  itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3}) => {
-    const deployer = await createEthAccountWithBalance(api, web3);
+  itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3, privateKeyWrapper}) => {
+    const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, deployer);
     const initialValue = await flipper.methods.getValue().call();
-    const alice = privateKey('//Alice');
+    const alice = privateKeyWrapper('//Alice');
     await transferBalanceToEth(api, alice, subToEth(alice.address));
 
     {
modifiedtests/src/eth/sponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/sponsoring.test.ts
+++ b/tests/src/eth/sponsoring.test.ts
@@ -21,7 +21,7 @@
   itWeb3('Fee is deducted from contract if sponsoring is enabled', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const caller = createEthAccount(web3);
     const originalCallerBalance = await web3.eth.getBalance(caller);
     expect(originalCallerBalance).to.be.equal('0');
@@ -52,8 +52,8 @@
   itWeb3('...but this doesn\'t applies to payable value', async ({api, web3, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
 
-    const owner = await createEthAccountWithBalance(api, web3);
-    const caller = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const originalCallerBalance = await web3.eth.getBalance(caller);
     expect(originalCallerBalance).to.be.not.equal('0');
 
modifiedtests/src/eth/tokenProperties.test.tsdiffbeforeafterboth
--- a/tests/src/eth/tokenProperties.test.ts
+++ b/tests/src/eth/tokenProperties.test.ts
@@ -7,7 +7,7 @@
 describe('EVM token properties', () => {
   itWeb3('Can be reconfigured', async({web3, api, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {
       const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
@@ -25,7 +25,7 @@
   });
   itWeb3('Can be set', async({web3, api, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
     const token = await createItemExpectSuccess(alice, collection, 'NFT');
 
@@ -48,7 +48,7 @@
   });
   itWeb3('Can be deleted', async({web3, api, privateKeyWrapper}) => {
     const alice = privateKeyWrapper('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
+    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
     const token = await createItemExpectSuccess(alice, collection, 'NFT');
 
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -112,8 +112,8 @@
   return account.address;
 }
 
-export async function createEthAccountWithBalance(api: ApiPromise, web3: Web3) {
-  const alice = privateKey('//Alice');
+export async function createEthAccountWithBalance(api: ApiPromise, web3: Web3, privateKeyWrapper: (account: string) => IKeyringPair) {
+  const alice = privateKeyWrapper('//Alice');
   const account = createEthAccount(web3);
   await transferBalanceToEth(api, alice, account);
 
modifiedtests/src/interfaces/augment-api-consts.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-consts.ts
+++ b/tests/src/interfaces/augment-api-consts.ts
@@ -46,6 +46,22 @@
        **/
       [key: string]: Codec;
     };
+    scheduler: {
+      /**
+       * The maximum weight that may be scheduled per block for any dispatchables of less
+       * priority than `schedule::HARD_DEADLINE`.
+       **/
+      maximumWeight: u64 & AugmentedConst<ApiType>;
+      /**
+       * The maximum number of scheduled calls in the queue for a single block.
+       * Not strictly enforced, but used for weight estimation.
+       **/
+      maxScheduledPerBlock: u32 & AugmentedConst<ApiType>;
+      /**
+       * Generic const
+       **/
+      [key: string]: Codec;
+    };
     system: {
       /**
        * Maximum number of block number to block hash mappings to keep (oldest pruned first).
modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -81,6 +81,14 @@
        **/
       CollectionFieldSizeExceeded: AugmentedError<ApiType>;
       /**
+       * Tried to access an external collection with an internal API
+       **/
+      CollectionIsExternal: AugmentedError<ApiType>;
+      /**
+       * Tried to access an internal collection with an external API
+       **/
+      CollectionIsInternal: AugmentedError<ApiType>;
+      /**
        * Collection limit bounds per collection exceeded
        **/
       CollectionLimitBoundsExceeded: AugmentedError<ApiType>;
@@ -437,6 +445,61 @@
        **/
       [key: string]: AugmentedError<ApiType>;
     };
+    rmrkCore: {
+      CannotAcceptNonOwnedNft: AugmentedError<ApiType>;
+      CannotRejectNonOwnedNft: AugmentedError<ApiType>;
+      CannotSendToDescendentOrSelf: AugmentedError<ApiType>;
+      CollectionFullOrLocked: AugmentedError<ApiType>;
+      CollectionNotEmpty: AugmentedError<ApiType>;
+      CollectionUnknown: AugmentedError<ApiType>;
+      CorruptedCollectionType: AugmentedError<ApiType>;
+      NftTypeEncodeError: AugmentedError<ApiType>;
+      NoAvailableCollectionId: AugmentedError<ApiType>;
+      NoAvailableNftId: AugmentedError<ApiType>;
+      NonTransferable: AugmentedError<ApiType>;
+      NoPermission: AugmentedError<ApiType>;
+      ResourceDoesntExist: AugmentedError<ApiType>;
+      ResourceNotPending: AugmentedError<ApiType>;
+      RmrkPropertyKeyIsTooLong: AugmentedError<ApiType>;
+      RmrkPropertyValueIsTooLong: AugmentedError<ApiType>;
+      /**
+       * Generic error
+       **/
+      [key: string]: AugmentedError<ApiType>;
+    };
+    rmrkEquip: {
+      BaseDoesntExist: AugmentedError<ApiType>;
+      NeedsDefaultThemeFirst: AugmentedError<ApiType>;
+      NoAvailableBaseId: AugmentedError<ApiType>;
+      NoAvailablePartId: AugmentedError<ApiType>;
+      PermissionError: AugmentedError<ApiType>;
+      /**
+       * Generic error
+       **/
+      [key: string]: AugmentedError<ApiType>;
+    };
+    scheduler: {
+      /**
+       * Failed to schedule a call
+       **/
+      FailedToSchedule: AugmentedError<ApiType>;
+      /**
+       * Cannot find the scheduled call.
+       **/
+      NotFound: AugmentedError<ApiType>;
+      /**
+       * Reschedule failed because it does not change scheduled time.
+       **/
+      RescheduleNoChange: AugmentedError<ApiType>;
+      /**
+       * Given target block number is in the past.
+       **/
+      TargetBlockNumberInPast: AugmentedError<ApiType>;
+      /**
+       * Generic error
+       **/
+      [key: string]: AugmentedError<ApiType>;
+    };
     structure: {
       /**
        * While searched for owner, encountered depth limit
@@ -509,6 +572,10 @@
        **/
       InvalidIndex: AugmentedError<ApiType>;
       /**
+       * Proposal has not been approved.
+       **/
+      ProposalNotApproved: AugmentedError<ApiType>;
+      /**
        * Too many approvals in the queue.
        **/
       TooManyApprovals: AugmentedError<ApiType>;
modifiedtests/src/interfaces/augment-api-events.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-events.ts
+++ b/tests/src/interfaces/augment-api-events.ts
@@ -2,9 +2,10 @@
 /* eslint-disable */
 
 import type { ApiTypes } from '@polkadot/api-base/types';
-import type { Bytes, Null, Option, Result, U256, U8aFixed, u128, u32, u64, u8 } from '@polkadot/types-codec';
+import type { Bytes, Null, Option, Result, U256, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';
+import type { ITuple } from '@polkadot/types-codec/types';
 import type { AccountId32, H160, H256 } from '@polkadot/types/interfaces/runtime';
-import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchInfo, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, SpRuntimeDispatchError, XcmV1MultiLocation, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';
+import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportScheduleLookupError, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchInfo, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiLocation, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';
 
 declare module '@polkadot/api-base/types/events' {
   export interface AugmentedEvents<ApiType extends ApiTypes> {
@@ -396,6 +397,56 @@
        **/
       [key: string]: AugmentedEvent<ApiType>;
     };
+    rmrkCore: {
+      CollectionCreated: AugmentedEvent<ApiType, [AccountId32, u32]>;
+      CollectionDestroyed: AugmentedEvent<ApiType, [AccountId32, u32]>;
+      CollectionLocked: AugmentedEvent<ApiType, [AccountId32, u32]>;
+      IssuerChanged: AugmentedEvent<ApiType, [AccountId32, AccountId32, u32]>;
+      NFTAccepted: AugmentedEvent<ApiType, [AccountId32, RmrkTraitsNftAccountIdOrCollectionNftTuple, u32, u32]>;
+      NFTBurned: AugmentedEvent<ApiType, [AccountId32, u32]>;
+      NftMinted: AugmentedEvent<ApiType, [AccountId32, u32, u32]>;
+      NFTRejected: AugmentedEvent<ApiType, [AccountId32, u32, u32]>;
+      NFTSent: AugmentedEvent<ApiType, [AccountId32, RmrkTraitsNftAccountIdOrCollectionNftTuple, u32, u32, bool]>;
+      PrioritySet: AugmentedEvent<ApiType, [u32, u32]>;
+      PropertySet: AugmentedEvent<ApiType, [u32, Option<u32>, Bytes, Bytes]>;
+      ResourceAccepted: AugmentedEvent<ApiType, [u32, u32]>;
+      ResourceAdded: AugmentedEvent<ApiType, [u32, u32]>;
+      ResourceRemoval: AugmentedEvent<ApiType, [u32, u32]>;
+      ResourceRemovalAccepted: AugmentedEvent<ApiType, [u32, u32]>;
+      /**
+       * Generic event
+       **/
+      [key: string]: AugmentedEvent<ApiType>;
+    };
+    rmrkEquip: {
+      BaseCreated: AugmentedEvent<ApiType, [AccountId32, u32]>;
+      /**
+       * Generic event
+       **/
+      [key: string]: AugmentedEvent<ApiType>;
+    };
+    scheduler: {
+      /**
+       * The call for the provided hash was not found so the task has been aborted.
+       **/
+      CallLookupFailed: AugmentedEvent<ApiType, [ITuple<[u32, u32]>, Option<U8aFixed>, FrameSupportScheduleLookupError]>;
+      /**
+       * Canceled some task.
+       **/
+      Canceled: AugmentedEvent<ApiType, [u32, u32]>;
+      /**
+       * Dispatched some task.
+       **/
+      Dispatched: AugmentedEvent<ApiType, [ITuple<[u32, u32]>, Option<U8aFixed>, Result<Null, SpRuntimeDispatchError>]>;
+      /**
+       * Scheduled some task.
+       **/
+      Scheduled: AugmentedEvent<ApiType, [u32, u32]>;
+      /**
+       * Generic event
+       **/
+      [key: string]: AugmentedEvent<ApiType>;
+    };
     structure: {
       /**
        * Executed call on behalf of token
modifiedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -2,10 +2,10 @@
 /* eslint-disable */
 
 import type { ApiTypes } from '@polkadot/api-base/types';
-import type { BTreeMap, Bytes, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types-codec';
+import type { BTreeMap, Bytes, Option, U256, U8aFixed, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types-codec';
 import type { AnyNumber, ITuple } from '@polkadot/types-codec/types';
 import type { AccountId32, H160, H256 } from '@polkadot/types/interfaces/runtime';
-import type { CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueQueueConfigData, EthereumBlock, EthereumLog, EthereumReceiptReceiptV3, EthereumTransactionTransactionV2, FpRpcTransactionStatus, FrameSupportWeightsPerDispatchClassU64, FrameSystemAccountInfo, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReleases, PalletBalancesReserveData, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmContractHelpersSponsoringModeT, PalletNonfungibleItemData, PalletRefungibleItemData, PalletTransactionPaymentReleases, PalletTreasuryProposal, PhantomTypeUpDataStructs, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, SpRuntimeDigest, SpTrieStorageProof, UpDataStructsCollection, UpDataStructsCollectionStats, UpDataStructsProperties, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsPropertyPermission, UpDataStructsTokenChild } from '@polkadot/types/lookup';
+import type { CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueQueueConfigData, EthereumBlock, EthereumLog, EthereumReceiptReceiptV3, EthereumTransactionTransactionV2, FpRpcTransactionStatus, FrameSupportWeightsPerDispatchClassU64, FrameSystemAccountInfo, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReleases, PalletBalancesReserveData, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmContractHelpersSponsoringModeT, PalletNonfungibleItemData, PalletRefungibleItemData, PalletTransactionPaymentReleases, PalletTreasuryProposal, PalletUnqSchedulerScheduledV3, PhantomTypeUpDataStructs, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, SpRuntimeDigest, SpTrieStorageProof, UpDataStructsCollection, UpDataStructsCollectionStats, UpDataStructsProperties, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsPropertyPermission, UpDataStructsTokenChild } from '@polkadot/types/lookup';
 import type { Observable } from '@polkadot/types/types';
 
 declare module '@polkadot/api-base/types/storage' {
@@ -415,6 +415,37 @@
        **/
       [key: string]: QueryableStorageEntry<ApiType>;
     };
+    rmrkCore: {
+      collectionIndex: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;
+      rmrkInernalCollectionId: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
+      uniqueCollectionId: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
+      /**
+       * Generic query
+       **/
+      [key: string]: QueryableStorageEntry<ApiType>;
+    };
+    rmrkEquip: {
+      baseHasDefaultTheme: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<bool>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
+      inernalPartId: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<u32>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
+      /**
+       * Generic query
+       **/
+      [key: string]: QueryableStorageEntry<ApiType>;
+    };
+    scheduler: {
+      /**
+       * Items to be executed, indexed by the block number that they should be executed on.
+       **/
+      agenda: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<Option<PalletUnqSchedulerScheduledV3>>>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
+      /**
+       * Lookup from identity to the block number and index of the task.
+       **/
+      lookup: AugmentedQuery<ApiType, (arg: U8aFixed | string | Uint8Array) => Observable<Option<ITuple<[u32, u32]>>>, [U8aFixed]> & QueryableStorageEntry<ApiType, [U8aFixed]>;
+      /**
+       * Generic query
+       **/
+      [key: string]: QueryableStorageEntry<ApiType>;
+    };
     structure: {
       /**
        * Generic query
modifiedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -1,7 +1,7 @@
 // Auto-generated via `yarn polkadot-types-from-chain`, do not edit
 /* eslint-disable */
 
-import type { PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCollectionLimits, UpDataStructsCollectionStats, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsRpcCollection, UpDataStructsTokenChild, UpDataStructsTokenData } from './default';
+import type { PalletEvmAccountBasicCrossAccountIdRepr, RmrkTraitsBaseBaseInfo, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftNftChild, RmrkTraitsNftNftInfo, RmrkTraitsPartPartType, RmrkTraitsPropertyPropertyInfo, RmrkTraitsResourceResourceInfo, RmrkTraitsTheme, UpDataStructsCollectionLimits, UpDataStructsCollectionStats, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsRpcCollection, UpDataStructsTokenChild, UpDataStructsTokenData } from './default';
 import type { AugmentedRpc } from '@polkadot/rpc-core/types';
 import type { Metadata, StorageKey } from '@polkadot/types';
 import type { Bytes, HashMap, Json, Null, Option, Text, U256, U64, Vec, bool, u128, u32, u64 } from '@polkadot/types-codec';
@@ -22,7 +22,7 @@
 import type { StorageKind } from '@polkadot/types/interfaces/offchain';
 import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';
 import type { RpcMethods } from '@polkadot/types/interfaces/rpc';
-import type { AccountId, BlockNumber, H160, H256, H64, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';
+import type { AccountId, AccountId32, BlockNumber, H160, H256, H64, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';
 import type { MigrationStatusResult, ReadProof, RuntimeVersion, TraceBlockResponse } from '@polkadot/types/interfaces/state';
 import type { ApplyExtrinsicResult, ChainProperties, ChainType, Health, NetworkState, NodeRole, PeerInfo, SyncState } from '@polkadot/types/interfaces/system';
 import type { IExtrinsic, Observable } from '@polkadot/types/types';
@@ -397,6 +397,60 @@
        **/
       queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<RuntimeDispatchInfo>>;
     };
+    rmrk: {
+      /**
+       * Get tokens owned by an account in a collection
+       **/
+      accountTokens: AugmentedRpc<(accountId: AccountId32 | string | Uint8Array, collectionId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<u32>>>;
+      /**
+       * Get base info
+       **/
+      base: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsBaseBaseInfo>>>;
+      /**
+       * Get all Base's parts
+       **/
+      baseParts: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsPartPartType>>>;
+      /**
+       * Get collection by id
+       **/
+      collectionById: AugmentedRpc<(id: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsCollectionCollectionInfo>>>;
+      /**
+       * Get collection properties
+       **/
+      collectionProperties: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, filterKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsPropertyPropertyInfo>>>;
+      /**
+       * Get the latest created collection id
+       **/
+      lastCollectionIdx: AugmentedRpc<(at?: Hash | string | Uint8Array) => Observable<u32>>;
+      /**
+       * Get NFT by collection id and NFT id
+       **/
+      nftById: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsNftNftInfo>>>;
+      /**
+       * Get NFT children
+       **/
+      nftChildren: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsNftNftChild>>>;
+      /**
+       * Get NFT properties
+       **/
+      nftProperties: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, filterKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsPropertyPropertyInfo>>>;
+      /**
+       * Get NFT resource priorities
+       **/
+      nftResourcePriority: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, resourceId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<u32>>>;
+      /**
+       * Get NFT resources
+       **/
+      nftResources: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsResourceResourceInfo>>>;
+      /**
+       * Get Base's theme names
+       **/
+      themeNames: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<Bytes>>>;
+      /**
+       * Get Theme's keys values
+       **/
+      themes: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, themeName: Text | string, keys: Option<Vec<Text>> | null | object | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsTheme>>>;
+    };
     rpc: {
       /**
        * Retrieves the list of RPC methods that are exposed by the node
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -2,10 +2,10 @@
 /* eslint-disable */
 
 import type { ApiTypes } from '@polkadot/api-base/types';
-import type { Bytes, Compact, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types-codec';
+import type { Bytes, Compact, Option, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec';
 import type { AnyNumber, IMethod, ITuple } from '@polkadot/types-codec/types';
-import type { AccountId32, Call, H160, H256, MultiAddress, Perbill } from '@polkadot/types/interfaces/runtime';
-import type { CumulusPrimitivesParachainInherentParachainInherentData, EthereumTransactionTransactionV2, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionPermissions, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
+import type { AccountId32, Call, H160, H256, MultiAddress, Perbill, Permill } from '@polkadot/types/interfaces/runtime';
+import type { CumulusPrimitivesParachainInherentParachainInherentData, EthereumTransactionTransactionV2, FrameSupportScheduleMaybeHashed, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, RmrkTraitsNftAccountIdOrCollectionNftTuple, RmrkTraitsPartPartType, RmrkTraitsResourceBasicResource, RmrkTraitsResourceComposableResource, RmrkTraitsResourceSlotResource, RmrkTraitsTheme, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionPermissions, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
 
 declare module '@polkadot/api-base/types/submittable' {
   export interface AugmentedSubmittables<ApiType extends ApiTypes> {
@@ -346,6 +346,59 @@
        **/
       [key: string]: SubmittableExtrinsicFunction<ApiType>;
     };
+    rmrkCore: {
+      acceptNft: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, rmrkNftId: u32 | AnyNumber | Uint8Array, newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple | { AccountId: any } | { CollectionAndNftTuple: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, RmrkTraitsNftAccountIdOrCollectionNftTuple]>;
+      acceptResource: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, rmrkNftId: u32 | AnyNumber | Uint8Array, rmrkResourceId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u32]>;
+      acceptResourceRemoval: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, rmrkNftId: u32 | AnyNumber | Uint8Array, rmrkResourceId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u32]>;
+      addBasicResource: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, resource: RmrkTraitsResourceBasicResource | { src?: any; metadata?: any; license?: any; thumb?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, RmrkTraitsResourceBasicResource]>;
+      addComposableResource: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, resourceId: Bytes | string | Uint8Array, resource: RmrkTraitsResourceComposableResource | { parts?: any; base?: any; src?: any; metadata?: any; license?: any; thumb?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, Bytes, RmrkTraitsResourceComposableResource]>;
+      addSlotResource: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, resource: RmrkTraitsResourceSlotResource | { base?: any; src?: any; metadata?: any; slot?: any; license?: any; thumb?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, RmrkTraitsResourceSlotResource]>;
+      burnNft: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32]>;
+      changeCollectionIssuer: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newIssuer: MultiAddress | { Id: any } | { Index: any } | { Raw: any } | { Address32: any } | { Address20: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, MultiAddress]>;
+      createCollection: AugmentedSubmittable<(metadata: Bytes | string | Uint8Array, max: Option<u32> | null | object | string | Uint8Array, symbol: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [Bytes, Option<u32>, Bytes]>;
+      destroyCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
+      lockCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
+      mintNft: AugmentedSubmittable<(owner: AccountId32 | string | Uint8Array, collectionId: u32 | AnyNumber | Uint8Array, recipient: Option<AccountId32> | null | object | string | Uint8Array, royaltyAmount: Option<Permill> | null | object | string | Uint8Array, metadata: Bytes | string | Uint8Array, transferable: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [AccountId32, u32, Option<AccountId32>, Option<Permill>, Bytes, bool]>;
+      rejectNft: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, rmrkNftId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32]>;
+      removeResource: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, resourceId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u32]>;
+      send: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, rmrkNftId: u32 | AnyNumber | Uint8Array, newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple | { AccountId: any } | { CollectionAndNftTuple: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, RmrkTraitsNftAccountIdOrCollectionNftTuple]>;
+      setPriority: AugmentedSubmittable<(rmrkCollectionId: u32 | AnyNumber | Uint8Array, rmrkNftId: u32 | AnyNumber | Uint8Array, priorities: Vec<u32> | (u32 | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, u32, Vec<u32>]>;
+      setProperty: AugmentedSubmittable<(rmrkCollectionId: Compact<u32> | AnyNumber | Uint8Array, maybeNftId: Option<u32> | null | object | string | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [Compact<u32>, Option<u32>, Bytes, Bytes]>;
+      /**
+       * Generic tx
+       **/
+      [key: string]: SubmittableExtrinsicFunction<ApiType>;
+    };
+    rmrkEquip: {
+      createBase: AugmentedSubmittable<(baseType: Bytes | string | Uint8Array, symbol: Bytes | string | Uint8Array, parts: Vec<RmrkTraitsPartPartType> | (RmrkTraitsPartPartType | { FixedPart: any } | { SlotPart: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [Bytes, Bytes, Vec<RmrkTraitsPartPartType>]>;
+      themeAdd: AugmentedSubmittable<(baseId: u32 | AnyNumber | Uint8Array, theme: RmrkTraitsTheme | { name?: any; properties?: any; inherit?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, RmrkTraitsTheme]>;
+      /**
+       * Generic tx
+       **/
+      [key: string]: SubmittableExtrinsicFunction<ApiType>;
+    };
+    scheduler: {
+      /**
+       * Cancel a named scheduled task.
+       **/
+      cancelNamed: AugmentedSubmittable<(id: U8aFixed | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [U8aFixed]>;
+      /**
+       * Schedule a named task.
+       **/
+      scheduleNamed: AugmentedSubmittable<(id: U8aFixed | string | Uint8Array, when: u32 | AnyNumber | Uint8Array, maybePeriodic: Option<ITuple<[u32, u32]>> | null | object | string | Uint8Array, priority: u8 | AnyNumber | Uint8Array, call: FrameSupportScheduleMaybeHashed | { Value: any } | { Hash: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [U8aFixed, u32, Option<ITuple<[u32, u32]>>, u8, FrameSupportScheduleMaybeHashed]>;
+      /**
+       * Schedule a named task after a delay.
+       * 
+       * # <weight>
+       * Same as [`schedule_named`](Self::schedule_named).
+       * # </weight>
+       **/
+      scheduleNamedAfter: AugmentedSubmittable<(id: U8aFixed | string | Uint8Array, after: u32 | AnyNumber | Uint8Array, maybePeriodic: Option<ITuple<[u32, u32]>> | null | object | string | Uint8Array, priority: u8 | AnyNumber | Uint8Array, call: FrameSupportScheduleMaybeHashed | { Value: any } | { Hash: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [U8aFixed, u32, Option<ITuple<[u32, u32]>>, u8, FrameSupportScheduleMaybeHashed]>;
+      /**
+       * Generic tx
+       **/
+      [key: string]: SubmittableExtrinsicFunction<ApiType>;
+    };
     structure: {
       /**
        * Generic tx
@@ -543,6 +596,24 @@
        **/
       rejectProposal: AugmentedSubmittable<(proposalId: Compact<u32> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [Compact<u32>]>;
       /**
+       * Force a previously approved proposal to be removed from the approval queue.
+       * The original deposit will no longer be returned.
+       * 
+       * May only be called from `T::RejectOrigin`.
+       * - `proposal_id`: The index of a proposal
+       * 
+       * # <weight>
+       * - Complexity: O(A) where `A` is the number of approvals
+       * - Db reads and writes: `Approvals`
+       * # </weight>
+       * 
+       * Errors:
+       * - `ProposalNotApproved`: The `proposal_id` supplied was not found in the approval queue,
+       * i.e., the proposal has not been approved. This could also mean the proposal does not
+       * exist altogether, thus there is no way it would have been approved in the first place.
+       **/
+      removeApproval: AugmentedSubmittable<(proposalId: Compact<u32> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [Compact<u32>]>;
+      /**
        * Generic tx
        **/
       [key: string]: SubmittableExtrinsicFunction<ApiType>;
modifiedtests/src/interfaces/augment-types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-types.ts
+++ b/tests/src/interfaces/augment-types.ts
@@ -1,7 +1,7 @@
 // Auto-generated via `yarn polkadot-types-from-defs`, do not edit
 /* eslint-disable */
 
-import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportPalletId, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PhantomTypeUpDataStructs, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionPermissions, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRmrkAccountIdOrCollectionNftTuple, UpDataStructsRmrkBaseInfo, UpDataStructsRmrkBasicResource, UpDataStructsRmrkCollectionInfo, UpDataStructsRmrkComposableResource, UpDataStructsRmrkEquippableList, UpDataStructsRmrkFixedPart, UpDataStructsRmrkNftChild, UpDataStructsRmrkNftInfo, UpDataStructsRmrkPartType, UpDataStructsRmrkPropertyInfo, UpDataStructsRmrkResourceInfo, UpDataStructsRmrkResourceTypes, UpDataStructsRmrkRoyaltyInfo, UpDataStructsRmrkSlotPart, UpDataStructsRmrkSlotResource, UpDataStructsRmrkTheme, UpDataStructsRmrkThemeProperty, UpDataStructsRpcCollection, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenChild, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from './default';
+import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmOrigin, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportDispatchRawOrigin, FrameSupportPalletId, FrameSupportScheduleLookupError, FrameSupportScheduleMaybeHashed, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeOriginCaller, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEthereumRawOrigin, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletRmrkCoreCall, PalletRmrkCoreError, PalletRmrkCoreEvent, PalletRmrkEquipCall, PalletRmrkEquipError, PalletRmrkEquipEvent, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletUnqSchedulerCall, PalletUnqSchedulerError, PalletUnqSchedulerEvent, PalletUnqSchedulerScheduledV3, PalletXcmCall, PalletXcmError, PalletXcmEvent, PalletXcmOrigin, PhantomTypeUpDataStructs, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, RmrkTraitsBaseBaseInfo, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftAccountIdOrCollectionNftTuple, RmrkTraitsNftNftChild, RmrkTraitsNftNftInfo, RmrkTraitsNftRoyaltyInfo, RmrkTraitsPartEquippableList, RmrkTraitsPartFixedPart, RmrkTraitsPartPartType, RmrkTraitsPartSlotPart, RmrkTraitsPropertyPropertyInfo, RmrkTraitsResourceBasicResource, RmrkTraitsResourceComposableResource, RmrkTraitsResourceResourceInfo, RmrkTraitsResourceResourceTypes, RmrkTraitsResourceSlotResource, RmrkTraitsTheme, RmrkTraitsThemeThemeProperty, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpCoreVoid, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionPermissions, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRpcCollection, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenChild, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from './default';
 import type { Data, StorageKey } from '@polkadot/types';
 import type { BitVec, Bool, Bytes, I128, I16, I256, I32, I64, I8, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec';
 import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets';
@@ -18,7 +18,7 @@
 import type { StatementKind } from '@polkadot/types/interfaces/claims';
 import type { CollectiveOrigin, MemberCount, ProposalIndex, Votes, VotesTo230 } from '@polkadot/types/interfaces/collective';
 import type { AuthorityId, RawVRFOutput } from '@polkadot/types/interfaces/consensus';
-import type { AliveContractInfo, CodeHash, CodeSource, CodeUploadRequest, CodeUploadResult, CodeUploadResultValue, ContractCallFlags, ContractCallRequest, ContractExecResult, ContractExecResultErr, ContractExecResultErrModule, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractInstantiateResultTo299, ContractReturnFlags, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateRequestV1, InstantiateRequestV2, InstantiateReturnValue, InstantiateReturnValueOk, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, StorageDeposit, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';
+import type { AliveContractInfo, CodeHash, CodeSource, CodeUploadRequest, CodeUploadResult, CodeUploadResultValue, ContractCallFlags, ContractCallRequest, ContractExecResult, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractInstantiateResultTo299, ContractReturnFlags, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateRequestV1, InstantiateRequestV2, InstantiateReturnValue, InstantiateReturnValueOk, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, StorageDeposit, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';
 import type { ContractConstructorSpecLatest, ContractConstructorSpecV0, ContractConstructorSpecV1, ContractConstructorSpecV2, ContractConstructorSpecV3, ContractContractSpecV0, ContractContractSpecV1, ContractContractSpecV2, ContractContractSpecV3, ContractCryptoHasher, ContractDiscriminant, ContractDisplayName, ContractEventParamSpecLatest, ContractEventParamSpecV0, ContractEventParamSpecV2, ContractEventSpecLatest, ContractEventSpecV0, ContractEventSpecV1, ContractEventSpecV2, ContractLayoutArray, ContractLayoutCell, ContractLayoutEnum, ContractLayoutHash, ContractLayoutHashingStrategy, ContractLayoutKey, ContractLayoutStruct, ContractLayoutStructField, ContractMessageParamSpecLatest, ContractMessageParamSpecV0, ContractMessageParamSpecV2, ContractMessageSpecLatest, ContractMessageSpecV0, ContractMessageSpecV1, ContractMessageSpecV2, ContractMetadata, ContractMetadataLatest, ContractMetadataV0, ContractMetadataV1, ContractMetadataV2, ContractMetadataV3, ContractProject, ContractProjectContract, ContractProjectInfo, ContractProjectSource, ContractProjectV0, ContractSelector, ContractStorageLayout, ContractTypeSpec } from '@polkadot/types/interfaces/contractsAbi';
 import type { FundIndex, FundInfo, LastContribution, TrieIndex } from '@polkadot/types/interfaces/crowdloan';
 import type { ConfigData, MessageId, OverweightIndex, PageCounter, PageIndexData } from '@polkadot/types/interfaces/cumulus';
@@ -54,7 +54,7 @@
 import type { ActiveEraInfo, CompactAssignments, CompactAssignmentsTo257, CompactAssignmentsTo265, CompactAssignmentsWith16, CompactAssignmentsWith24, CompactScore, CompactScoreCompact, ElectionCompute, ElectionPhase, ElectionResult, ElectionScore, ElectionSize, ElectionStatus, EraIndex, EraPoints, EraRewardPoints, EraRewards, Exposure, ExtendedBalance, Forcing, IndividualExposure, KeyType, MomentOf, Nominations, NominatorIndex, NominatorIndexCompact, OffchainAccuracy, OffchainAccuracyCompact, PhragmenScore, Points, RawSolution, RawSolutionTo265, RawSolutionWith16, RawSolutionWith24, ReadySolution, RewardDestination, RewardPoint, RoundSnapshot, SeatHolder, SignedSubmission, SignedSubmissionOf, SignedSubmissionTo276, SlashJournalEntry, SlashingSpans, SlashingSpansTo204, SolutionOrSnapshotSize, SolutionSupport, SolutionSupports, SpanIndex, SpanRecord, StakingLedger, StakingLedgerTo223, StakingLedgerTo240, SubmissionIndicesOf, Supports, UnappliedSlash, UnappliedSlashOther, UnlockChunk, ValidatorIndex, ValidatorIndexCompact, ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196, ValidatorPrefsWithBlocked, ValidatorPrefsWithCommission, VoteWeight, Voter } from '@polkadot/types/interfaces/staking';
 import type { ApiId, BlockTrace, BlockTraceEvent, BlockTraceEventData, BlockTraceSpan, KeyValueOption, MigrationStatusResult, ReadProof, RuntimeVersion, RuntimeVersionApi, RuntimeVersionPartial, SpecVersion, StorageChangeSet, TraceBlockResponse, TraceError } from '@polkadot/types/interfaces/state';
 import type { WeightToFeeCoefficient } from '@polkadot/types/interfaces/support';
-import type { AccountInfo, AccountInfoWithDualRefCount, AccountInfoWithProviders, AccountInfoWithRefCount, AccountInfoWithRefCountU8, AccountInfoWithTripleRefCount, ApplyExtrinsicResult, ArithmeticError, BlockLength, BlockWeights, ChainProperties, ChainType, ConsumedWeight, DigestOf, DispatchClass, DispatchError, DispatchErrorModule, DispatchErrorModuleU8a, DispatchErrorTo198, DispatchInfo, DispatchInfoTo190, DispatchInfoTo244, DispatchOutcome, DispatchResult, DispatchResultOf, DispatchResultTo198, Event, EventId, EventIndex, EventRecord, Health, InvalidTransaction, Key, LastRuntimeUpgradeInfo, NetworkState, NetworkStatePeerset, NetworkStatePeersetInfo, NodeRole, NotConnectedPeer, Peer, PeerEndpoint, PeerEndpointAddr, PeerInfo, PeerPing, PerDispatchClassU32, PerDispatchClassWeight, PerDispatchClassWeightsPerClass, Phase, RawOrigin, RefCount, RefCountTo259, SyncState, SystemOrigin, TokenError, TransactionValidityError, UnknownTransaction, WeightPerClass } from '@polkadot/types/interfaces/system';
+import type { AccountInfo, AccountInfoWithDualRefCount, AccountInfoWithProviders, AccountInfoWithRefCount, AccountInfoWithRefCountU8, AccountInfoWithTripleRefCount, ApplyExtrinsicResult, ArithmeticError, BlockLength, BlockWeights, ChainProperties, ChainType, ConsumedWeight, DigestOf, DispatchClass, DispatchError, DispatchErrorModule, DispatchErrorModuleU8, DispatchErrorModuleU8a, DispatchErrorTo198, DispatchInfo, DispatchInfoTo190, DispatchInfoTo244, DispatchOutcome, DispatchResult, DispatchResultOf, DispatchResultTo198, Event, EventId, EventIndex, EventRecord, Health, InvalidTransaction, Key, LastRuntimeUpgradeInfo, NetworkState, NetworkStatePeerset, NetworkStatePeersetInfo, NodeRole, NotConnectedPeer, Peer, PeerEndpoint, PeerEndpointAddr, PeerInfo, PeerPing, PerDispatchClassU32, PerDispatchClassWeight, PerDispatchClassWeightsPerClass, Phase, RawOrigin, RefCount, RefCountTo259, SyncState, SystemOrigin, TokenError, TransactionValidityError, TransactionalError, UnknownTransaction, WeightPerClass } from '@polkadot/types/interfaces/system';
 import type { Bounty, BountyIndex, BountyStatus, BountyStatusActive, BountyStatusCuratorProposed, BountyStatusPendingPayout, OpenTip, OpenTipFinderTo225, OpenTipTip, OpenTipTo225, TreasuryProposal } from '@polkadot/types/interfaces/treasury';
 import type { Multiplier } from '@polkadot/types/interfaces/txpayment';
 import type { ClassDetails, ClassId, ClassMetadata, DepositBalance, DepositBalanceOf, DestroyWitness, InstanceDetails, InstanceId, InstanceMetadata } from '@polkadot/types/interfaces/uniques';
@@ -241,8 +241,6 @@
     ContractEventSpecV1: ContractEventSpecV1;
     ContractEventSpecV2: ContractEventSpecV2;
     ContractExecResult: ContractExecResult;
-    ContractExecResultErr: ContractExecResultErr;
-    ContractExecResultErrModule: ContractExecResultErrModule;
     ContractExecResultOk: ContractExecResultOk;
     ContractExecResultResult: ContractExecResultResult;
     ContractExecResultSuccessTo255: ContractExecResultSuccessTo255;
@@ -303,6 +301,7 @@
     CumulusPalletXcmCall: CumulusPalletXcmCall;
     CumulusPalletXcmError: CumulusPalletXcmError;
     CumulusPalletXcmEvent: CumulusPalletXcmEvent;
+    CumulusPalletXcmOrigin: CumulusPalletXcmOrigin;
     CumulusPalletXcmpQueueCall: CumulusPalletXcmpQueueCall;
     CumulusPalletXcmpQueueError: CumulusPalletXcmpQueueError;
     CumulusPalletXcmpQueueEvent: CumulusPalletXcmpQueueEvent;
@@ -329,6 +328,7 @@
     DispatchClass: DispatchClass;
     DispatchError: DispatchError;
     DispatchErrorModule: DispatchErrorModule;
+    DispatchErrorModuleU8: DispatchErrorModuleU8;
     DispatchErrorModuleU8a: DispatchErrorModuleU8a;
     DispatchErrorTo198: DispatchErrorTo198;
     DispatchFeePayment: DispatchFeePayment;
@@ -477,7 +477,10 @@
     ForkTreePendingChange: ForkTreePendingChange;
     ForkTreePendingChangeNode: ForkTreePendingChangeNode;
     FpRpcTransactionStatus: FpRpcTransactionStatus;
+    FrameSupportDispatchRawOrigin: FrameSupportDispatchRawOrigin;
     FrameSupportPalletId: FrameSupportPalletId;
+    FrameSupportScheduleLookupError: FrameSupportScheduleLookupError;
+    FrameSupportScheduleMaybeHashed: FrameSupportScheduleMaybeHashed;
     FrameSupportTokensMiscBalanceStatus: FrameSupportTokensMiscBalanceStatus;
     FrameSupportWeightsDispatchClass: FrameSupportWeightsDispatchClass;
     FrameSupportWeightsDispatchInfo: FrameSupportWeightsDispatchInfo;
@@ -717,6 +720,7 @@
     OffchainAccuracyCompact: OffchainAccuracyCompact;
     OffenceDetails: OffenceDetails;
     Offender: Offender;
+    OpalRuntimeOriginCaller: OpalRuntimeOriginCaller;
     OpalRuntimeRuntime: OpalRuntimeRuntime;
     OpaqueCall: OpaqueCall;
     OpaqueMultiaddr: OpaqueMultiaddr;
@@ -768,6 +772,7 @@
     PalletEthereumError: PalletEthereumError;
     PalletEthereumEvent: PalletEthereumEvent;
     PalletEthereumFakeTransactionFinalizer: PalletEthereumFakeTransactionFinalizer;
+    PalletEthereumRawOrigin: PalletEthereumRawOrigin;
     PalletEventMetadataLatest: PalletEventMetadataLatest;
     PalletEventMetadataV14: PalletEventMetadataV14;
     PalletEvmAccountBasicCrossAccountIdRepr: PalletEvmAccountBasicCrossAccountIdRepr;
@@ -788,6 +793,12 @@
     PalletNonfungibleItemData: PalletNonfungibleItemData;
     PalletRefungibleError: PalletRefungibleError;
     PalletRefungibleItemData: PalletRefungibleItemData;
+    PalletRmrkCoreCall: PalletRmrkCoreCall;
+    PalletRmrkCoreError: PalletRmrkCoreError;
+    PalletRmrkCoreEvent: PalletRmrkCoreEvent;
+    PalletRmrkEquipCall: PalletRmrkEquipCall;
+    PalletRmrkEquipError: PalletRmrkEquipError;
+    PalletRmrkEquipEvent: PalletRmrkEquipEvent;
     PalletsOrigin: PalletsOrigin;
     PalletStorageMetadataLatest: PalletStorageMetadataLatest;
     PalletStorageMetadataV14: PalletStorageMetadataV14;
@@ -808,10 +819,15 @@
     PalletUniqueCall: PalletUniqueCall;
     PalletUniqueError: PalletUniqueError;
     PalletUniqueRawEvent: PalletUniqueRawEvent;
+    PalletUnqSchedulerCall: PalletUnqSchedulerCall;
+    PalletUnqSchedulerError: PalletUnqSchedulerError;
+    PalletUnqSchedulerEvent: PalletUnqSchedulerEvent;
+    PalletUnqSchedulerScheduledV3: PalletUnqSchedulerScheduledV3;
     PalletVersion: PalletVersion;
     PalletXcmCall: PalletXcmCall;
     PalletXcmError: PalletXcmError;
     PalletXcmEvent: PalletXcmEvent;
+    PalletXcmOrigin: PalletXcmOrigin;
     ParachainDispatchOrigin: ParachainDispatchOrigin;
     ParachainInherentData: ParachainInherentData;
     ParachainProposal: ParachainProposal;
@@ -943,6 +959,24 @@
     Retriable: Retriable;
     RewardDestination: RewardDestination;
     RewardPoint: RewardPoint;
+    RmrkTraitsBaseBaseInfo: RmrkTraitsBaseBaseInfo;
+    RmrkTraitsCollectionCollectionInfo: RmrkTraitsCollectionCollectionInfo;
+    RmrkTraitsNftAccountIdOrCollectionNftTuple: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    RmrkTraitsNftNftChild: RmrkTraitsNftNftChild;
+    RmrkTraitsNftNftInfo: RmrkTraitsNftNftInfo;
+    RmrkTraitsNftRoyaltyInfo: RmrkTraitsNftRoyaltyInfo;
+    RmrkTraitsPartEquippableList: RmrkTraitsPartEquippableList;
+    RmrkTraitsPartFixedPart: RmrkTraitsPartFixedPart;
+    RmrkTraitsPartPartType: RmrkTraitsPartPartType;
+    RmrkTraitsPartSlotPart: RmrkTraitsPartSlotPart;
+    RmrkTraitsPropertyPropertyInfo: RmrkTraitsPropertyPropertyInfo;
+    RmrkTraitsResourceBasicResource: RmrkTraitsResourceBasicResource;
+    RmrkTraitsResourceComposableResource: RmrkTraitsResourceComposableResource;
+    RmrkTraitsResourceResourceInfo: RmrkTraitsResourceResourceInfo;
+    RmrkTraitsResourceResourceTypes: RmrkTraitsResourceResourceTypes;
+    RmrkTraitsResourceSlotResource: RmrkTraitsResourceSlotResource;
+    RmrkTraitsTheme: RmrkTraitsTheme;
+    RmrkTraitsThemeThemeProperty: RmrkTraitsThemeThemeProperty;
     RoundSnapshot: RoundSnapshot;
     RoundState: RoundState;
     RpcMethods: RpcMethods;
@@ -1061,6 +1095,7 @@
     SpCoreEcdsaSignature: SpCoreEcdsaSignature;
     SpCoreEd25519Signature: SpCoreEd25519Signature;
     SpCoreSr25519Signature: SpCoreSr25519Signature;
+    SpCoreVoid: SpCoreVoid;
     SpecVersion: SpecVersion;
     SpRuntimeArithmeticError: SpRuntimeArithmeticError;
     SpRuntimeDigest: SpRuntimeDigest;
@@ -1136,6 +1171,7 @@
     TombstoneContractInfo: TombstoneContractInfo;
     TraceBlockResponse: TraceBlockResponse;
     TraceError: TraceError;
+    TransactionalError: TransactionalError;
     TransactionInfo: TransactionInfo;
     TransactionPriority: TransactionPriority;
     TransactionStorageProof: TransactionStorageProof;
@@ -1189,24 +1225,6 @@
     UpDataStructsProperty: UpDataStructsProperty;
     UpDataStructsPropertyKeyPermission: UpDataStructsPropertyKeyPermission;
     UpDataStructsPropertyPermission: UpDataStructsPropertyPermission;
-    UpDataStructsRmrkAccountIdOrCollectionNftTuple: UpDataStructsRmrkAccountIdOrCollectionNftTuple;
-    UpDataStructsRmrkBaseInfo: UpDataStructsRmrkBaseInfo;
-    UpDataStructsRmrkBasicResource: UpDataStructsRmrkBasicResource;
-    UpDataStructsRmrkCollectionInfo: UpDataStructsRmrkCollectionInfo;
-    UpDataStructsRmrkComposableResource: UpDataStructsRmrkComposableResource;
-    UpDataStructsRmrkEquippableList: UpDataStructsRmrkEquippableList;
-    UpDataStructsRmrkFixedPart: UpDataStructsRmrkFixedPart;
-    UpDataStructsRmrkNftChild: UpDataStructsRmrkNftChild;
-    UpDataStructsRmrkNftInfo: UpDataStructsRmrkNftInfo;
-    UpDataStructsRmrkPartType: UpDataStructsRmrkPartType;
-    UpDataStructsRmrkPropertyInfo: UpDataStructsRmrkPropertyInfo;
-    UpDataStructsRmrkResourceInfo: UpDataStructsRmrkResourceInfo;
-    UpDataStructsRmrkResourceTypes: UpDataStructsRmrkResourceTypes;
-    UpDataStructsRmrkRoyaltyInfo: UpDataStructsRmrkRoyaltyInfo;
-    UpDataStructsRmrkSlotPart: UpDataStructsRmrkSlotPart;
-    UpDataStructsRmrkSlotResource: UpDataStructsRmrkSlotResource;
-    UpDataStructsRmrkTheme: UpDataStructsRmrkTheme;
-    UpDataStructsRmrkThemeProperty: UpDataStructsRmrkThemeProperty;
     UpDataStructsRpcCollection: UpDataStructsRpcCollection;
     UpDataStructsSponsoringRateLimit: UpDataStructsSponsoringRateLimit;
     UpDataStructsSponsorshipState: UpDataStructsSponsorshipState;
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -126,6 +126,14 @@
   readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward';
 }
 
+/** @name CumulusPalletXcmOrigin */
+export interface CumulusPalletXcmOrigin extends Enum {
+  readonly isRelay: boolean;
+  readonly isSiblingParachain: boolean;
+  readonly asSiblingParachain: u32;
+  readonly type: 'Relay' | 'SiblingParachain';
+}
+
 /** @name CumulusPalletXcmpQueueCall */
 export interface CumulusPalletXcmpQueueCall extends Enum {
   readonly isServiceOverweight: boolean;
@@ -443,9 +451,34 @@
   readonly logsBloom: EthbloomBloom;
 }
 
+/** @name FrameSupportDispatchRawOrigin */
+export interface FrameSupportDispatchRawOrigin extends Enum {
+  readonly isRoot: boolean;
+  readonly isSigned: boolean;
+  readonly asSigned: AccountId32;
+  readonly isNone: boolean;
+  readonly type: 'Root' | 'Signed' | 'None';
+}
+
 /** @name FrameSupportPalletId */
 export interface FrameSupportPalletId extends U8aFixed {}
 
+/** @name FrameSupportScheduleLookupError */
+export interface FrameSupportScheduleLookupError extends Enum {
+  readonly isUnknown: boolean;
+  readonly isBadFormat: boolean;
+  readonly type: 'Unknown' | 'BadFormat';
+}
+
+/** @name FrameSupportScheduleMaybeHashed */
+export interface FrameSupportScheduleMaybeHashed extends Enum {
+  readonly isValue: boolean;
+  readonly asValue: Call;
+  readonly isHash: boolean;
+  readonly asHash: H256;
+  readonly type: 'Value' | 'Hash';
+}
+
 /** @name FrameSupportTokensMiscBalanceStatus */
 export interface FrameSupportTokensMiscBalanceStatus extends Enum {
   readonly isFree: boolean;
@@ -654,6 +687,21 @@
   readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';
 }
 
+/** @name OpalRuntimeOriginCaller */
+export interface OpalRuntimeOriginCaller extends Enum {
+  readonly isVoid: boolean;
+  readonly asVoid: SpCoreVoid;
+  readonly isSystem: boolean;
+  readonly asSystem: FrameSupportDispatchRawOrigin;
+  readonly isPolkadotXcm: boolean;
+  readonly asPolkadotXcm: PalletXcmOrigin;
+  readonly isCumulusXcm: boolean;
+  readonly asCumulusXcm: CumulusPalletXcmOrigin;
+  readonly isEthereum: boolean;
+  readonly asEthereum: PalletEthereumRawOrigin;
+  readonly type: 'Void' | 'System' | 'PolkadotXcm' | 'CumulusXcm' | 'Ethereum';
+}
+
 /** @name OpalRuntimeRuntime */
 export interface OpalRuntimeRuntime extends Null {}
 
@@ -896,7 +944,9 @@
   readonly isPropertyKeyIsTooLong: boolean;
   readonly isInvalidCharacterInPropertyKey: boolean;
   readonly isEmptyPropertyKey: boolean;
-  readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'CantDestroyNotEmptyCollection' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
+  readonly isCollectionIsExternal: boolean;
+  readonly isCollectionIsInternal: boolean;
+  readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'CantDestroyNotEmptyCollection' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey' | 'CollectionIsExternal' | 'CollectionIsInternal';
 }
 
 /** @name PalletCommonEvent */
@@ -952,6 +1002,13 @@
 /** @name PalletEthereumFakeTransactionFinalizer */
 export interface PalletEthereumFakeTransactionFinalizer extends Null {}
 
+/** @name PalletEthereumRawOrigin */
+export interface PalletEthereumRawOrigin extends Enum {
+  readonly isEthereumTransaction: boolean;
+  readonly asEthereumTransaction: H160;
+  readonly type: 'EthereumTransaction';
+}
+
 /** @name PalletEvmAccountBasicCrossAccountIdRepr */
 export interface PalletEvmAccountBasicCrossAccountIdRepr extends Enum {
   readonly isSubstrate: boolean;
@@ -1129,6 +1186,258 @@
   readonly constData: Bytes;
 }
 
+/** @name PalletRmrkCoreCall */
+export interface PalletRmrkCoreCall extends Enum {
+  readonly isCreateCollection: boolean;
+  readonly asCreateCollection: {
+    readonly metadata: Bytes;
+    readonly max: Option<u32>;
+    readonly symbol: Bytes;
+  } & Struct;
+  readonly isDestroyCollection: boolean;
+  readonly asDestroyCollection: {
+    readonly collectionId: u32;
+  } & Struct;
+  readonly isChangeCollectionIssuer: boolean;
+  readonly asChangeCollectionIssuer: {
+    readonly collectionId: u32;
+    readonly newIssuer: MultiAddress;
+  } & Struct;
+  readonly isLockCollection: boolean;
+  readonly asLockCollection: {
+    readonly collectionId: u32;
+  } & Struct;
+  readonly isMintNft: boolean;
+  readonly asMintNft: {
+    readonly owner: AccountId32;
+    readonly collectionId: u32;
+    readonly recipient: Option<AccountId32>;
+    readonly royaltyAmount: Option<Permill>;
+    readonly metadata: Bytes;
+    readonly transferable: bool;
+  } & Struct;
+  readonly isBurnNft: boolean;
+  readonly asBurnNft: {
+    readonly collectionId: u32;
+    readonly nftId: u32;
+  } & Struct;
+  readonly isSend: boolean;
+  readonly asSend: {
+    readonly rmrkCollectionId: u32;
+    readonly rmrkNftId: u32;
+    readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+  } & Struct;
+  readonly isAcceptNft: boolean;
+  readonly asAcceptNft: {
+    readonly rmrkCollectionId: u32;
+    readonly rmrkNftId: u32;
+    readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+  } & Struct;
+  readonly isRejectNft: boolean;
+  readonly asRejectNft: {
+    readonly rmrkCollectionId: u32;
+    readonly rmrkNftId: u32;
+  } & Struct;
+  readonly isAcceptResource: boolean;
+  readonly asAcceptResource: {
+    readonly rmrkCollectionId: u32;
+    readonly rmrkNftId: u32;
+    readonly rmrkResourceId: u32;
+  } & Struct;
+  readonly isAcceptResourceRemoval: boolean;
+  readonly asAcceptResourceRemoval: {
+    readonly rmrkCollectionId: u32;
+    readonly rmrkNftId: u32;
+    readonly rmrkResourceId: u32;
+  } & Struct;
+  readonly isSetProperty: boolean;
+  readonly asSetProperty: {
+    readonly rmrkCollectionId: Compact<u32>;
+    readonly maybeNftId: Option<u32>;
+    readonly key: Bytes;
+    readonly value: Bytes;
+  } & Struct;
+  readonly isSetPriority: boolean;
+  readonly asSetPriority: {
+    readonly rmrkCollectionId: u32;
+    readonly rmrkNftId: u32;
+    readonly priorities: Vec<u32>;
+  } & Struct;
+  readonly isAddBasicResource: boolean;
+  readonly asAddBasicResource: {
+    readonly rmrkCollectionId: u32;
+    readonly nftId: u32;
+    readonly resource: RmrkTraitsResourceBasicResource;
+  } & Struct;
+  readonly isAddComposableResource: boolean;
+  readonly asAddComposableResource: {
+    readonly rmrkCollectionId: u32;
+    readonly nftId: u32;
+    readonly resourceId: Bytes;
+    readonly resource: RmrkTraitsResourceComposableResource;
+  } & Struct;
+  readonly isAddSlotResource: boolean;
+  readonly asAddSlotResource: {
+    readonly rmrkCollectionId: u32;
+    readonly nftId: u32;
+    readonly resource: RmrkTraitsResourceSlotResource;
+  } & Struct;
+  readonly isRemoveResource: boolean;
+  readonly asRemoveResource: {
+    readonly rmrkCollectionId: u32;
+    readonly nftId: u32;
+    readonly resourceId: u32;
+  } & Struct;
+  readonly type: 'CreateCollection' | 'DestroyCollection' | 'ChangeCollectionIssuer' | 'LockCollection' | 'MintNft' | 'BurnNft' | 'Send' | 'AcceptNft' | 'RejectNft' | 'AcceptResource' | 'AcceptResourceRemoval' | 'SetProperty' | 'SetPriority' | 'AddBasicResource' | 'AddComposableResource' | 'AddSlotResource' | 'RemoveResource';
+}
+
+/** @name PalletRmrkCoreError */
+export interface PalletRmrkCoreError extends Enum {
+  readonly isCorruptedCollectionType: boolean;
+  readonly isNftTypeEncodeError: boolean;
+  readonly isRmrkPropertyKeyIsTooLong: boolean;
+  readonly isRmrkPropertyValueIsTooLong: boolean;
+  readonly isCollectionNotEmpty: boolean;
+  readonly isNoAvailableCollectionId: boolean;
+  readonly isNoAvailableNftId: boolean;
+  readonly isCollectionUnknown: boolean;
+  readonly isNoPermission: boolean;
+  readonly isNonTransferable: boolean;
+  readonly isCollectionFullOrLocked: boolean;
+  readonly isResourceDoesntExist: boolean;
+  readonly isCannotSendToDescendentOrSelf: boolean;
+  readonly isCannotAcceptNonOwnedNft: boolean;
+  readonly isCannotRejectNonOwnedNft: boolean;
+  readonly isResourceNotPending: boolean;
+  readonly type: 'CorruptedCollectionType' | 'NftTypeEncodeError' | 'RmrkPropertyKeyIsTooLong' | 'RmrkPropertyValueIsTooLong' | 'CollectionNotEmpty' | 'NoAvailableCollectionId' | 'NoAvailableNftId' | 'CollectionUnknown' | 'NoPermission' | 'NonTransferable' | 'CollectionFullOrLocked' | 'ResourceDoesntExist' | 'CannotSendToDescendentOrSelf' | 'CannotAcceptNonOwnedNft' | 'CannotRejectNonOwnedNft' | 'ResourceNotPending';
+}
+
+/** @name PalletRmrkCoreEvent */
+export interface PalletRmrkCoreEvent extends Enum {
+  readonly isCollectionCreated: boolean;
+  readonly asCollectionCreated: {
+    readonly issuer: AccountId32;
+    readonly collectionId: u32;
+  } & Struct;
+  readonly isCollectionDestroyed: boolean;
+  readonly asCollectionDestroyed: {
+    readonly issuer: AccountId32;
+    readonly collectionId: u32;
+  } & Struct;
+  readonly isIssuerChanged: boolean;
+  readonly asIssuerChanged: {
+    readonly oldIssuer: AccountId32;
+    readonly newIssuer: AccountId32;
+    readonly collectionId: u32;
+  } & Struct;
+  readonly isCollectionLocked: boolean;
+  readonly asCollectionLocked: {
+    readonly issuer: AccountId32;
+    readonly collectionId: u32;
+  } & Struct;
+  readonly isNftMinted: boolean;
+  readonly asNftMinted: {
+    readonly owner: AccountId32;
+    readonly collectionId: u32;
+    readonly nftId: u32;
+  } & Struct;
+  readonly isNftBurned: boolean;
+  readonly asNftBurned: {
+    readonly owner: AccountId32;
+    readonly nftId: u32;
+  } & Struct;
+  readonly isNftSent: boolean;
+  readonly asNftSent: {
+    readonly sender: AccountId32;
+    readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    readonly collectionId: u32;
+    readonly nftId: u32;
+    readonly approvalRequired: bool;
+  } & Struct;
+  readonly isNftAccepted: boolean;
+  readonly asNftAccepted: {
+    readonly sender: AccountId32;
+    readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    readonly collectionId: u32;
+    readonly nftId: u32;
+  } & Struct;
+  readonly isNftRejected: boolean;
+  readonly asNftRejected: {
+    readonly sender: AccountId32;
+    readonly collectionId: u32;
+    readonly nftId: u32;
+  } & Struct;
+  readonly isPropertySet: boolean;
+  readonly asPropertySet: {
+    readonly collectionId: u32;
+    readonly maybeNftId: Option<u32>;
+    readonly key: Bytes;
+    readonly value: Bytes;
+  } & Struct;
+  readonly isResourceAdded: boolean;
+  readonly asResourceAdded: {
+    readonly nftId: u32;
+    readonly resourceId: u32;
+  } & Struct;
+  readonly isResourceRemoval: boolean;
+  readonly asResourceRemoval: {
+    readonly nftId: u32;
+    readonly resourceId: u32;
+  } & Struct;
+  readonly isResourceAccepted: boolean;
+  readonly asResourceAccepted: {
+    readonly nftId: u32;
+    readonly resourceId: u32;
+  } & Struct;
+  readonly isResourceRemovalAccepted: boolean;
+  readonly asResourceRemovalAccepted: {
+    readonly nftId: u32;
+    readonly resourceId: u32;
+  } & Struct;
+  readonly isPrioritySet: boolean;
+  readonly asPrioritySet: {
+    readonly collectionId: u32;
+    readonly nftId: u32;
+  } & Struct;
+  readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';
+}
+
+/** @name PalletRmrkEquipCall */
+export interface PalletRmrkEquipCall extends Enum {
+  readonly isCreateBase: boolean;
+  readonly asCreateBase: {
+    readonly baseType: Bytes;
+    readonly symbol: Bytes;
+    readonly parts: Vec<RmrkTraitsPartPartType>;
+  } & Struct;
+  readonly isThemeAdd: boolean;
+  readonly asThemeAdd: {
+    readonly baseId: u32;
+    readonly theme: RmrkTraitsTheme;
+  } & Struct;
+  readonly type: 'CreateBase' | 'ThemeAdd';
+}
+
+/** @name PalletRmrkEquipError */
+export interface PalletRmrkEquipError extends Enum {
+  readonly isPermissionError: boolean;
+  readonly isNoAvailableBaseId: boolean;
+  readonly isNoAvailablePartId: boolean;
+  readonly isBaseDoesntExist: boolean;
+  readonly isNeedsDefaultThemeFirst: boolean;
+  readonly type: 'PermissionError' | 'NoAvailableBaseId' | 'NoAvailablePartId' | 'BaseDoesntExist' | 'NeedsDefaultThemeFirst';
+}
+
+/** @name PalletRmrkEquipEvent */
+export interface PalletRmrkEquipEvent extends Enum {
+  readonly isBaseCreated: boolean;
+  readonly asBaseCreated: {
+    readonly issuer: AccountId32;
+    readonly baseId: u32;
+  } & Struct;
+  readonly type: 'BaseCreated';
+}
+
 /** @name PalletStructureCall */
 export interface PalletStructureCall extends Null {}
 
@@ -1230,7 +1539,11 @@
   readonly asApproveProposal: {
     readonly proposalId: Compact<u32>;
   } & Struct;
-  readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal';
+  readonly isRemoveApproval: boolean;
+  readonly asRemoveApproval: {
+    readonly proposalId: Compact<u32>;
+  } & Struct;
+  readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal' | 'RemoveApproval';
 }
 
 /** @name PalletTreasuryError */
@@ -1238,7 +1551,8 @@
   readonly isInsufficientProposersBalance: boolean;
   readonly isInvalidIndex: boolean;
   readonly isTooManyApprovals: boolean;
-  readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals';
+  readonly isProposalNotApproved: boolean;
+  readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals' | 'ProposalNotApproved';
 }
 
 /** @name PalletTreasuryEvent */
@@ -1470,6 +1784,76 @@
   readonly type: 'CollectionSponsorRemoved' | 'CollectionAdminAdded' | 'CollectionOwnedChanged' | 'CollectionSponsorSet' | 'SponsorshipConfirmed' | 'CollectionAdminRemoved' | 'AllowListAddressRemoved' | 'AllowListAddressAdded' | 'CollectionLimitSet' | 'CollectionPermissionSet';
 }
 
+/** @name PalletUnqSchedulerCall */
+export interface PalletUnqSchedulerCall extends Enum {
+  readonly isScheduleNamed: boolean;
+  readonly asScheduleNamed: {
+    readonly id: U8aFixed;
+    readonly when: u32;
+    readonly maybePeriodic: Option<ITuple<[u32, u32]>>;
+    readonly priority: u8;
+    readonly call: FrameSupportScheduleMaybeHashed;
+  } & Struct;
+  readonly isCancelNamed: boolean;
+  readonly asCancelNamed: {
+    readonly id: U8aFixed;
+  } & Struct;
+  readonly isScheduleNamedAfter: boolean;
+  readonly asScheduleNamedAfter: {
+    readonly id: U8aFixed;
+    readonly after: u32;
+    readonly maybePeriodic: Option<ITuple<[u32, u32]>>;
+    readonly priority: u8;
+    readonly call: FrameSupportScheduleMaybeHashed;
+  } & Struct;
+  readonly type: 'ScheduleNamed' | 'CancelNamed' | 'ScheduleNamedAfter';
+}
+
+/** @name PalletUnqSchedulerError */
+export interface PalletUnqSchedulerError extends Enum {
+  readonly isFailedToSchedule: boolean;
+  readonly isNotFound: boolean;
+  readonly isTargetBlockNumberInPast: boolean;
+  readonly isRescheduleNoChange: boolean;
+  readonly type: 'FailedToSchedule' | 'NotFound' | 'TargetBlockNumberInPast' | 'RescheduleNoChange';
+}
+
+/** @name PalletUnqSchedulerEvent */
+export interface PalletUnqSchedulerEvent extends Enum {
+  readonly isScheduled: boolean;
+  readonly asScheduled: {
+    readonly when: u32;
+    readonly index: u32;
+  } & Struct;
+  readonly isCanceled: boolean;
+  readonly asCanceled: {
+    readonly when: u32;
+    readonly index: u32;
+  } & Struct;
+  readonly isDispatched: boolean;
+  readonly asDispatched: {
+    readonly task: ITuple<[u32, u32]>;
+    readonly id: Option<U8aFixed>;
+    readonly result: Result<Null, SpRuntimeDispatchError>;
+  } & Struct;
+  readonly isCallLookupFailed: boolean;
+  readonly asCallLookupFailed: {
+    readonly task: ITuple<[u32, u32]>;
+    readonly id: Option<U8aFixed>;
+    readonly error: FrameSupportScheduleLookupError;
+  } & Struct;
+  readonly type: 'Scheduled' | 'Canceled' | 'Dispatched' | 'CallLookupFailed';
+}
+
+/** @name PalletUnqSchedulerScheduledV3 */
+export interface PalletUnqSchedulerScheduledV3 extends Struct {
+  readonly maybeId: Option<U8aFixed>;
+  readonly priority: u8;
+  readonly call: FrameSupportScheduleMaybeHashed;
+  readonly maybePeriodic: Option<ITuple<[u32, u32]>>;
+  readonly origin: OpalRuntimeOriginCaller;
+}
+
 /** @name PalletXcmCall */
 export interface PalletXcmCall extends Enum {
   readonly isSend: boolean;
@@ -1587,8 +1971,17 @@
   readonly type: 'Attempted' | 'Sent' | 'UnexpectedResponse' | 'ResponseReady' | 'Notified' | 'NotifyOverweight' | 'NotifyDispatchError' | 'NotifyDecodeFailed' | 'InvalidResponder' | 'InvalidResponderVersion' | 'ResponseTaken' | 'AssetsTrapped' | 'VersionChangeNotified' | 'SupportedVersionChanged' | 'NotifyTargetSendFail' | 'NotifyTargetMigrationFail';
 }
 
+/** @name PalletXcmOrigin */
+export interface PalletXcmOrigin extends Enum {
+  readonly isXcm: boolean;
+  readonly asXcm: XcmV1MultiLocation;
+  readonly isResponse: boolean;
+  readonly asResponse: XcmV1MultiLocation;
+  readonly type: 'Xcm' | 'Response';
+}
+
 /** @name PhantomTypeUpDataStructs */
-export interface PhantomTypeUpDataStructs extends Vec<ITuple<[UpDataStructsTokenData, UpDataStructsRpcCollection, UpDataStructsRmrkCollectionInfo, UpDataStructsRmrkNftInfo, UpDataStructsRmrkResourceInfo, UpDataStructsRmrkPropertyInfo, UpDataStructsRmrkBaseInfo, UpDataStructsRmrkPartType, UpDataStructsRmrkTheme, UpDataStructsRmrkNftChild]>> {}
+export interface PhantomTypeUpDataStructs extends Vec<ITuple<[UpDataStructsTokenData, UpDataStructsRpcCollection, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftNftInfo, RmrkTraitsResourceResourceInfo, RmrkTraitsPropertyPropertyInfo, RmrkTraitsBaseBaseInfo, RmrkTraitsPartPartType, RmrkTraitsTheme, RmrkTraitsNftNftChild]>> {}
 
 /** @name PolkadotCorePrimitivesInboundDownwardMessage */
 export interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {
@@ -1653,6 +2046,151 @@
   readonly type: 'Present';
 }
 
+/** @name RmrkTraitsBaseBaseInfo */
+export interface RmrkTraitsBaseBaseInfo extends Struct {
+  readonly issuer: AccountId32;
+  readonly baseType: Bytes;
+  readonly symbol: Bytes;
+}
+
+/** @name RmrkTraitsCollectionCollectionInfo */
+export interface RmrkTraitsCollectionCollectionInfo extends Struct {
+  readonly issuer: AccountId32;
+  readonly metadata: Bytes;
+  readonly max: Option<u32>;
+  readonly symbol: Bytes;
+  readonly nftsCount: u32;
+}
+
+/** @name RmrkTraitsNftAccountIdOrCollectionNftTuple */
+export interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {
+  readonly isAccountId: boolean;
+  readonly asAccountId: AccountId32;
+  readonly isCollectionAndNftTuple: boolean;
+  readonly asCollectionAndNftTuple: ITuple<[u32, u32]>;
+  readonly type: 'AccountId' | 'CollectionAndNftTuple';
+}
+
+/** @name RmrkTraitsNftNftChild */
+export interface RmrkTraitsNftNftChild extends Struct {
+  readonly collectionId: u32;
+  readonly nftId: u32;
+}
+
+/** @name RmrkTraitsNftNftInfo */
+export interface RmrkTraitsNftNftInfo extends Struct {
+  readonly owner: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+  readonly royalty: Option<RmrkTraitsNftRoyaltyInfo>;
+  readonly metadata: Bytes;
+  readonly equipped: bool;
+  readonly pending: bool;
+}
+
+/** @name RmrkTraitsNftRoyaltyInfo */
+export interface RmrkTraitsNftRoyaltyInfo extends Struct {
+  readonly recipient: AccountId32;
+  readonly amount: Permill;
+}
+
+/** @name RmrkTraitsPartEquippableList */
+export interface RmrkTraitsPartEquippableList extends Enum {
+  readonly isAll: boolean;
+  readonly isEmpty: boolean;
+  readonly isCustom: boolean;
+  readonly asCustom: Vec<u32>;
+  readonly type: 'All' | 'Empty' | 'Custom';
+}
+
+/** @name RmrkTraitsPartFixedPart */
+export interface RmrkTraitsPartFixedPart extends Struct {
+  readonly id: u32;
+  readonly z: u32;
+  readonly src: Bytes;
+}
+
+/** @name RmrkTraitsPartPartType */
+export interface RmrkTraitsPartPartType extends Enum {
+  readonly isFixedPart: boolean;
+  readonly asFixedPart: RmrkTraitsPartFixedPart;
+  readonly isSlotPart: boolean;
+  readonly asSlotPart: RmrkTraitsPartSlotPart;
+  readonly type: 'FixedPart' | 'SlotPart';
+}
+
+/** @name RmrkTraitsPartSlotPart */
+export interface RmrkTraitsPartSlotPart extends Struct {
+  readonly id: u32;
+  readonly equippable: RmrkTraitsPartEquippableList;
+  readonly src: Bytes;
+  readonly z: u32;
+}
+
+/** @name RmrkTraitsPropertyPropertyInfo */
+export interface RmrkTraitsPropertyPropertyInfo extends Struct {
+  readonly key: Bytes;
+  readonly value: Bytes;
+}
+
+/** @name RmrkTraitsResourceBasicResource */
+export interface RmrkTraitsResourceBasicResource extends Struct {
+  readonly src: Option<Bytes>;
+  readonly metadata: Option<Bytes>;
+  readonly license: Option<Bytes>;
+  readonly thumb: Option<Bytes>;
+}
+
+/** @name RmrkTraitsResourceComposableResource */
+export interface RmrkTraitsResourceComposableResource extends Struct {
+  readonly parts: Vec<u32>;
+  readonly base: u32;
+  readonly src: Option<Bytes>;
+  readonly metadata: Option<Bytes>;
+  readonly license: Option<Bytes>;
+  readonly thumb: Option<Bytes>;
+}
+
+/** @name RmrkTraitsResourceResourceInfo */
+export interface RmrkTraitsResourceResourceInfo extends Struct {
+  readonly id: u32;
+  readonly resource: RmrkTraitsResourceResourceTypes;
+  readonly pending: bool;
+  readonly pendingRemoval: bool;
+}
+
+/** @name RmrkTraitsResourceResourceTypes */
+export interface RmrkTraitsResourceResourceTypes extends Enum {
+  readonly isBasic: boolean;
+  readonly asBasic: RmrkTraitsResourceBasicResource;
+  readonly isComposable: boolean;
+  readonly asComposable: RmrkTraitsResourceComposableResource;
+  readonly isSlot: boolean;
+  readonly asSlot: RmrkTraitsResourceSlotResource;
+  readonly type: 'Basic' | 'Composable' | 'Slot';
+}
+
+/** @name RmrkTraitsResourceSlotResource */
+export interface RmrkTraitsResourceSlotResource extends Struct {
+  readonly base: u32;
+  readonly src: Option<Bytes>;
+  readonly metadata: Option<Bytes>;
+  readonly slot: u32;
+  readonly license: Option<Bytes>;
+  readonly thumb: Option<Bytes>;
+}
+
+/** @name RmrkTraitsTheme */
+export interface RmrkTraitsTheme extends Struct {
+  readonly name: Bytes;
+  readonly properties: Vec<RmrkTraitsThemeThemeProperty>;
+  readonly inherit: bool;
+}
+
+/** @name RmrkTraitsThemeThemeProperty */
+export interface RmrkTraitsThemeThemeProperty extends Struct {
+  readonly key: Bytes;
+  readonly value: Bytes;
+}
+
 /** @name SpCoreEcdsaSignature */
 export interface SpCoreEcdsaSignature extends U8aFixed {}
 
@@ -1662,6 +2200,9 @@
 /** @name SpCoreSr25519Signature */
 export interface SpCoreSr25519Signature extends U8aFixed {}
 
+/** @name SpCoreVoid */
+export interface SpCoreVoid extends Null {}
+
 /** @name SpRuntimeArithmeticError */
 export interface SpRuntimeArithmeticError extends Enum {
   readonly isUnderflow: boolean;
@@ -1778,6 +2319,7 @@
   readonly sponsorship: UpDataStructsSponsorshipState;
   readonly limits: UpDataStructsCollectionLimits;
   readonly permissions: UpDataStructsCollectionPermissions;
+  readonly externalCollection: bool;
 }
 
 /** @name UpDataStructsCollectionLimits */
@@ -1921,153 +2463,8 @@
   readonly mutable: bool;
   readonly collectionAdmin: bool;
   readonly tokenOwner: bool;
-}
-
-/** @name UpDataStructsRmrkAccountIdOrCollectionNftTuple */
-export interface UpDataStructsRmrkAccountIdOrCollectionNftTuple extends Enum {
-  readonly isAccountId: boolean;
-  readonly asAccountId: AccountId32;
-  readonly isCollectionAndNftTuple: boolean;
-  readonly asCollectionAndNftTuple: ITuple<[u32, u32]>;
-  readonly type: 'AccountId' | 'CollectionAndNftTuple';
-}
-
-/** @name UpDataStructsRmrkBaseInfo */
-export interface UpDataStructsRmrkBaseInfo extends Struct {
-  readonly issuer: AccountId32;
-  readonly baseType: Bytes;
-  readonly symbol: Bytes;
-}
-
-/** @name UpDataStructsRmrkBasicResource */
-export interface UpDataStructsRmrkBasicResource extends Struct {
-  readonly src: Option<Bytes>;
-  readonly metadata: Option<Bytes>;
-  readonly license: Option<Bytes>;
-  readonly thumb: Option<Bytes>;
-}
-
-/** @name UpDataStructsRmrkCollectionInfo */
-export interface UpDataStructsRmrkCollectionInfo extends Struct {
-  readonly issuer: AccountId32;
-  readonly metadata: Bytes;
-  readonly max: Option<u32>;
-  readonly symbol: Bytes;
-  readonly nftsCount: u32;
-}
-
-/** @name UpDataStructsRmrkComposableResource */
-export interface UpDataStructsRmrkComposableResource extends Struct {
-  readonly parts: Vec<u32>;
-  readonly base: u32;
-  readonly src: Option<Bytes>;
-  readonly metadata: Option<Bytes>;
-  readonly license: Option<Bytes>;
-  readonly thumb: Option<Bytes>;
-}
-
-/** @name UpDataStructsRmrkEquippableList */
-export interface UpDataStructsRmrkEquippableList extends Enum {
-  readonly isAll: boolean;
-  readonly isEmpty: boolean;
-  readonly isCustom: boolean;
-  readonly asCustom: Vec<u32>;
-  readonly type: 'All' | 'Empty' | 'Custom';
-}
-
-/** @name UpDataStructsRmrkFixedPart */
-export interface UpDataStructsRmrkFixedPart extends Struct {
-  readonly id: u32;
-  readonly z: u32;
-  readonly src: Bytes;
 }
 
-/** @name UpDataStructsRmrkNftChild */
-export interface UpDataStructsRmrkNftChild extends Struct {
-  readonly collectionId: u32;
-  readonly nftId: u32;
-}
-
-/** @name UpDataStructsRmrkNftInfo */
-export interface UpDataStructsRmrkNftInfo extends Struct {
-  readonly owner: UpDataStructsRmrkAccountIdOrCollectionNftTuple;
-  readonly royalty: Option<UpDataStructsRmrkRoyaltyInfo>;
-  readonly metadata: Bytes;
-  readonly equipped: bool;
-  readonly pending: bool;
-}
-
-/** @name UpDataStructsRmrkPartType */
-export interface UpDataStructsRmrkPartType extends Enum {
-  readonly isFixedPart: boolean;
-  readonly asFixedPart: UpDataStructsRmrkFixedPart;
-  readonly isSlotPart: boolean;
-  readonly asSlotPart: UpDataStructsRmrkSlotPart;
-  readonly type: 'FixedPart' | 'SlotPart';
-}
-
-/** @name UpDataStructsRmrkPropertyInfo */
-export interface UpDataStructsRmrkPropertyInfo extends Struct {
-  readonly key: Bytes;
-  readonly value: Bytes;
-}
-
-/** @name UpDataStructsRmrkResourceInfo */
-export interface UpDataStructsRmrkResourceInfo extends Struct {
-  readonly id: Bytes;
-  readonly resource: UpDataStructsRmrkResourceTypes;
-  readonly pending: bool;
-  readonly pendingRemoval: bool;
-}
-
-/** @name UpDataStructsRmrkResourceTypes */
-export interface UpDataStructsRmrkResourceTypes extends Enum {
-  readonly isBasic: boolean;
-  readonly asBasic: UpDataStructsRmrkBasicResource;
-  readonly isComposable: boolean;
-  readonly asComposable: UpDataStructsRmrkComposableResource;
-  readonly isSlot: boolean;
-  readonly asSlot: UpDataStructsRmrkSlotResource;
-  readonly type: 'Basic' | 'Composable' | 'Slot';
-}
-
-/** @name UpDataStructsRmrkRoyaltyInfo */
-export interface UpDataStructsRmrkRoyaltyInfo extends Struct {
-  readonly recipient: AccountId32;
-  readonly amount: Permill;
-}
-
-/** @name UpDataStructsRmrkSlotPart */
-export interface UpDataStructsRmrkSlotPart extends Struct {
-  readonly id: u32;
-  readonly equippable: UpDataStructsRmrkEquippableList;
-  readonly src: Bytes;
-  readonly z: u32;
-}
-
-/** @name UpDataStructsRmrkSlotResource */
-export interface UpDataStructsRmrkSlotResource extends Struct {
-  readonly base: u32;
-  readonly src: Option<Bytes>;
-  readonly metadata: Option<Bytes>;
-  readonly slot: u32;
-  readonly license: Option<Bytes>;
-  readonly thumb: Option<Bytes>;
-}
-
-/** @name UpDataStructsRmrkTheme */
-export interface UpDataStructsRmrkTheme extends Struct {
-  readonly name: Bytes;
-  readonly properties: Vec<UpDataStructsRmrkThemeProperty>;
-  readonly inherit: bool;
-}
-
-/** @name UpDataStructsRmrkThemeProperty */
-export interface UpDataStructsRmrkThemeProperty extends Struct {
-  readonly key: Bytes;
-  readonly value: Bytes;
-}
-
 /** @name UpDataStructsRpcCollection */
 export interface UpDataStructsRpcCollection extends Struct {
   readonly owner: AccountId32;
@@ -2080,6 +2477,7 @@
   readonly permissions: UpDataStructsCollectionPermissions;
   readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
   readonly properties: Vec<UpDataStructsProperty>;
+  readonly readOnly: bool;
 }
 
 /** @name UpDataStructsSponsoringRateLimit */
modifiedtests/src/interfaces/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/definitions.ts
+++ b/tests/src/interfaces/definitions.ts
@@ -15,5 +15,5 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 export {default as unique} from './unique/definitions';
-// TODO free RMRK! export {default as rmrk} from './rmrk/definitions';
+export {default as rmrk} from './rmrk/definitions';
 export {default as default} from './default/definitions';
\ No newline at end of file
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -154,17 +154,17 @@
    * Lookup48: pallet_balances::ReserveData<ReserveIdentifier, Balance>
    **/
   PalletBalancesReserveData: {
-    id: '[u8;8]',
+    id: '[u8;16]',
     amount: 'u128'
   },
   /**
-   * Lookup50: pallet_balances::Releases
+   * Lookup51: pallet_balances::Releases
    **/
   PalletBalancesReleases: {
     _enum: ['V1_0_0', 'V2_0_0']
   },
   /**
-   * Lookup51: pallet_balances::pallet::Call<T, I>
+   * Lookup52: pallet_balances::pallet::Call<T, I>
    **/
   PalletBalancesCall: {
     _enum: {
@@ -197,7 +197,7 @@
     }
   },
   /**
-   * Lookup57: pallet_balances::pallet::Event<T, I>
+   * Lookup58: pallet_balances::pallet::Event<T, I>
    **/
   PalletBalancesEvent: {
     _enum: {
@@ -248,19 +248,19 @@
     }
   },
   /**
-   * Lookup58: frame_support::traits::tokens::misc::BalanceStatus
+   * Lookup59: frame_support::traits::tokens::misc::BalanceStatus
    **/
   FrameSupportTokensMiscBalanceStatus: {
     _enum: ['Free', 'Reserved']
   },
   /**
-   * Lookup59: pallet_balances::pallet::Error<T, I>
+   * Lookup60: pallet_balances::pallet::Error<T, I>
    **/
   PalletBalancesError: {
     _enum: ['VestingBalance', 'LiquidityRestrictions', 'InsufficientBalance', 'ExistentialDeposit', 'KeepAlive', 'ExistingVestingSchedule', 'DeadAccount', 'TooManyReserves']
   },
   /**
-   * Lookup62: pallet_timestamp::pallet::Call<T>
+   * Lookup63: pallet_timestamp::pallet::Call<T>
    **/
   PalletTimestampCall: {
     _enum: {
@@ -270,13 +270,13 @@
     }
   },
   /**
-   * Lookup65: pallet_transaction_payment::Releases
+   * Lookup66: pallet_transaction_payment::Releases
    **/
   PalletTransactionPaymentReleases: {
     _enum: ['V1Ancient', 'V2']
   },
   /**
-   * Lookup67: frame_support::weights::WeightToFeeCoefficient<Balance>
+   * Lookup68: frame_support::weights::WeightToFeeCoefficient<Balance>
    **/
   FrameSupportWeightsWeightToFeeCoefficient: {
     coeffInteger: 'u128',
@@ -285,7 +285,7 @@
     degree: 'u8'
   },
   /**
-   * Lookup69: pallet_treasury::Proposal<sp_core::crypto::AccountId32, Balance>
+   * Lookup70: pallet_treasury::Proposal<sp_core::crypto::AccountId32, Balance>
    **/
   PalletTreasuryProposal: {
     proposer: 'AccountId32',
@@ -294,7 +294,7 @@
     bond: 'u128'
   },
   /**
-   * Lookup72: pallet_treasury::pallet::Call<T, I>
+   * Lookup73: pallet_treasury::pallet::Call<T, I>
    **/
   PalletTreasuryCall: {
     _enum: {
@@ -306,12 +306,15 @@
         proposalId: 'Compact<u32>',
       },
       approve_proposal: {
+        proposalId: 'Compact<u32>',
+      },
+      remove_approval: {
         proposalId: 'Compact<u32>'
       }
     }
   },
   /**
-   * Lookup74: pallet_treasury::pallet::Event<T, I>
+   * Lookup75: pallet_treasury::pallet::Event<T, I>
    **/
   PalletTreasuryEvent: {
     _enum: {
@@ -342,17 +345,17 @@
     }
   },
   /**
-   * Lookup77: frame_support::PalletId
+   * Lookup78: frame_support::PalletId
    **/
   FrameSupportPalletId: '[u8;8]',
   /**
-   * Lookup78: pallet_treasury::pallet::Error<T, I>
+   * Lookup79: pallet_treasury::pallet::Error<T, I>
    **/
   PalletTreasuryError: {
-    _enum: ['InsufficientProposersBalance', 'InvalidIndex', 'TooManyApprovals']
+    _enum: ['InsufficientProposersBalance', 'InvalidIndex', 'TooManyApprovals', 'ProposalNotApproved']
   },
   /**
-   * Lookup79: pallet_sudo::pallet::Call<T>
+   * Lookup80: pallet_sudo::pallet::Call<T>
    **/
   PalletSudoCall: {
     _enum: {
@@ -376,7 +379,7 @@
     }
   },
   /**
-   * Lookup81: frame_system::pallet::Call<T>
+   * Lookup82: frame_system::pallet::Call<T>
    **/
   FrameSystemCall: {
     _enum: {
@@ -414,7 +417,7 @@
     }
   },
   /**
-   * Lookup84: orml_vesting::module::Call<T>
+   * Lookup85: orml_vesting::module::Call<T>
    **/
   OrmlVestingModuleCall: {
     _enum: {
@@ -433,7 +436,7 @@
     }
   },
   /**
-   * Lookup85: orml_vesting::VestingSchedule<BlockNumber, Balance>
+   * Lookup86: orml_vesting::VestingSchedule<BlockNumber, Balance>
    **/
   OrmlVestingVestingSchedule: {
     start: 'u32',
@@ -442,7 +445,7 @@
     perPeriod: 'Compact<u128>'
   },
   /**
-   * Lookup87: cumulus_pallet_xcmp_queue::pallet::Call<T>
+   * Lookup88: cumulus_pallet_xcmp_queue::pallet::Call<T>
    **/
   CumulusPalletXcmpQueueCall: {
     _enum: {
@@ -491,7 +494,7 @@
     }
   },
   /**
-   * Lookup88: pallet_xcm::pallet::Call<T>
+   * Lookup89: pallet_xcm::pallet::Call<T>
    **/
   PalletXcmCall: {
     _enum: {
@@ -545,7 +548,7 @@
     }
   },
   /**
-   * Lookup89: xcm::VersionedMultiLocation
+   * Lookup90: xcm::VersionedMultiLocation
    **/
   XcmVersionedMultiLocation: {
     _enum: {
@@ -554,7 +557,7 @@
     }
   },
   /**
-   * Lookup90: xcm::v0::multi_location::MultiLocation
+   * Lookup91: xcm::v0::multi_location::MultiLocation
    **/
   XcmV0MultiLocation: {
     _enum: {
@@ -570,7 +573,7 @@
     }
   },
   /**
-   * Lookup91: xcm::v0::junction::Junction
+   * Lookup92: xcm::v0::junction::Junction
    **/
   XcmV0Junction: {
     _enum: {
@@ -599,7 +602,7 @@
     }
   },
   /**
-   * Lookup92: xcm::v0::junction::NetworkId
+   * Lookup93: xcm::v0::junction::NetworkId
    **/
   XcmV0JunctionNetworkId: {
     _enum: {
@@ -610,7 +613,7 @@
     }
   },
   /**
-   * Lookup93: xcm::v0::junction::BodyId
+   * Lookup94: xcm::v0::junction::BodyId
    **/
   XcmV0JunctionBodyId: {
     _enum: {
@@ -624,7 +627,7 @@
     }
   },
   /**
-   * Lookup94: xcm::v0::junction::BodyPart
+   * Lookup95: xcm::v0::junction::BodyPart
    **/
   XcmV0JunctionBodyPart: {
     _enum: {
@@ -647,14 +650,14 @@
     }
   },
   /**
-   * Lookup95: xcm::v1::multilocation::MultiLocation
+   * Lookup96: xcm::v1::multilocation::MultiLocation
    **/
   XcmV1MultiLocation: {
     parents: 'u8',
     interior: 'XcmV1MultilocationJunctions'
   },
   /**
-   * Lookup96: xcm::v1::multilocation::Junctions
+   * Lookup97: xcm::v1::multilocation::Junctions
    **/
   XcmV1MultilocationJunctions: {
     _enum: {
@@ -670,7 +673,7 @@
     }
   },
   /**
-   * Lookup97: xcm::v1::junction::Junction
+   * Lookup98: xcm::v1::junction::Junction
    **/
   XcmV1Junction: {
     _enum: {
@@ -698,7 +701,7 @@
     }
   },
   /**
-   * Lookup98: xcm::VersionedXcm<Call>
+   * Lookup99: xcm::VersionedXcm<Call>
    **/
   XcmVersionedXcm: {
     _enum: {
@@ -708,7 +711,7 @@
     }
   },
   /**
-   * Lookup99: xcm::v0::Xcm<Call>
+   * Lookup100: xcm::v0::Xcm<Call>
    **/
   XcmV0Xcm: {
     _enum: {
@@ -762,7 +765,7 @@
     }
   },
   /**
-   * Lookup101: xcm::v0::multi_asset::MultiAsset
+   * Lookup102: xcm::v0::multi_asset::MultiAsset
    **/
   XcmV0MultiAsset: {
     _enum: {
@@ -801,7 +804,7 @@
     }
   },
   /**
-   * Lookup102: xcm::v1::multiasset::AssetInstance
+   * Lookup103: xcm::v1::multiasset::AssetInstance
    **/
   XcmV1MultiassetAssetInstance: {
     _enum: {
@@ -1520,16 +1523,246 @@
     users: 'BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>'
   },
   /**
-   * Lookup204: pallet_template_transaction_payment::Call<T>
+   * Lookup204: pallet_unq_scheduler::pallet::Call<T>
+   **/
+  PalletUnqSchedulerCall: {
+    _enum: {
+      schedule_named: {
+        id: '[u8;16]',
+        when: 'u32',
+        maybePeriodic: 'Option<(u32,u32)>',
+        priority: 'u8',
+        call: 'FrameSupportScheduleMaybeHashed',
+      },
+      cancel_named: {
+        id: '[u8;16]',
+      },
+      schedule_named_after: {
+        id: '[u8;16]',
+        after: 'u32',
+        maybePeriodic: 'Option<(u32,u32)>',
+        priority: 'u8',
+        call: 'FrameSupportScheduleMaybeHashed'
+      }
+    }
+  },
+  /**
+   * Lookup206: frame_support::traits::schedule::MaybeHashed<opal_runtime::Call, primitive_types::H256>
+   **/
+  FrameSupportScheduleMaybeHashed: {
+    _enum: {
+      Value: 'Call',
+      Hash: 'H256'
+    }
+  },
+  /**
+   * Lookup207: pallet_template_transaction_payment::Call<T>
    **/
   PalletTemplateTransactionPaymentCall: 'Null',
   /**
-   * Lookup205: pallet_structure::pallet::Call<T>
+   * Lookup208: pallet_structure::pallet::Call<T>
    **/
   PalletStructureCall: 'Null',
   /**
-   * Lookup206: pallet_evm::pallet::Call<T>
+   * Lookup209: pallet_rmrk_core::pallet::Call<T>
+   **/
+  PalletRmrkCoreCall: {
+    _enum: {
+      create_collection: {
+        metadata: 'Bytes',
+        max: 'Option<u32>',
+        symbol: 'Bytes',
+      },
+      destroy_collection: {
+        collectionId: 'u32',
+      },
+      change_collection_issuer: {
+        collectionId: 'u32',
+        newIssuer: 'MultiAddress',
+      },
+      lock_collection: {
+        collectionId: 'u32',
+      },
+      mint_nft: {
+        owner: 'AccountId32',
+        collectionId: 'u32',
+        recipient: 'Option<AccountId32>',
+        royaltyAmount: 'Option<Permill>',
+        metadata: 'Bytes',
+        transferable: 'bool',
+      },
+      burn_nft: {
+        collectionId: 'u32',
+        nftId: 'u32',
+      },
+      send: {
+        rmrkCollectionId: 'u32',
+        rmrkNftId: 'u32',
+        newOwner: 'RmrkTraitsNftAccountIdOrCollectionNftTuple',
+      },
+      accept_nft: {
+        rmrkCollectionId: 'u32',
+        rmrkNftId: 'u32',
+        newOwner: 'RmrkTraitsNftAccountIdOrCollectionNftTuple',
+      },
+      reject_nft: {
+        rmrkCollectionId: 'u32',
+        rmrkNftId: 'u32',
+      },
+      accept_resource: {
+        rmrkCollectionId: 'u32',
+        rmrkNftId: 'u32',
+        rmrkResourceId: 'u32',
+      },
+      accept_resource_removal: {
+        rmrkCollectionId: 'u32',
+        rmrkNftId: 'u32',
+        rmrkResourceId: 'u32',
+      },
+      set_property: {
+        rmrkCollectionId: 'Compact<u32>',
+        maybeNftId: 'Option<u32>',
+        key: 'Bytes',
+        value: 'Bytes',
+      },
+      set_priority: {
+        rmrkCollectionId: 'u32',
+        rmrkNftId: 'u32',
+        priorities: 'Vec<u32>',
+      },
+      add_basic_resource: {
+        rmrkCollectionId: 'u32',
+        nftId: 'u32',
+        resource: 'RmrkTraitsResourceBasicResource',
+      },
+      add_composable_resource: {
+        rmrkCollectionId: 'u32',
+        nftId: 'u32',
+        resourceId: 'Bytes',
+        resource: 'RmrkTraitsResourceComposableResource',
+      },
+      add_slot_resource: {
+        rmrkCollectionId: 'u32',
+        nftId: 'u32',
+        resource: 'RmrkTraitsResourceSlotResource',
+      },
+      remove_resource: {
+        rmrkCollectionId: 'u32',
+        nftId: 'u32',
+        resourceId: 'u32'
+      }
+    }
+  },
+  /**
+   * Lookup213: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
+   **/
+  RmrkTraitsNftAccountIdOrCollectionNftTuple: {
+    _enum: {
+      AccountId: 'AccountId32',
+      CollectionAndNftTuple: '(u32,u32)'
+    }
+  },
+  /**
+   * Lookup217: rmrk_traits::resource::BasicResource<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsResourceBasicResource: {
+    src: 'Option<Bytes>',
+    metadata: 'Option<Bytes>',
+    license: 'Option<Bytes>',
+    thumb: 'Option<Bytes>'
+  },
+  /**
+   * Lookup220: rmrk_traits::resource::ComposableResource<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsResourceComposableResource: {
+    parts: 'Vec<u32>',
+    base: 'u32',
+    src: 'Option<Bytes>',
+    metadata: 'Option<Bytes>',
+    license: 'Option<Bytes>',
+    thumb: 'Option<Bytes>'
+  },
+  /**
+   * Lookup222: rmrk_traits::resource::SlotResource<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsResourceSlotResource: {
+    base: 'u32',
+    src: 'Option<Bytes>',
+    metadata: 'Option<Bytes>',
+    slot: 'u32',
+    license: 'Option<Bytes>',
+    thumb: 'Option<Bytes>'
+  },
+  /**
+   * Lookup223: pallet_rmrk_equip::pallet::Call<T>
+   **/
+  PalletRmrkEquipCall: {
+    _enum: {
+      create_base: {
+        baseType: 'Bytes',
+        symbol: 'Bytes',
+        parts: 'Vec<RmrkTraitsPartPartType>',
+      },
+      theme_add: {
+        baseId: 'u32',
+        theme: 'RmrkTraitsTheme'
+      }
+    }
+  },
+  /**
+   * Lookup225: rmrk_traits::part::PartType<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
+  RmrkTraitsPartPartType: {
+    _enum: {
+      FixedPart: 'RmrkTraitsPartFixedPart',
+      SlotPart: 'RmrkTraitsPartSlotPart'
+    }
+  },
+  /**
+   * Lookup227: rmrk_traits::part::FixedPart<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsPartFixedPart: {
+    id: 'u32',
+    z: 'u32',
+    src: 'Bytes'
+  },
+  /**
+   * Lookup228: rmrk_traits::part::SlotPart<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsPartSlotPart: {
+    id: 'u32',
+    equippable: 'RmrkTraitsPartEquippableList',
+    src: 'Bytes',
+    z: 'u32'
+  },
+  /**
+   * Lookup229: rmrk_traits::part::EquippableList<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsPartEquippableList: {
+    _enum: {
+      All: 'Null',
+      Empty: 'Null',
+      Custom: 'Vec<u32>'
+    }
+  },
+  /**
+   * Lookup231: rmrk_traits::theme::Theme<frame_support::storage::bounded_vec::BoundedVec<T, S>, PropertyList>
+   **/
+  RmrkTraitsTheme: {
+    name: 'Bytes',
+    properties: 'Vec<RmrkTraitsThemeThemeProperty>',
+    inherit: 'bool'
+  },
+  /**
+   * Lookup233: rmrk_traits::theme::ThemeProperty<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   **/
+  RmrkTraitsThemeThemeProperty: {
+    key: 'Bytes',
+    value: 'Bytes'
+  },
+  /**
+   * Lookup234: pallet_evm::pallet::Call<T>
+   **/
   PalletEvmCall: {
     _enum: {
       withdraw: {
@@ -1571,7 +1804,7 @@
     }
   },
   /**
-   * Lookup212: pallet_ethereum::pallet::Call<T>
+   * Lookup240: pallet_ethereum::pallet::Call<T>
    **/
   PalletEthereumCall: {
     _enum: {
@@ -1581,7 +1814,7 @@
     }
   },
   /**
-   * Lookup213: ethereum::transaction::TransactionV2
+   * Lookup241: ethereum::transaction::TransactionV2
    **/
   EthereumTransactionTransactionV2: {
     _enum: {
@@ -1591,7 +1824,7 @@
     }
   },
   /**
-   * Lookup214: ethereum::transaction::LegacyTransaction
+   * Lookup242: ethereum::transaction::LegacyTransaction
    **/
   EthereumTransactionLegacyTransaction: {
     nonce: 'U256',
@@ -1603,7 +1836,7 @@
     signature: 'EthereumTransactionTransactionSignature'
   },
   /**
-   * Lookup215: ethereum::transaction::TransactionAction
+   * Lookup243: ethereum::transaction::TransactionAction
    **/
   EthereumTransactionTransactionAction: {
     _enum: {
@@ -1612,7 +1845,7 @@
     }
   },
   /**
-   * Lookup216: ethereum::transaction::TransactionSignature
+   * Lookup244: ethereum::transaction::TransactionSignature
    **/
   EthereumTransactionTransactionSignature: {
     v: 'u64',
@@ -1620,7 +1853,7 @@
     s: 'H256'
   },
   /**
-   * Lookup218: ethereum::transaction::EIP2930Transaction
+   * Lookup246: ethereum::transaction::EIP2930Transaction
    **/
   EthereumTransactionEip2930Transaction: {
     chainId: 'u64',
@@ -1636,14 +1869,14 @@
     s: 'H256'
   },
   /**
-   * Lookup220: ethereum::transaction::AccessListItem
+   * Lookup248: ethereum::transaction::AccessListItem
    **/
   EthereumTransactionAccessListItem: {
     address: 'H160',
     storageKeys: 'Vec<H256>'
   },
   /**
-   * Lookup221: ethereum::transaction::EIP1559Transaction
+   * Lookup249: ethereum::transaction::EIP1559Transaction
    **/
   EthereumTransactionEip1559Transaction: {
     chainId: 'u64',
@@ -1660,7 +1893,7 @@
     s: 'H256'
   },
   /**
-   * Lookup222: pallet_evm_migration::pallet::Call<T>
+   * Lookup250: pallet_evm_migration::pallet::Call<T>
    **/
   PalletEvmMigrationCall: {
     _enum: {
@@ -1678,7 +1911,7 @@
     }
   },
   /**
-   * Lookup225: pallet_sudo::pallet::Event<T>
+   * Lookup253: pallet_sudo::pallet::Event<T>
    **/
   PalletSudoEvent: {
     _enum: {
@@ -1694,7 +1927,7 @@
     }
   },
   /**
-   * Lookup227: sp_runtime::DispatchError
+   * Lookup255: sp_runtime::DispatchError
    **/
   SpRuntimeDispatchError: {
     _enum: {
@@ -1711,38 +1944,38 @@
     }
   },
   /**
-   * Lookup228: sp_runtime::ModuleError
+   * Lookup256: sp_runtime::ModuleError
    **/
   SpRuntimeModuleError: {
     index: 'u8',
     error: '[u8;4]'
   },
   /**
-   * Lookup229: sp_runtime::TokenError
+   * Lookup257: sp_runtime::TokenError
    **/
   SpRuntimeTokenError: {
     _enum: ['NoFunds', 'WouldDie', 'BelowMinimum', 'CannotCreate', 'UnknownAsset', 'Frozen', 'Unsupported']
   },
   /**
-   * Lookup230: sp_runtime::ArithmeticError
+   * Lookup258: sp_runtime::ArithmeticError
    **/
   SpRuntimeArithmeticError: {
     _enum: ['Underflow', 'Overflow', 'DivisionByZero']
   },
   /**
-   * Lookup231: sp_runtime::TransactionalError
+   * Lookup259: sp_runtime::TransactionalError
    **/
   SpRuntimeTransactionalError: {
     _enum: ['LimitReached', 'NoLayer']
   },
   /**
-   * Lookup232: pallet_sudo::pallet::Error<T>
+   * Lookup260: pallet_sudo::pallet::Error<T>
    **/
   PalletSudoError: {
     _enum: ['RequireSudo']
   },
   /**
-   * Lookup233: frame_system::AccountInfo<Index, pallet_balances::AccountData<Balance>>
+   * Lookup261: frame_system::AccountInfo<Index, pallet_balances::AccountData<Balance>>
    **/
   FrameSystemAccountInfo: {
     nonce: 'u32',
@@ -1752,7 +1985,7 @@
     data: 'PalletBalancesAccountData'
   },
   /**
-   * Lookup234: frame_support::weights::PerDispatchClass<T>
+   * Lookup262: frame_support::weights::PerDispatchClass<T>
    **/
   FrameSupportWeightsPerDispatchClassU64: {
     normal: 'u64',
@@ -1760,13 +1993,13 @@
     mandatory: 'u64'
   },
   /**
-   * Lookup235: sp_runtime::generic::digest::Digest
+   * Lookup263: sp_runtime::generic::digest::Digest
    **/
   SpRuntimeDigest: {
     logs: 'Vec<SpRuntimeDigestDigestItem>'
   },
   /**
-   * Lookup237: sp_runtime::generic::digest::DigestItem
+   * Lookup265: sp_runtime::generic::digest::DigestItem
    **/
   SpRuntimeDigestDigestItem: {
     _enum: {
@@ -1782,7 +2015,7 @@
     }
   },
   /**
-   * Lookup239: frame_system::EventRecord<opal_runtime::Event, primitive_types::H256>
+   * Lookup267: frame_system::EventRecord<opal_runtime::Event, primitive_types::H256>
    **/
   FrameSystemEventRecord: {
     phase: 'FrameSystemPhase',
@@ -1790,7 +2023,7 @@
     topics: 'Vec<H256>'
   },
   /**
-   * Lookup241: frame_system::pallet::Event<T>
+   * Lookup269: frame_system::pallet::Event<T>
    **/
   FrameSystemEvent: {
     _enum: {
@@ -1818,7 +2051,7 @@
     }
   },
   /**
-   * Lookup242: frame_support::weights::DispatchInfo
+   * Lookup270: frame_support::weights::DispatchInfo
    **/
   FrameSupportWeightsDispatchInfo: {
     weight: 'u64',
@@ -1826,19 +2059,19 @@
     paysFee: 'FrameSupportWeightsPays'
   },
   /**
-   * Lookup243: frame_support::weights::DispatchClass
+   * Lookup271: frame_support::weights::DispatchClass
    **/
   FrameSupportWeightsDispatchClass: {
     _enum: ['Normal', 'Operational', 'Mandatory']
   },
   /**
-   * Lookup244: frame_support::weights::Pays
+   * Lookup272: frame_support::weights::Pays
    **/
   FrameSupportWeightsPays: {
     _enum: ['Yes', 'No']
   },
   /**
-   * Lookup245: orml_vesting::module::Event<T>
+   * Lookup273: orml_vesting::module::Event<T>
    **/
   OrmlVestingModuleEvent: {
     _enum: {
@@ -1857,7 +2090,7 @@
     }
   },
   /**
-   * Lookup246: cumulus_pallet_xcmp_queue::pallet::Event<T>
+   * Lookup274: cumulus_pallet_xcmp_queue::pallet::Event<T>
    **/
   CumulusPalletXcmpQueueEvent: {
     _enum: {
@@ -1872,7 +2105,7 @@
     }
   },
   /**
-   * Lookup247: pallet_xcm::pallet::Event<T>
+   * Lookup275: pallet_xcm::pallet::Event<T>
    **/
   PalletXcmEvent: {
     _enum: {
@@ -1895,7 +2128,7 @@
     }
   },
   /**
-   * Lookup248: xcm::v2::traits::Outcome
+   * Lookup276: xcm::v2::traits::Outcome
    **/
   XcmV2TraitsOutcome: {
     _enum: {
@@ -1905,7 +2138,7 @@
     }
   },
   /**
-   * Lookup250: cumulus_pallet_xcm::pallet::Event<T>
+   * Lookup278: cumulus_pallet_xcm::pallet::Event<T>
    **/
   CumulusPalletXcmEvent: {
     _enum: {
@@ -1915,7 +2148,7 @@
     }
   },
   /**
-   * Lookup251: cumulus_pallet_dmp_queue::pallet::Event<T>
+   * Lookup279: cumulus_pallet_dmp_queue::pallet::Event<T>
    **/
   CumulusPalletDmpQueueEvent: {
     _enum: {
@@ -1928,7 +2161,7 @@
     }
   },
   /**
-   * Lookup252: pallet_unique::RawEvent<sp_core::crypto::AccountId32, pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup280: pallet_unique::RawEvent<sp_core::crypto::AccountId32, pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   PalletUniqueRawEvent: {
     _enum: {
@@ -1945,8 +2178,39 @@
     }
   },
   /**
-   * Lookup253: pallet_common::pallet::Event<T>
+   * Lookup281: pallet_unq_scheduler::pallet::Event<T>
+   **/
+  PalletUnqSchedulerEvent: {
+    _enum: {
+      Scheduled: {
+        when: 'u32',
+        index: 'u32',
+      },
+      Canceled: {
+        when: 'u32',
+        index: 'u32',
+      },
+      Dispatched: {
+        task: '(u32,u32)',
+        id: 'Option<[u8;16]>',
+        result: 'Result<Null, SpRuntimeDispatchError>',
+      },
+      CallLookupFailed: {
+        task: '(u32,u32)',
+        id: 'Option<[u8;16]>',
+        error: 'FrameSupportScheduleLookupError'
+      }
+    }
+  },
+  /**
+   * Lookup283: frame_support::traits::schedule::LookupError
    **/
+  FrameSupportScheduleLookupError: {
+    _enum: ['Unknown', 'BadFormat']
+  },
+  /**
+   * Lookup284: pallet_common::pallet::Event<T>
+   **/
   PalletCommonEvent: {
     _enum: {
       CollectionCreated: '(u32,u8,AccountId32)',
@@ -1963,7 +2227,7 @@
     }
   },
   /**
-   * Lookup254: pallet_structure::pallet::Event<T>
+   * Lookup285: pallet_structure::pallet::Event<T>
    **/
   PalletStructureEvent: {
     _enum: {
@@ -1971,7 +2235,95 @@
     }
   },
   /**
-   * Lookup255: pallet_evm::pallet::Event<T>
+   * Lookup286: pallet_rmrk_core::pallet::Event<T>
+   **/
+  PalletRmrkCoreEvent: {
+    _enum: {
+      CollectionCreated: {
+        issuer: 'AccountId32',
+        collectionId: 'u32',
+      },
+      CollectionDestroyed: {
+        issuer: 'AccountId32',
+        collectionId: 'u32',
+      },
+      IssuerChanged: {
+        oldIssuer: 'AccountId32',
+        newIssuer: 'AccountId32',
+        collectionId: 'u32',
+      },
+      CollectionLocked: {
+        issuer: 'AccountId32',
+        collectionId: 'u32',
+      },
+      NftMinted: {
+        owner: 'AccountId32',
+        collectionId: 'u32',
+        nftId: 'u32',
+      },
+      NFTBurned: {
+        owner: 'AccountId32',
+        nftId: 'u32',
+      },
+      NFTSent: {
+        sender: 'AccountId32',
+        recipient: 'RmrkTraitsNftAccountIdOrCollectionNftTuple',
+        collectionId: 'u32',
+        nftId: 'u32',
+        approvalRequired: 'bool',
+      },
+      NFTAccepted: {
+        sender: 'AccountId32',
+        recipient: 'RmrkTraitsNftAccountIdOrCollectionNftTuple',
+        collectionId: 'u32',
+        nftId: 'u32',
+      },
+      NFTRejected: {
+        sender: 'AccountId32',
+        collectionId: 'u32',
+        nftId: 'u32',
+      },
+      PropertySet: {
+        collectionId: 'u32',
+        maybeNftId: 'Option<u32>',
+        key: 'Bytes',
+        value: 'Bytes',
+      },
+      ResourceAdded: {
+        nftId: 'u32',
+        resourceId: 'u32',
+      },
+      ResourceRemoval: {
+        nftId: 'u32',
+        resourceId: 'u32',
+      },
+      ResourceAccepted: {
+        nftId: 'u32',
+        resourceId: 'u32',
+      },
+      ResourceRemovalAccepted: {
+        nftId: 'u32',
+        resourceId: 'u32',
+      },
+      PrioritySet: {
+        collectionId: 'u32',
+        nftId: 'u32'
+      }
+    }
+  },
+  /**
+   * Lookup287: pallet_rmrk_equip::pallet::Event<T>
+   **/
+  PalletRmrkEquipEvent: {
+    _enum: {
+      BaseCreated: {
+        issuer: 'AccountId32',
+        baseId: 'u32'
+      }
+    }
+  },
+  /**
+   * Lookup288: pallet_evm::pallet::Event<T>
    **/
   PalletEvmEvent: {
     _enum: {
@@ -1985,7 +2337,7 @@
     }
   },
   /**
-   * Lookup256: ethereum::log::Log
+   * Lookup289: ethereum::log::Log
    **/
   EthereumLog: {
     address: 'H160',
@@ -1993,7 +2345,7 @@
     data: 'Bytes'
   },
   /**
-   * Lookup257: pallet_ethereum::pallet::Event
+   * Lookup290: pallet_ethereum::pallet::Event
    **/
   PalletEthereumEvent: {
     _enum: {
@@ -2001,7 +2353,7 @@
     }
   },
   /**
-   * Lookup258: evm_core::error::ExitReason
+   * Lookup291: evm_core::error::ExitReason
    **/
   EvmCoreErrorExitReason: {
     _enum: {
@@ -2012,13 +2364,13 @@
     }
   },
   /**
-   * Lookup259: evm_core::error::ExitSucceed
+   * Lookup292: evm_core::error::ExitSucceed
    **/
   EvmCoreErrorExitSucceed: {
     _enum: ['Stopped', 'Returned', 'Suicided']
   },
   /**
-   * Lookup260: evm_core::error::ExitError
+   * Lookup293: evm_core::error::ExitError
    **/
   EvmCoreErrorExitError: {
     _enum: {
@@ -2040,13 +2392,13 @@
     }
   },
   /**
-   * Lookup263: evm_core::error::ExitRevert
+   * Lookup296: evm_core::error::ExitRevert
    **/
   EvmCoreErrorExitRevert: {
     _enum: ['Reverted']
   },
   /**
-   * Lookup264: evm_core::error::ExitFatal
+   * Lookup297: evm_core::error::ExitFatal
    **/
   EvmCoreErrorExitFatal: {
     _enum: {
@@ -2057,7 +2409,7 @@
     }
   },
   /**
-   * Lookup265: frame_system::Phase
+   * Lookup298: frame_system::Phase
    **/
   FrameSystemPhase: {
     _enum: {
@@ -2067,14 +2419,14 @@
     }
   },
   /**
-   * Lookup267: frame_system::LastRuntimeUpgradeInfo
+   * Lookup300: frame_system::LastRuntimeUpgradeInfo
    **/
   FrameSystemLastRuntimeUpgradeInfo: {
     specVersion: 'Compact<u32>',
     specName: 'Text'
   },
   /**
-   * Lookup268: frame_system::limits::BlockWeights
+   * Lookup301: frame_system::limits::BlockWeights
    **/
   FrameSystemLimitsBlockWeights: {
     baseBlock: 'u64',
@@ -2082,7 +2434,7 @@
     perClass: 'FrameSupportWeightsPerDispatchClassWeightsPerClass'
   },
   /**
-   * Lookup269: frame_support::weights::PerDispatchClass<frame_system::limits::WeightsPerClass>
+   * Lookup302: frame_support::weights::PerDispatchClass<frame_system::limits::WeightsPerClass>
    **/
   FrameSupportWeightsPerDispatchClassWeightsPerClass: {
     normal: 'FrameSystemLimitsWeightsPerClass',
@@ -2090,7 +2442,7 @@
     mandatory: 'FrameSystemLimitsWeightsPerClass'
   },
   /**
-   * Lookup270: frame_system::limits::WeightsPerClass
+   * Lookup303: frame_system::limits::WeightsPerClass
    **/
   FrameSystemLimitsWeightsPerClass: {
     baseExtrinsic: 'u64',
@@ -2099,13 +2451,13 @@
     reserved: 'Option<u64>'
   },
   /**
-   * Lookup272: frame_system::limits::BlockLength
+   * Lookup305: frame_system::limits::BlockLength
    **/
   FrameSystemLimitsBlockLength: {
     max: 'FrameSupportWeightsPerDispatchClassU32'
   },
   /**
-   * Lookup273: frame_support::weights::PerDispatchClass<T>
+   * Lookup306: frame_support::weights::PerDispatchClass<T>
    **/
   FrameSupportWeightsPerDispatchClassU32: {
     normal: 'u32',
@@ -2113,14 +2465,14 @@
     mandatory: 'u32'
   },
   /**
-   * Lookup274: frame_support::weights::RuntimeDbWeight
+   * Lookup307: frame_support::weights::RuntimeDbWeight
    **/
   FrameSupportWeightsRuntimeDbWeight: {
     read: 'u64',
     write: 'u64'
   },
   /**
-   * Lookup275: sp_version::RuntimeVersion
+   * Lookup308: sp_version::RuntimeVersion
    **/
   SpVersionRuntimeVersion: {
     specName: 'Text',
@@ -2133,19 +2485,19 @@
     stateVersion: 'u8'
   },
   /**
-   * Lookup279: frame_system::pallet::Error<T>
+   * Lookup312: frame_system::pallet::Error<T>
    **/
   FrameSystemError: {
     _enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered']
   },
   /**
-   * Lookup281: orml_vesting::module::Error<T>
+   * Lookup314: orml_vesting::module::Error<T>
    **/
   OrmlVestingModuleError: {
     _enum: ['ZeroVestingPeriod', 'ZeroVestingPeriodCount', 'InsufficientBalanceToLock', 'TooManyVestingSchedules', 'AmountLow', 'MaxVestingSchedulesExceeded']
   },
   /**
-   * Lookup283: cumulus_pallet_xcmp_queue::InboundChannelDetails
+   * Lookup316: cumulus_pallet_xcmp_queue::InboundChannelDetails
    **/
   CumulusPalletXcmpQueueInboundChannelDetails: {
     sender: 'u32',
@@ -2153,19 +2505,19 @@
     messageMetadata: 'Vec<(u32,PolkadotParachainPrimitivesXcmpMessageFormat)>'
   },
   /**
-   * Lookup284: cumulus_pallet_xcmp_queue::InboundState
+   * Lookup317: cumulus_pallet_xcmp_queue::InboundState
    **/
   CumulusPalletXcmpQueueInboundState: {
     _enum: ['Ok', 'Suspended']
   },
   /**
-   * Lookup287: polkadot_parachain::primitives::XcmpMessageFormat
+   * Lookup320: polkadot_parachain::primitives::XcmpMessageFormat
    **/
   PolkadotParachainPrimitivesXcmpMessageFormat: {
     _enum: ['ConcatenatedVersionedXcm', 'ConcatenatedEncodedBlob', 'Signals']
   },
   /**
-   * Lookup290: cumulus_pallet_xcmp_queue::OutboundChannelDetails
+   * Lookup323: cumulus_pallet_xcmp_queue::OutboundChannelDetails
    **/
   CumulusPalletXcmpQueueOutboundChannelDetails: {
     recipient: 'u32',
@@ -2175,13 +2527,13 @@
     lastIndex: 'u16'
   },
   /**
-   * Lookup291: cumulus_pallet_xcmp_queue::OutboundState
+   * Lookup324: cumulus_pallet_xcmp_queue::OutboundState
    **/
   CumulusPalletXcmpQueueOutboundState: {
     _enum: ['Ok', 'Suspended']
   },
   /**
-   * Lookup293: cumulus_pallet_xcmp_queue::QueueConfigData
+   * Lookup326: cumulus_pallet_xcmp_queue::QueueConfigData
    **/
   CumulusPalletXcmpQueueQueueConfigData: {
     suspendThreshold: 'u32',
@@ -2192,29 +2544,29 @@
     xcmpMaxIndividualWeight: 'u64'
   },
   /**
-   * Lookup295: cumulus_pallet_xcmp_queue::pallet::Error<T>
+   * Lookup328: cumulus_pallet_xcmp_queue::pallet::Error<T>
    **/
   CumulusPalletXcmpQueueError: {
     _enum: ['FailedToSend', 'BadXcmOrigin', 'BadXcm', 'BadOverweightIndex', 'WeightOverLimit']
   },
   /**
-   * Lookup296: pallet_xcm::pallet::Error<T>
+   * Lookup329: pallet_xcm::pallet::Error<T>
    **/
   PalletXcmError: {
     _enum: ['Unreachable', 'SendFailure', 'Filtered', 'UnweighableMessage', 'DestinationNotInvertible', 'Empty', 'CannotReanchor', 'TooManyAssets', 'InvalidOrigin', 'BadVersion', 'BadLocation', 'NoSubscription', 'AlreadySubscribed']
   },
   /**
-   * Lookup297: cumulus_pallet_xcm::pallet::Error<T>
+   * Lookup330: cumulus_pallet_xcm::pallet::Error<T>
    **/
   CumulusPalletXcmError: 'Null',
   /**
-   * Lookup298: cumulus_pallet_dmp_queue::ConfigData
+   * Lookup331: cumulus_pallet_dmp_queue::ConfigData
    **/
   CumulusPalletDmpQueueConfigData: {
     maxIndividual: 'u64'
   },
   /**
-   * Lookup299: cumulus_pallet_dmp_queue::PageIndexData
+   * Lookup332: cumulus_pallet_dmp_queue::PageIndexData
    **/
   CumulusPalletDmpQueuePageIndexData: {
     beginUsed: 'u32',
@@ -2222,19 +2574,184 @@
     overweightCount: 'u64'
   },
   /**
-   * Lookup302: cumulus_pallet_dmp_queue::pallet::Error<T>
+   * Lookup335: cumulus_pallet_dmp_queue::pallet::Error<T>
    **/
   CumulusPalletDmpQueueError: {
     _enum: ['Unknown', 'OverLimit']
   },
   /**
-   * Lookup306: pallet_unique::Error<T>
+   * Lookup339: pallet_unique::Error<T>
    **/
   PalletUniqueError: {
     _enum: ['CollectionDecimalPointLimitExceeded', 'ConfirmUnsetSponsorFail', 'EmptyArgument']
   },
   /**
-   * Lookup307: up_data_structs::Collection<sp_core::crypto::AccountId32>
+   * Lookup342: pallet_unq_scheduler::ScheduledV3<frame_support::traits::schedule::MaybeHashed<opal_runtime::Call, primitive_types::H256>, BlockNumber, opal_runtime::OriginCaller, sp_core::crypto::AccountId32>
+   **/
+  PalletUnqSchedulerScheduledV3: {
+    maybeId: 'Option<[u8;16]>',
+    priority: 'u8',
+    call: 'FrameSupportScheduleMaybeHashed',
+    maybePeriodic: 'Option<(u32,u32)>',
+    origin: 'OpalRuntimeOriginCaller'
+  },
+  /**
+   * Lookup343: opal_runtime::OriginCaller
+   **/
+  OpalRuntimeOriginCaller: {
+    _enum: {
+      __Unused0: 'Null',
+      __Unused1: 'Null',
+      __Unused2: 'Null',
+      __Unused3: 'Null',
+      Void: 'SpCoreVoid',
+      __Unused5: 'Null',
+      __Unused6: 'Null',
+      __Unused7: 'Null',
+      __Unused8: 'Null',
+      __Unused9: 'Null',
+      __Unused10: 'Null',
+      __Unused11: 'Null',
+      __Unused12: 'Null',
+      __Unused13: 'Null',
+      __Unused14: 'Null',
+      __Unused15: 'Null',
+      __Unused16: 'Null',
+      __Unused17: 'Null',
+      __Unused18: 'Null',
+      __Unused19: 'Null',
+      __Unused20: 'Null',
+      __Unused21: 'Null',
+      __Unused22: 'Null',
+      __Unused23: 'Null',
+      __Unused24: 'Null',
+      __Unused25: 'Null',
+      __Unused26: 'Null',
+      __Unused27: 'Null',
+      __Unused28: 'Null',
+      __Unused29: 'Null',
+      __Unused30: 'Null',
+      __Unused31: 'Null',
+      __Unused32: 'Null',
+      __Unused33: 'Null',
+      __Unused34: 'Null',
+      __Unused35: 'Null',
+      system: 'FrameSupportDispatchRawOrigin',
+      __Unused37: 'Null',
+      __Unused38: 'Null',
+      __Unused39: 'Null',
+      __Unused40: 'Null',
+      __Unused41: 'Null',
+      __Unused42: 'Null',
+      __Unused43: 'Null',
+      __Unused44: 'Null',
+      __Unused45: 'Null',
+      __Unused46: 'Null',
+      __Unused47: 'Null',
+      __Unused48: 'Null',
+      __Unused49: 'Null',
+      __Unused50: 'Null',
+      PolkadotXcm: 'PalletXcmOrigin',
+      CumulusXcm: 'CumulusPalletXcmOrigin',
+      __Unused53: 'Null',
+      __Unused54: 'Null',
+      __Unused55: 'Null',
+      __Unused56: 'Null',
+      __Unused57: 'Null',
+      __Unused58: 'Null',
+      __Unused59: 'Null',
+      __Unused60: 'Null',
+      __Unused61: 'Null',
+      __Unused62: 'Null',
+      __Unused63: 'Null',
+      __Unused64: 'Null',
+      __Unused65: 'Null',
+      __Unused66: 'Null',
+      __Unused67: 'Null',
+      __Unused68: 'Null',
+      __Unused69: 'Null',
+      __Unused70: 'Null',
+      __Unused71: 'Null',
+      __Unused72: 'Null',
+      __Unused73: 'Null',
+      __Unused74: 'Null',
+      __Unused75: 'Null',
+      __Unused76: 'Null',
+      __Unused77: 'Null',
+      __Unused78: 'Null',
+      __Unused79: 'Null',
+      __Unused80: 'Null',
+      __Unused81: 'Null',
+      __Unused82: 'Null',
+      __Unused83: 'Null',
+      __Unused84: 'Null',
+      __Unused85: 'Null',
+      __Unused86: 'Null',
+      __Unused87: 'Null',
+      __Unused88: 'Null',
+      __Unused89: 'Null',
+      __Unused90: 'Null',
+      __Unused91: 'Null',
+      __Unused92: 'Null',
+      __Unused93: 'Null',
+      __Unused94: 'Null',
+      __Unused95: 'Null',
+      __Unused96: 'Null',
+      __Unused97: 'Null',
+      __Unused98: 'Null',
+      __Unused99: 'Null',
+      __Unused100: 'Null',
+      Ethereum: 'PalletEthereumRawOrigin'
+    }
+  },
+  /**
+   * Lookup344: frame_support::dispatch::RawOrigin<sp_core::crypto::AccountId32>
+   **/
+  FrameSupportDispatchRawOrigin: {
+    _enum: {
+      Root: 'Null',
+      Signed: 'AccountId32',
+      None: 'Null'
+    }
+  },
+  /**
+   * Lookup345: pallet_xcm::pallet::Origin
+   **/
+  PalletXcmOrigin: {
+    _enum: {
+      Xcm: 'XcmV1MultiLocation',
+      Response: 'XcmV1MultiLocation'
+    }
+  },
+  /**
+   * Lookup346: cumulus_pallet_xcm::pallet::Origin
+   **/
+  CumulusPalletXcmOrigin: {
+    _enum: {
+      Relay: 'Null',
+      SiblingParachain: 'u32'
+    }
+  },
+  /**
+   * Lookup347: pallet_ethereum::RawOrigin
+   **/
+  PalletEthereumRawOrigin: {
+    _enum: {
+      EthereumTransaction: 'H160'
+    }
+  },
+  /**
+   * Lookup348: sp_core::Void
+   **/
+  SpCoreVoid: 'Null',
+  /**
+   * Lookup349: pallet_unq_scheduler::pallet::Error<T>
+   **/
+  PalletUnqSchedulerError: {
+    _enum: ['FailedToSchedule', 'NotFound', 'TargetBlockNumberInPast', 'RescheduleNoChange']
+  },
+  /**
+   * Lookup350: up_data_structs::Collection<sp_core::crypto::AccountId32>
    **/
   UpDataStructsCollection: {
     owner: 'AccountId32',
@@ -2244,10 +2761,11 @@
     tokenPrefix: 'Bytes',
     sponsorship: 'UpDataStructsSponsorshipState',
     limits: 'UpDataStructsCollectionLimits',
-    permissions: 'UpDataStructsCollectionPermissions'
+    permissions: 'UpDataStructsCollectionPermissions',
+    externalCollection: 'bool'
   },
   /**
-   * Lookup308: up_data_structs::SponsorshipState<sp_core::crypto::AccountId32>
+   * Lookup351: up_data_structs::SponsorshipState<sp_core::crypto::AccountId32>
    **/
   UpDataStructsSponsorshipState: {
     _enum: {
@@ -2257,7 +2775,7 @@
     }
   },
   /**
-   * Lookup309: up_data_structs::Properties
+   * Lookup352: up_data_structs::Properties
    **/
   UpDataStructsProperties: {
     map: 'UpDataStructsPropertiesMapBoundedVec',
@@ -2265,15 +2783,15 @@
     spaceLimit: 'u32'
   },
   /**
-   * Lookup310: up_data_structs::PropertiesMap<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup353: up_data_structs::PropertiesMap<frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   UpDataStructsPropertiesMapBoundedVec: 'BTreeMap<Bytes, Bytes>',
   /**
-   * Lookup315: up_data_structs::PropertiesMap<up_data_structs::PropertyPermission>
+   * Lookup358: up_data_structs::PropertiesMap<up_data_structs::PropertyPermission>
    **/
   UpDataStructsPropertiesMapPropertyPermission: 'BTreeMap<Bytes, UpDataStructsPropertyPermission>',
   /**
-   * Lookup322: up_data_structs::CollectionStats
+   * Lookup365: up_data_structs::CollectionStats
    **/
   UpDataStructsCollectionStats: {
     created: 'u32',
@@ -2281,25 +2799,25 @@
     alive: 'u32'
   },
   /**
-   * Lookup323: up_data_structs::TokenChild
+   * Lookup366: up_data_structs::TokenChild
    **/
   UpDataStructsTokenChild: {
     token: 'u32',
     collection: 'u32'
   },
   /**
-   * Lookup324: PhantomType::up_data_structs<T>
+   * Lookup367: PhantomType::up_data_structs<T>
    **/
-  PhantomTypeUpDataStructs: '[(UpDataStructsTokenData,UpDataStructsRpcCollection,UpDataStructsRmrkCollectionInfo,UpDataStructsRmrkNftInfo,UpDataStructsRmrkResourceInfo,UpDataStructsRmrkPropertyInfo,UpDataStructsRmrkBaseInfo,UpDataStructsRmrkPartType,UpDataStructsRmrkTheme,UpDataStructsRmrkNftChild);0]',
+  PhantomTypeUpDataStructs: '[(UpDataStructsTokenData,UpDataStructsRpcCollection,RmrkTraitsCollectionCollectionInfo,RmrkTraitsNftNftInfo,RmrkTraitsResourceResourceInfo,RmrkTraitsPropertyPropertyInfo,RmrkTraitsBaseBaseInfo,RmrkTraitsPartPartType,RmrkTraitsTheme,RmrkTraitsNftNftChild);0]',
   /**
-   * Lookup326: up_data_structs::TokenData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup369: up_data_structs::TokenData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsTokenData: {
     properties: 'Vec<UpDataStructsProperty>',
     owner: 'Option<PalletEvmAccountBasicCrossAccountIdRepr>'
   },
   /**
-   * Lookup328: up_data_structs::RpcCollection<sp_core::crypto::AccountId32>
+   * Lookup371: up_data_structs::RpcCollection<sp_core::crypto::AccountId32>
    **/
   UpDataStructsRpcCollection: {
     owner: 'AccountId32',
@@ -2311,12 +2829,13 @@
     limits: 'UpDataStructsCollectionLimits',
     permissions: 'UpDataStructsCollectionPermissions',
     tokenPropertyPermissions: 'Vec<UpDataStructsPropertyKeyPermission>',
-    properties: 'Vec<UpDataStructsProperty>'
+    properties: 'Vec<UpDataStructsProperty>',
+    readOnly: 'bool'
   },
   /**
-   * Lookup329: up_data_structs::rmrk::CollectionInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, sp_core::crypto::AccountId32>
+   * Lookup372: rmrk_traits::collection::CollectionInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, sp_core::crypto::AccountId32>
    **/
-  UpDataStructsRmrkCollectionInfo: {
+  RmrkTraitsCollectionCollectionInfo: {
     issuer: 'AccountId32',
     metadata: 'Bytes',
     max: 'Option<u32>',
@@ -2324,204 +2843,125 @@
     nftsCount: 'u32'
   },
   /**
-   * Lookup332: up_data_structs::rmrk::NftInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup373: rmrk_traits::nft::NftInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
-  UpDataStructsRmrkNftInfo: {
-    owner: 'UpDataStructsRmrkAccountIdOrCollectionNftTuple',
-    royalty: 'Option<UpDataStructsRmrkRoyaltyInfo>',
+  RmrkTraitsNftNftInfo: {
+    owner: 'RmrkTraitsNftAccountIdOrCollectionNftTuple',
+    royalty: 'Option<RmrkTraitsNftRoyaltyInfo>',
     metadata: 'Bytes',
     equipped: 'bool',
     pending: 'bool'
   },
   /**
-   * Lookup333: up_data_structs::rmrk::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
+   * Lookup375: rmrk_traits::nft::RoyaltyInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill>
    **/
-  UpDataStructsRmrkAccountIdOrCollectionNftTuple: {
-    _enum: {
-      AccountId: 'AccountId32',
-      CollectionAndNftTuple: '(u32,u32)'
-    }
-  },
-  /**
-   * Lookup335: up_data_structs::rmrk::RoyaltyInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill>
-   **/
-  UpDataStructsRmrkRoyaltyInfo: {
+  RmrkTraitsNftRoyaltyInfo: {
     recipient: 'AccountId32',
     amount: 'Permill'
   },
   /**
-   * Lookup336: up_data_structs::rmrk::ResourceInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup376: rmrk_traits::resource::ResourceInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
-  UpDataStructsRmrkResourceInfo: {
-    id: 'Bytes',
-    resource: 'UpDataStructsRmrkResourceTypes',
+  RmrkTraitsResourceResourceInfo: {
+    id: 'u32',
+    resource: 'RmrkTraitsResourceResourceTypes',
     pending: 'bool',
     pendingRemoval: 'bool'
   },
   /**
-   * Lookup339: up_data_structs::rmrk::ResourceTypes<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup377: rmrk_traits::resource::ResourceTypes<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
-  UpDataStructsRmrkResourceTypes: {
+  RmrkTraitsResourceResourceTypes: {
     _enum: {
-      Basic: 'UpDataStructsRmrkBasicResource',
-      Composable: 'UpDataStructsRmrkComposableResource',
-      Slot: 'UpDataStructsRmrkSlotResource'
+      Basic: 'RmrkTraitsResourceBasicResource',
+      Composable: 'RmrkTraitsResourceComposableResource',
+      Slot: 'RmrkTraitsResourceSlotResource'
     }
   },
   /**
-   * Lookup340: up_data_structs::rmrk::BasicResource<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup378: rmrk_traits::property::PropertyInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
-  UpDataStructsRmrkBasicResource: {
-    src: 'Option<Bytes>',
-    metadata: 'Option<Bytes>',
-    license: 'Option<Bytes>',
-    thumb: 'Option<Bytes>'
-  },
-  /**
-   * Lookup342: up_data_structs::rmrk::ComposableResource<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkComposableResource: {
-    parts: 'Vec<u32>',
-    base: 'u32',
-    src: 'Option<Bytes>',
-    metadata: 'Option<Bytes>',
-    license: 'Option<Bytes>',
-    thumb: 'Option<Bytes>'
-  },
-  /**
-   * Lookup343: up_data_structs::rmrk::SlotResource<frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkSlotResource: {
-    base: 'u32',
-    src: 'Option<Bytes>',
-    metadata: 'Option<Bytes>',
-    slot: 'u32',
-    license: 'Option<Bytes>',
-    thumb: 'Option<Bytes>'
-  },
-  /**
-   * Lookup344: up_data_structs::rmrk::PropertyInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkPropertyInfo: {
+  RmrkTraitsPropertyPropertyInfo: {
     key: 'Bytes',
     value: 'Bytes'
   },
   /**
-   * Lookup347: up_data_structs::rmrk::BaseInfo<sp_core::crypto::AccountId32, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup379: rmrk_traits::base::BaseInfo<sp_core::crypto::AccountId32, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
-  UpDataStructsRmrkBaseInfo: {
+  RmrkTraitsBaseBaseInfo: {
     issuer: 'AccountId32',
     baseType: 'Bytes',
     symbol: 'Bytes'
   },
   /**
-   * Lookup348: up_data_structs::rmrk::PartType<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkPartType: {
-    _enum: {
-      FixedPart: 'UpDataStructsRmrkFixedPart',
-      SlotPart: 'UpDataStructsRmrkSlotPart'
-    }
-  },
-  /**
-   * Lookup350: up_data_structs::rmrk::FixedPart<frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkFixedPart: {
-    id: 'u32',
-    z: 'u32',
-    src: 'Bytes'
-  },
-  /**
-   * Lookup351: up_data_structs::rmrk::SlotPart<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup380: rmrk_traits::nft::NftChild
    **/
-  UpDataStructsRmrkSlotPart: {
-    id: 'u32',
-    equippable: 'UpDataStructsRmrkEquippableList',
-    src: 'Bytes',
-    z: 'u32'
-  },
-  /**
-   * Lookup352: up_data_structs::rmrk::EquippableList<frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkEquippableList: {
-    _enum: {
-      All: 'Null',
-      Empty: 'Null',
-      Custom: 'Vec<u32>'
-    }
-  },
-  /**
-   * Lookup353: up_data_structs::rmrk::Theme<frame_support::storage::bounded_vec::BoundedVec<T, S>, PropertyList>
-   **/
-  UpDataStructsRmrkTheme: {
-    name: 'Bytes',
-    properties: 'Vec<UpDataStructsRmrkThemeProperty>',
-    inherit: 'bool'
-  },
-  /**
-   * Lookup355: up_data_structs::rmrk::ThemeProperty<frame_support::storage::bounded_vec::BoundedVec<T, S>>
-   **/
-  UpDataStructsRmrkThemeProperty: {
-    key: 'Bytes',
-    value: 'Bytes'
-  },
-  /**
-   * Lookup356: up_data_structs::rmrk::NftChild
-   **/
-  UpDataStructsRmrkNftChild: {
+  RmrkTraitsNftNftChild: {
     collectionId: 'u32',
     nftId: 'u32'
   },
   /**
-   * Lookup358: pallet_common::pallet::Error<T>
+   * Lookup382: pallet_common::pallet::Error<T>
    **/
   PalletCommonError: {
-    _enum: ['CollectionNotFound', 'MustBeTokenOwner', 'NoPermission', 'CantDestroyNotEmptyCollection', 'PublicMintingNotAllowed', 'AddressNotInAllowlist', 'CollectionNameLimitExceeded', 'CollectionDescriptionLimitExceeded', 'CollectionTokenPrefixLimitExceeded', 'TotalCollectionsLimitExceeded', 'CollectionAdminCountExceeded', 'CollectionLimitBoundsExceeded', 'OwnerPermissionsCantBeReverted', 'TransferNotAllowed', 'AccountTokenLimitExceeded', 'CollectionTokenLimitExceeded', 'MetadataFlagFrozen', 'TokenNotFound', 'TokenValueTooLow', 'ApprovedValueTooLow', 'CantApproveMoreThanOwned', 'AddressIsZero', 'UnsupportedOperation', 'NotSufficientFounds', 'NestingIsDisabled', 'OnlyOwnerAllowedToNest', 'SourceCollectionIsNotAllowedToNest', 'CollectionFieldSizeExceeded', 'NoSpaceForProperty', 'PropertyLimitReached', 'PropertyKeyIsTooLong', 'InvalidCharacterInPropertyKey', 'EmptyPropertyKey']
+    _enum: ['CollectionNotFound', 'MustBeTokenOwner', 'NoPermission', 'CantDestroyNotEmptyCollection', 'PublicMintingNotAllowed', 'AddressNotInAllowlist', 'CollectionNameLimitExceeded', 'CollectionDescriptionLimitExceeded', 'CollectionTokenPrefixLimitExceeded', 'TotalCollectionsLimitExceeded', 'CollectionAdminCountExceeded', 'CollectionLimitBoundsExceeded', 'OwnerPermissionsCantBeReverted', 'TransferNotAllowed', 'AccountTokenLimitExceeded', 'CollectionTokenLimitExceeded', 'MetadataFlagFrozen', 'TokenNotFound', 'TokenValueTooLow', 'ApprovedValueTooLow', 'CantApproveMoreThanOwned', 'AddressIsZero', 'UnsupportedOperation', 'NotSufficientFounds', 'NestingIsDisabled', 'OnlyOwnerAllowedToNest', 'SourceCollectionIsNotAllowedToNest', 'CollectionFieldSizeExceeded', 'NoSpaceForProperty', 'PropertyLimitReached', 'PropertyKeyIsTooLong', 'InvalidCharacterInPropertyKey', 'EmptyPropertyKey', 'CollectionIsExternal', 'CollectionIsInternal']
   },
   /**
-   * Lookup360: pallet_fungible::pallet::Error<T>
+   * Lookup384: pallet_fungible::pallet::Error<T>
    **/
   PalletFungibleError: {
     _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed']
   },
   /**
-   * Lookup361: pallet_refungible::ItemData
+   * Lookup385: pallet_refungible::ItemData
    **/
   PalletRefungibleItemData: {
     constData: 'Bytes'
   },
   /**
-   * Lookup365: pallet_refungible::pallet::Error<T>
+   * Lookup389: pallet_refungible::pallet::Error<T>
    **/
   PalletRefungibleError: {
     _enum: ['NotRefungibleDataUsedToMintFungibleCollectionToken', 'WrongRefungiblePieces', 'RefungibleDisallowsNesting', 'SettingPropertiesNotAllowed']
   },
   /**
-   * Lookup366: pallet_nonfungible::ItemData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup390: pallet_nonfungible::ItemData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   PalletNonfungibleItemData: {
     owner: 'PalletEvmAccountBasicCrossAccountIdRepr'
   },
   /**
-   * Lookup368: pallet_nonfungible::pallet::Error<T>
+   * Lookup392: pallet_nonfungible::pallet::Error<T>
    **/
   PalletNonfungibleError: {
     _enum: ['NotNonfungibleDataUsedToMintFungibleCollectionToken', 'NonfungibleItemsHaveNoAmount', 'CantBurnNftWithChildren']
   },
   /**
-   * Lookup369: pallet_structure::pallet::Error<T>
+   * Lookup393: pallet_structure::pallet::Error<T>
    **/
   PalletStructureError: {
     _enum: ['OuroborosDetected', 'DepthLimit', 'TokenNotFound']
   },
   /**
-   * Lookup372: pallet_evm::pallet::Error<T>
+   * Lookup394: pallet_rmrk_core::pallet::Error<T>
+   **/
+  PalletRmrkCoreError: {
+    _enum: ['CorruptedCollectionType', 'NftTypeEncodeError', 'RmrkPropertyKeyIsTooLong', 'RmrkPropertyValueIsTooLong', 'CollectionNotEmpty', 'NoAvailableCollectionId', 'NoAvailableNftId', 'CollectionUnknown', 'NoPermission', 'NonTransferable', 'CollectionFullOrLocked', 'ResourceDoesntExist', 'CannotSendToDescendentOrSelf', 'CannotAcceptNonOwnedNft', 'CannotRejectNonOwnedNft', 'ResourceNotPending']
+  },
+  /**
+   * Lookup396: pallet_rmrk_equip::pallet::Error<T>
    **/
+  PalletRmrkEquipError: {
+    _enum: ['PermissionError', 'NoAvailableBaseId', 'NoAvailablePartId', 'BaseDoesntExist', 'NeedsDefaultThemeFirst']
+  },
+  /**
+   * Lookup399: pallet_evm::pallet::Error<T>
+   **/
   PalletEvmError: {
     _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce']
   },
   /**
-   * Lookup375: fp_rpc::TransactionStatus
+   * Lookup402: fp_rpc::TransactionStatus
    **/
   FpRpcTransactionStatus: {
     transactionHash: 'H256',
@@ -2533,11 +2973,11 @@
     logsBloom: 'EthbloomBloom'
   },
   /**
-   * Lookup377: ethbloom::Bloom
+   * Lookup404: ethbloom::Bloom
    **/
   EthbloomBloom: '[u8;256]',
   /**
-   * Lookup379: ethereum::receipt::ReceiptV3
+   * Lookup406: ethereum::receipt::ReceiptV3
    **/
   EthereumReceiptReceiptV3: {
     _enum: {
@@ -2547,7 +2987,7 @@
     }
   },
   /**
-   * Lookup380: ethereum::receipt::EIP658ReceiptData
+   * Lookup407: ethereum::receipt::EIP658ReceiptData
    **/
   EthereumReceiptEip658ReceiptData: {
     statusCode: 'u8',
@@ -2556,7 +2996,7 @@
     logs: 'Vec<EthereumLog>'
   },
   /**
-   * Lookup381: ethereum::block::Block<ethereum::transaction::TransactionV2>
+   * Lookup408: ethereum::block::Block<ethereum::transaction::TransactionV2>
    **/
   EthereumBlock: {
     header: 'EthereumHeader',
@@ -2564,7 +3004,7 @@
     ommers: 'Vec<EthereumHeader>'
   },
   /**
-   * Lookup382: ethereum::header::Header
+   * Lookup409: ethereum::header::Header
    **/
   EthereumHeader: {
     parentHash: 'H256',
@@ -2584,41 +3024,41 @@
     nonce: 'EthereumTypesHashH64'
   },
   /**
-   * Lookup383: ethereum_types::hash::H64
+   * Lookup410: ethereum_types::hash::H64
    **/
   EthereumTypesHashH64: '[u8;8]',
   /**
-   * Lookup388: pallet_ethereum::pallet::Error<T>
+   * Lookup415: pallet_ethereum::pallet::Error<T>
    **/
   PalletEthereumError: {
     _enum: ['InvalidSignature', 'PreLogExists']
   },
   /**
-   * Lookup389: pallet_evm_coder_substrate::pallet::Error<T>
+   * Lookup416: pallet_evm_coder_substrate::pallet::Error<T>
    **/
   PalletEvmCoderSubstrateError: {
     _enum: ['OutOfGas', 'OutOfFund']
   },
   /**
-   * Lookup390: pallet_evm_contract_helpers::SponsoringModeT
+   * Lookup417: pallet_evm_contract_helpers::SponsoringModeT
    **/
   PalletEvmContractHelpersSponsoringModeT: {
     _enum: ['Disabled', 'Allowlisted', 'Generous']
   },
   /**
-   * Lookup392: pallet_evm_contract_helpers::pallet::Error<T>
+   * Lookup419: pallet_evm_contract_helpers::pallet::Error<T>
    **/
   PalletEvmContractHelpersError: {
     _enum: ['NoPermission']
   },
   /**
-   * Lookup393: pallet_evm_migration::pallet::Error<T>
+   * Lookup420: pallet_evm_migration::pallet::Error<T>
    **/
   PalletEvmMigrationError: {
     _enum: ['AccountNotEmpty', 'AccountIsNotMigrating']
   },
   /**
-   * Lookup395: sp_runtime::MultiSignature
+   * Lookup422: sp_runtime::MultiSignature
    **/
   SpRuntimeMultiSignature: {
     _enum: {
@@ -2628,43 +3068,43 @@
     }
   },
   /**
-   * Lookup396: sp_core::ed25519::Signature
+   * Lookup423: sp_core::ed25519::Signature
    **/
   SpCoreEd25519Signature: '[u8;64]',
   /**
-   * Lookup398: sp_core::sr25519::Signature
+   * Lookup425: sp_core::sr25519::Signature
    **/
   SpCoreSr25519Signature: '[u8;64]',
   /**
-   * Lookup399: sp_core::ecdsa::Signature
+   * Lookup426: sp_core::ecdsa::Signature
    **/
   SpCoreEcdsaSignature: '[u8;65]',
   /**
-   * Lookup402: frame_system::extensions::check_spec_version::CheckSpecVersion<T>
+   * Lookup429: frame_system::extensions::check_spec_version::CheckSpecVersion<T>
    **/
   FrameSystemExtensionsCheckSpecVersion: 'Null',
   /**
-   * Lookup403: frame_system::extensions::check_genesis::CheckGenesis<T>
+   * Lookup430: frame_system::extensions::check_genesis::CheckGenesis<T>
    **/
   FrameSystemExtensionsCheckGenesis: 'Null',
   /**
-   * Lookup406: frame_system::extensions::check_nonce::CheckNonce<T>
+   * Lookup433: frame_system::extensions::check_nonce::CheckNonce<T>
    **/
   FrameSystemExtensionsCheckNonce: 'Compact<u32>',
   /**
-   * Lookup407: frame_system::extensions::check_weight::CheckWeight<T>
+   * Lookup434: frame_system::extensions::check_weight::CheckWeight<T>
    **/
   FrameSystemExtensionsCheckWeight: 'Null',
   /**
-   * Lookup408: pallet_template_transaction_payment::ChargeTransactionPayment<opal_runtime::Runtime>
+   * Lookup435: pallet_template_transaction_payment::ChargeTransactionPayment<opal_runtime::Runtime>
    **/
   PalletTemplateTransactionPaymentChargeTransactionPayment: 'Compact<u128>',
   /**
-   * Lookup409: opal_runtime::Runtime
+   * Lookup436: opal_runtime::Runtime
    **/
   OpalRuntimeRuntime: 'Null',
   /**
-   * Lookup410: pallet_ethereum::FakeTransactionFinalizer<opal_runtime::Runtime>
+   * Lookup437: pallet_ethereum::FakeTransactionFinalizer<opal_runtime::Runtime>
    **/
   PalletEthereumFakeTransactionFinalizer: 'Null'
 };
modifiedtests/src/interfaces/registry.tsdiffbeforeafterboth
--- a/tests/src/interfaces/registry.ts
+++ b/tests/src/interfaces/registry.ts
@@ -1,7 +1,7 @@
 // Auto-generated via `yarn polkadot-types-from-defs`, do not edit
 /* eslint-disable */
 
-import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportPalletId, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PhantomTypeUpDataStructs, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionPermissions, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRmrkAccountIdOrCollectionNftTuple, UpDataStructsRmrkBaseInfo, UpDataStructsRmrkBasicResource, UpDataStructsRmrkCollectionInfo, UpDataStructsRmrkComposableResource, UpDataStructsRmrkEquippableList, UpDataStructsRmrkFixedPart, UpDataStructsRmrkNftChild, UpDataStructsRmrkNftInfo, UpDataStructsRmrkPartType, UpDataStructsRmrkPropertyInfo, UpDataStructsRmrkResourceInfo, UpDataStructsRmrkResourceTypes, UpDataStructsRmrkRoyaltyInfo, UpDataStructsRmrkSlotPart, UpDataStructsRmrkSlotResource, UpDataStructsRmrkTheme, UpDataStructsRmrkThemeProperty, UpDataStructsRpcCollection, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenChild, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
+import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmOrigin, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportDispatchRawOrigin, FrameSupportPalletId, FrameSupportScheduleLookupError, FrameSupportScheduleMaybeHashed, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeOriginCaller, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEthereumRawOrigin, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletRmrkCoreCall, PalletRmrkCoreError, PalletRmrkCoreEvent, PalletRmrkEquipCall, PalletRmrkEquipError, PalletRmrkEquipEvent, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletUnqSchedulerCall, PalletUnqSchedulerError, PalletUnqSchedulerEvent, PalletUnqSchedulerScheduledV3, PalletXcmCall, PalletXcmError, PalletXcmEvent, PalletXcmOrigin, PhantomTypeUpDataStructs, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, RmrkTraitsBaseBaseInfo, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftAccountIdOrCollectionNftTuple, RmrkTraitsNftNftChild, RmrkTraitsNftNftInfo, RmrkTraitsNftRoyaltyInfo, RmrkTraitsPartEquippableList, RmrkTraitsPartFixedPart, RmrkTraitsPartPartType, RmrkTraitsPartSlotPart, RmrkTraitsPropertyPropertyInfo, RmrkTraitsResourceBasicResource, RmrkTraitsResourceComposableResource, RmrkTraitsResourceResourceInfo, RmrkTraitsResourceResourceTypes, RmrkTraitsResourceSlotResource, RmrkTraitsTheme, RmrkTraitsThemeThemeProperty, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpCoreVoid, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionPermissions, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRpcCollection, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenChild, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
 
 declare module '@polkadot/types/types/registry' {
   export interface InterfaceTypes {
@@ -17,6 +17,7 @@
     CumulusPalletXcmCall: CumulusPalletXcmCall;
     CumulusPalletXcmError: CumulusPalletXcmError;
     CumulusPalletXcmEvent: CumulusPalletXcmEvent;
+    CumulusPalletXcmOrigin: CumulusPalletXcmOrigin;
     CumulusPalletXcmpQueueCall: CumulusPalletXcmpQueueCall;
     CumulusPalletXcmpQueueError: CumulusPalletXcmpQueueError;
     CumulusPalletXcmpQueueEvent: CumulusPalletXcmpQueueEvent;
@@ -46,7 +47,10 @@
     EvmCoreErrorExitRevert: EvmCoreErrorExitRevert;
     EvmCoreErrorExitSucceed: EvmCoreErrorExitSucceed;
     FpRpcTransactionStatus: FpRpcTransactionStatus;
+    FrameSupportDispatchRawOrigin: FrameSupportDispatchRawOrigin;
     FrameSupportPalletId: FrameSupportPalletId;
+    FrameSupportScheduleLookupError: FrameSupportScheduleLookupError;
+    FrameSupportScheduleMaybeHashed: FrameSupportScheduleMaybeHashed;
     FrameSupportTokensMiscBalanceStatus: FrameSupportTokensMiscBalanceStatus;
     FrameSupportWeightsDispatchClass: FrameSupportWeightsDispatchClass;
     FrameSupportWeightsDispatchInfo: FrameSupportWeightsDispatchInfo;
@@ -70,6 +74,7 @@
     FrameSystemLimitsBlockWeights: FrameSystemLimitsBlockWeights;
     FrameSystemLimitsWeightsPerClass: FrameSystemLimitsWeightsPerClass;
     FrameSystemPhase: FrameSystemPhase;
+    OpalRuntimeOriginCaller: OpalRuntimeOriginCaller;
     OpalRuntimeRuntime: OpalRuntimeRuntime;
     OrmlVestingModuleCall: OrmlVestingModuleCall;
     OrmlVestingModuleError: OrmlVestingModuleError;
@@ -89,6 +94,7 @@
     PalletEthereumError: PalletEthereumError;
     PalletEthereumEvent: PalletEthereumEvent;
     PalletEthereumFakeTransactionFinalizer: PalletEthereumFakeTransactionFinalizer;
+    PalletEthereumRawOrigin: PalletEthereumRawOrigin;
     PalletEvmAccountBasicCrossAccountIdRepr: PalletEvmAccountBasicCrossAccountIdRepr;
     PalletEvmCall: PalletEvmCall;
     PalletEvmCoderSubstrateError: PalletEvmCoderSubstrateError;
@@ -104,6 +110,12 @@
     PalletNonfungibleItemData: PalletNonfungibleItemData;
     PalletRefungibleError: PalletRefungibleError;
     PalletRefungibleItemData: PalletRefungibleItemData;
+    PalletRmrkCoreCall: PalletRmrkCoreCall;
+    PalletRmrkCoreError: PalletRmrkCoreError;
+    PalletRmrkCoreEvent: PalletRmrkCoreEvent;
+    PalletRmrkEquipCall: PalletRmrkEquipCall;
+    PalletRmrkEquipError: PalletRmrkEquipError;
+    PalletRmrkEquipEvent: PalletRmrkEquipEvent;
     PalletStructureCall: PalletStructureCall;
     PalletStructureError: PalletStructureError;
     PalletStructureEvent: PalletStructureEvent;
@@ -121,9 +133,14 @@
     PalletUniqueCall: PalletUniqueCall;
     PalletUniqueError: PalletUniqueError;
     PalletUniqueRawEvent: PalletUniqueRawEvent;
+    PalletUnqSchedulerCall: PalletUnqSchedulerCall;
+    PalletUnqSchedulerError: PalletUnqSchedulerError;
+    PalletUnqSchedulerEvent: PalletUnqSchedulerEvent;
+    PalletUnqSchedulerScheduledV3: PalletUnqSchedulerScheduledV3;
     PalletXcmCall: PalletXcmCall;
     PalletXcmError: PalletXcmError;
     PalletXcmEvent: PalletXcmEvent;
+    PalletXcmOrigin: PalletXcmOrigin;
     PhantomTypeUpDataStructs: PhantomTypeUpDataStructs;
     PolkadotCorePrimitivesInboundDownwardMessage: PolkadotCorePrimitivesInboundDownwardMessage;
     PolkadotCorePrimitivesInboundHrmpMessage: PolkadotCorePrimitivesInboundHrmpMessage;
@@ -133,9 +150,28 @@
     PolkadotPrimitivesV2AbridgedHrmpChannel: PolkadotPrimitivesV2AbridgedHrmpChannel;
     PolkadotPrimitivesV2PersistedValidationData: PolkadotPrimitivesV2PersistedValidationData;
     PolkadotPrimitivesV2UpgradeRestriction: PolkadotPrimitivesV2UpgradeRestriction;
+    RmrkTraitsBaseBaseInfo: RmrkTraitsBaseBaseInfo;
+    RmrkTraitsCollectionCollectionInfo: RmrkTraitsCollectionCollectionInfo;
+    RmrkTraitsNftAccountIdOrCollectionNftTuple: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    RmrkTraitsNftNftChild: RmrkTraitsNftNftChild;
+    RmrkTraitsNftNftInfo: RmrkTraitsNftNftInfo;
+    RmrkTraitsNftRoyaltyInfo: RmrkTraitsNftRoyaltyInfo;
+    RmrkTraitsPartEquippableList: RmrkTraitsPartEquippableList;
+    RmrkTraitsPartFixedPart: RmrkTraitsPartFixedPart;
+    RmrkTraitsPartPartType: RmrkTraitsPartPartType;
+    RmrkTraitsPartSlotPart: RmrkTraitsPartSlotPart;
+    RmrkTraitsPropertyPropertyInfo: RmrkTraitsPropertyPropertyInfo;
+    RmrkTraitsResourceBasicResource: RmrkTraitsResourceBasicResource;
+    RmrkTraitsResourceComposableResource: RmrkTraitsResourceComposableResource;
+    RmrkTraitsResourceResourceInfo: RmrkTraitsResourceResourceInfo;
+    RmrkTraitsResourceResourceTypes: RmrkTraitsResourceResourceTypes;
+    RmrkTraitsResourceSlotResource: RmrkTraitsResourceSlotResource;
+    RmrkTraitsTheme: RmrkTraitsTheme;
+    RmrkTraitsThemeThemeProperty: RmrkTraitsThemeThemeProperty;
     SpCoreEcdsaSignature: SpCoreEcdsaSignature;
     SpCoreEd25519Signature: SpCoreEd25519Signature;
     SpCoreSr25519Signature: SpCoreSr25519Signature;
+    SpCoreVoid: SpCoreVoid;
     SpRuntimeArithmeticError: SpRuntimeArithmeticError;
     SpRuntimeDigest: SpRuntimeDigest;
     SpRuntimeDigestDigestItem: SpRuntimeDigestDigestItem;
@@ -167,24 +203,6 @@
     UpDataStructsProperty: UpDataStructsProperty;
     UpDataStructsPropertyKeyPermission: UpDataStructsPropertyKeyPermission;
     UpDataStructsPropertyPermission: UpDataStructsPropertyPermission;
-    UpDataStructsRmrkAccountIdOrCollectionNftTuple: UpDataStructsRmrkAccountIdOrCollectionNftTuple;
-    UpDataStructsRmrkBaseInfo: UpDataStructsRmrkBaseInfo;
-    UpDataStructsRmrkBasicResource: UpDataStructsRmrkBasicResource;
-    UpDataStructsRmrkCollectionInfo: UpDataStructsRmrkCollectionInfo;
-    UpDataStructsRmrkComposableResource: UpDataStructsRmrkComposableResource;
-    UpDataStructsRmrkEquippableList: UpDataStructsRmrkEquippableList;
-    UpDataStructsRmrkFixedPart: UpDataStructsRmrkFixedPart;
-    UpDataStructsRmrkNftChild: UpDataStructsRmrkNftChild;
-    UpDataStructsRmrkNftInfo: UpDataStructsRmrkNftInfo;
-    UpDataStructsRmrkPartType: UpDataStructsRmrkPartType;
-    UpDataStructsRmrkPropertyInfo: UpDataStructsRmrkPropertyInfo;
-    UpDataStructsRmrkResourceInfo: UpDataStructsRmrkResourceInfo;
-    UpDataStructsRmrkResourceTypes: UpDataStructsRmrkResourceTypes;
-    UpDataStructsRmrkRoyaltyInfo: UpDataStructsRmrkRoyaltyInfo;
-    UpDataStructsRmrkSlotPart: UpDataStructsRmrkSlotPart;
-    UpDataStructsRmrkSlotResource: UpDataStructsRmrkSlotResource;
-    UpDataStructsRmrkTheme: UpDataStructsRmrkTheme;
-    UpDataStructsRmrkThemeProperty: UpDataStructsRmrkThemeProperty;
     UpDataStructsRpcCollection: UpDataStructsRpcCollection;
     UpDataStructsSponsoringRateLimit: UpDataStructsSponsoringRateLimit;
     UpDataStructsSponsorshipState: UpDataStructsSponsorshipState;
modifiedtests/src/interfaces/rmrk/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/rmrk/definitions.ts
+++ b/tests/src/interfaces/rmrk/definitions.ts
@@ -31,14 +31,14 @@
   types: {},
   rpc: {
     lastCollectionIdx: fn('Get the latest created collection id', [], 'u32'),
-    collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<UpDataStructsRmrkCollectionInfo>'),
+    collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<RmrkTraitsCollectionCollectionInfo>'),
     nftById: fn(
       'Get NFT by collection id and NFT id',
       [
         {name: 'collectionId', type: 'u32'},
         {name: 'nftId', type: 'u32'},
       ],
-      'Option<UpDataStructsRmrkNftInfo>',
+      'Option<RmrkTraitsNftNftInfo>',
     ),
     accountTokens: fn(
       'Get tokens owned by an account in a collection',
@@ -54,20 +54,24 @@
         {name: 'collectionId', type: 'u32'},
         {name: 'nftId', type: 'u32'},
       ],
-      'Vec<UpDataStructsRmrkNftChild>',
+      'Vec<RmrkTraitsNftNftChild>',
     ),
     collectionProperties: fn(
       'Get collection properties',
-      [{name: 'collectionId', type: 'u32'}],
-      'Vec<UpDataStructsRmrkPropertyInfo>',
+      [
+        {name: 'collectionId', type: 'u32'},
+        {name: 'filterKeys', type: 'Vec<String>', isOptional: true},
+      ],
+      'Vec<RmrkTraitsPropertyPropertyInfo>',
     ),
     nftProperties: fn(
       'Get NFT properties',
       [
         {name: 'collectionId', type: 'u32'},
         {name: 'nftId', type: 'u32'},
+        {name: 'filterKeys', type: 'Vec<String>', isOptional: true},
       ],
-      'Vec<UpDataStructsRmrkPropertyInfo>',
+      'Vec<RmrkTraitsPropertyPropertyInfo>',
     ),
     nftResources: fn(
       'Get NFT resources',
@@ -75,25 +79,26 @@
         {name: 'collectionId', type: 'u32'},
         {name: 'nftId', type: 'u32'},
       ],
-      'Vec<UpDataStructsRmrkResourceInfo>',
+      'Vec<RmrkTraitsResourceResourceInfo>',
     ),
-    nftResourcePriorities: fn(
+    nftResourcePriority: fn(
       'Get NFT resource priorities',
       [
         {name: 'collectionId', type: 'u32'},
         {name: 'nftId', type: 'u32'},
+        {name: 'resourceId', type: 'u32'},
       ],
-      'Vec<Bytes>',
+      'Option<u32>',
     ),
     base: fn(
       'Get base info',
       [{name: 'baseId', type: 'u32'}],
-      'Option<UpDataStructsRmrkBaseInfo>',
+      'Option<RmrkTraitsBaseBaseInfo>',
     ),
     baseParts: fn(
       'Get all Base\'s parts',
       [{name: 'baseId', type: 'u32'}],
-      'Vec<UpDataStructsRmrkPartType>',
+      'Vec<RmrkTraitsPartPartType>',
     ),
     themeNames: fn(
       'Get Base\'s theme names',
@@ -107,7 +112,7 @@
         {name: 'themeName', type: 'String'},
         {name: 'keys', type: 'Option<Vec<String>>'},
       ],
-      'Option<UpDataStructsRmrkTheme>',
+      'Option<RmrkTraitsTheme>',
     ),
   },
 };
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -161,14 +161,14 @@
     readonly amount: u128;
   }
 
-  /** @name PalletBalancesReleases (50) */
+  /** @name PalletBalancesReleases (51) */
   export interface PalletBalancesReleases extends Enum {
     readonly isV100: boolean;
     readonly isV200: boolean;
     readonly type: 'V100' | 'V200';
   }
 
-  /** @name PalletBalancesCall (51) */
+  /** @name PalletBalancesCall (52) */
   export interface PalletBalancesCall extends Enum {
     readonly isTransfer: boolean;
     readonly asTransfer: {
@@ -205,7 +205,7 @@
     readonly type: 'Transfer' | 'SetBalance' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve';
   }
 
-  /** @name PalletBalancesEvent (57) */
+  /** @name PalletBalancesEvent (58) */
   export interface PalletBalancesEvent extends Enum {
     readonly isEndowed: boolean;
     readonly asEndowed: {
@@ -264,14 +264,14 @@
     readonly type: 'Endowed' | 'DustLost' | 'Transfer' | 'BalanceSet' | 'Reserved' | 'Unreserved' | 'ReserveRepatriated' | 'Deposit' | 'Withdraw' | 'Slashed';
   }
 
-  /** @name FrameSupportTokensMiscBalanceStatus (58) */
+  /** @name FrameSupportTokensMiscBalanceStatus (59) */
   export interface FrameSupportTokensMiscBalanceStatus extends Enum {
     readonly isFree: boolean;
     readonly isReserved: boolean;
     readonly type: 'Free' | 'Reserved';
   }
 
-  /** @name PalletBalancesError (59) */
+  /** @name PalletBalancesError (60) */
   export interface PalletBalancesError extends Enum {
     readonly isVestingBalance: boolean;
     readonly isLiquidityRestrictions: boolean;
@@ -284,7 +284,7 @@
     readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'KeepAlive' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves';
   }
 
-  /** @name PalletTimestampCall (62) */
+  /** @name PalletTimestampCall (63) */
   export interface PalletTimestampCall extends Enum {
     readonly isSet: boolean;
     readonly asSet: {
@@ -293,14 +293,14 @@
     readonly type: 'Set';
   }
 
-  /** @name PalletTransactionPaymentReleases (65) */
+  /** @name PalletTransactionPaymentReleases (66) */
   export interface PalletTransactionPaymentReleases extends Enum {
     readonly isV1Ancient: boolean;
     readonly isV2: boolean;
     readonly type: 'V1Ancient' | 'V2';
   }
 
-  /** @name FrameSupportWeightsWeightToFeeCoefficient (67) */
+  /** @name FrameSupportWeightsWeightToFeeCoefficient (68) */
   export interface FrameSupportWeightsWeightToFeeCoefficient extends Struct {
     readonly coeffInteger: u128;
     readonly coeffFrac: Perbill;
@@ -308,7 +308,7 @@
     readonly degree: u8;
   }
 
-  /** @name PalletTreasuryProposal (69) */
+  /** @name PalletTreasuryProposal (70) */
   export interface PalletTreasuryProposal extends Struct {
     readonly proposer: AccountId32;
     readonly value: u128;
@@ -316,7 +316,7 @@
     readonly bond: u128;
   }
 
-  /** @name PalletTreasuryCall (72) */
+  /** @name PalletTreasuryCall (73) */
   export interface PalletTreasuryCall extends Enum {
     readonly isProposeSpend: boolean;
     readonly asProposeSpend: {
@@ -331,10 +331,14 @@
     readonly asApproveProposal: {
       readonly proposalId: Compact<u32>;
     } & Struct;
-    readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal';
+    readonly isRemoveApproval: boolean;
+    readonly asRemoveApproval: {
+      readonly proposalId: Compact<u32>;
+    } & Struct;
+    readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal' | 'RemoveApproval';
   }
 
-  /** @name PalletTreasuryEvent (74) */
+  /** @name PalletTreasuryEvent (75) */
   export interface PalletTreasuryEvent extends Enum {
     readonly isProposed: boolean;
     readonly asProposed: {
@@ -370,18 +374,19 @@
     readonly type: 'Proposed' | 'Spending' | 'Awarded' | 'Rejected' | 'Burnt' | 'Rollover' | 'Deposit';
   }
 
-  /** @name FrameSupportPalletId (77) */
+  /** @name FrameSupportPalletId (78) */
   export interface FrameSupportPalletId extends U8aFixed {}
 
-  /** @name PalletTreasuryError (78) */
+  /** @name PalletTreasuryError (79) */
   export interface PalletTreasuryError extends Enum {
     readonly isInsufficientProposersBalance: boolean;
     readonly isInvalidIndex: boolean;
     readonly isTooManyApprovals: boolean;
-    readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals';
+    readonly isProposalNotApproved: boolean;
+    readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals' | 'ProposalNotApproved';
   }
 
-  /** @name PalletSudoCall (79) */
+  /** @name PalletSudoCall (80) */
   export interface PalletSudoCall extends Enum {
     readonly isSudo: boolean;
     readonly asSudo: {
@@ -404,7 +409,7 @@
     readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs';
   }
 
-  /** @name FrameSystemCall (81) */
+  /** @name FrameSystemCall (82) */
   export interface FrameSystemCall extends Enum {
     readonly isFillBlock: boolean;
     readonly asFillBlock: {
@@ -446,7 +451,7 @@
     readonly type: 'FillBlock' | 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent';
   }
 
-  /** @name OrmlVestingModuleCall (84) */
+  /** @name OrmlVestingModuleCall (85) */
   export interface OrmlVestingModuleCall extends Enum {
     readonly isClaim: boolean;
     readonly isVestedTransfer: boolean;
@@ -466,7 +471,7 @@
     readonly type: 'Claim' | 'VestedTransfer' | 'UpdateVestingSchedules' | 'ClaimFor';
   }
 
-  /** @name OrmlVestingVestingSchedule (85) */
+  /** @name OrmlVestingVestingSchedule (86) */
   export interface OrmlVestingVestingSchedule extends Struct {
     readonly start: u32;
     readonly period: u32;
@@ -474,7 +479,7 @@
     readonly perPeriod: Compact<u128>;
   }
 
-  /** @name CumulusPalletXcmpQueueCall (87) */
+  /** @name CumulusPalletXcmpQueueCall (88) */
   export interface CumulusPalletXcmpQueueCall extends Enum {
     readonly isServiceOverweight: boolean;
     readonly asServiceOverweight: {
@@ -510,7 +515,7 @@
     readonly type: 'ServiceOverweight' | 'SuspendXcmExecution' | 'ResumeXcmExecution' | 'UpdateSuspendThreshold' | 'UpdateDropThreshold' | 'UpdateResumeThreshold' | 'UpdateThresholdWeight' | 'UpdateWeightRestrictDecay' | 'UpdateXcmpMaxIndividualWeight';
   }
 
-  /** @name PalletXcmCall (88) */
+  /** @name PalletXcmCall (89) */
   export interface PalletXcmCall extends Enum {
     readonly isSend: boolean;
     readonly asSend: {
@@ -572,7 +577,7 @@
     readonly type: 'Send' | 'TeleportAssets' | 'ReserveTransferAssets' | 'Execute' | 'ForceXcmVersion' | 'ForceDefaultXcmVersion' | 'ForceSubscribeVersionNotify' | 'ForceUnsubscribeVersionNotify' | 'LimitedReserveTransferAssets' | 'LimitedTeleportAssets';
   }
 
-  /** @name XcmVersionedMultiLocation (89) */
+  /** @name XcmVersionedMultiLocation (90) */
   export interface XcmVersionedMultiLocation extends Enum {
     readonly isV0: boolean;
     readonly asV0: XcmV0MultiLocation;
@@ -581,7 +586,7 @@
     readonly type: 'V0' | 'V1';
   }
 
-  /** @name XcmV0MultiLocation (90) */
+  /** @name XcmV0MultiLocation (91) */
   export interface XcmV0MultiLocation extends Enum {
     readonly isNull: boolean;
     readonly isX1: boolean;
@@ -603,7 +608,7 @@
     readonly type: 'Null' | 'X1' | 'X2' | 'X3' | 'X4' | 'X5' | 'X6' | 'X7' | 'X8';
   }
 
-  /** @name XcmV0Junction (91) */
+  /** @name XcmV0Junction (92) */
   export interface XcmV0Junction extends Enum {
     readonly isParent: boolean;
     readonly isParachain: boolean;
@@ -638,7 +643,7 @@
     readonly type: 'Parent' | 'Parachain' | 'AccountId32' | 'AccountIndex64' | 'AccountKey20' | 'PalletInstance' | 'GeneralIndex' | 'GeneralKey' | 'OnlyChild' | 'Plurality';
   }
 
-  /** @name XcmV0JunctionNetworkId (92) */
+  /** @name XcmV0JunctionNetworkId (93) */
   export interface XcmV0JunctionNetworkId extends Enum {
     readonly isAny: boolean;
     readonly isNamed: boolean;
@@ -648,7 +653,7 @@
     readonly type: 'Any' | 'Named' | 'Polkadot' | 'Kusama';
   }
 
-  /** @name XcmV0JunctionBodyId (93) */
+  /** @name XcmV0JunctionBodyId (94) */
   export interface XcmV0JunctionBodyId extends Enum {
     readonly isUnit: boolean;
     readonly isNamed: boolean;
@@ -662,7 +667,7 @@
     readonly type: 'Unit' | 'Named' | 'Index' | 'Executive' | 'Technical' | 'Legislative' | 'Judicial';
   }
 
-  /** @name XcmV0JunctionBodyPart (94) */
+  /** @name XcmV0JunctionBodyPart (95) */
   export interface XcmV0JunctionBodyPart extends Enum {
     readonly isVoice: boolean;
     readonly isMembers: boolean;
@@ -687,13 +692,13 @@
     readonly type: 'Voice' | 'Members' | 'Fraction' | 'AtLeastProportion' | 'MoreThanProportion';
   }
 
-  /** @name XcmV1MultiLocation (95) */
+  /** @name XcmV1MultiLocation (96) */
   export interface XcmV1MultiLocation extends Struct {
     readonly parents: u8;
     readonly interior: XcmV1MultilocationJunctions;
   }
 
-  /** @name XcmV1MultilocationJunctions (96) */
+  /** @name XcmV1MultilocationJunctions (97) */
   export interface XcmV1MultilocationJunctions extends Enum {
     readonly isHere: boolean;
     readonly isX1: boolean;
@@ -715,7 +720,7 @@
     readonly type: 'Here' | 'X1' | 'X2' | 'X3' | 'X4' | 'X5' | 'X6' | 'X7' | 'X8';
   }
 
-  /** @name XcmV1Junction (97) */
+  /** @name XcmV1Junction (98) */
   export interface XcmV1Junction extends Enum {
     readonly isParachain: boolean;
     readonly asParachain: Compact<u32>;
@@ -749,7 +754,7 @@
     readonly type: 'Parachain' | 'AccountId32' | 'AccountIndex64' | 'AccountKey20' | 'PalletInstance' | 'GeneralIndex' | 'GeneralKey' | 'OnlyChild' | 'Plurality';
   }
 
-  /** @name XcmVersionedXcm (98) */
+  /** @name XcmVersionedXcm (99) */
   export interface XcmVersionedXcm extends Enum {
     readonly isV0: boolean;
     readonly asV0: XcmV0Xcm;
@@ -760,7 +765,7 @@
     readonly type: 'V0' | 'V1' | 'V2';
   }
 
-  /** @name XcmV0Xcm (99) */
+  /** @name XcmV0Xcm (100) */
   export interface XcmV0Xcm extends Enum {
     readonly isWithdrawAsset: boolean;
     readonly asWithdrawAsset: {
@@ -823,7 +828,7 @@
     readonly type: 'WithdrawAsset' | 'ReserveAssetDeposit' | 'TeleportAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom';
   }
 
-  /** @name XcmV0MultiAsset (101) */
+  /** @name XcmV0MultiAsset (102) */
   export interface XcmV0MultiAsset extends Enum {
     readonly isNone: boolean;
     readonly isAll: boolean;
@@ -868,7 +873,7 @@
     readonly type: 'None' | 'All' | 'AllFungible' | 'AllNonFungible' | 'AllAbstractFungible' | 'AllAbstractNonFungible' | 'AllConcreteFungible' | 'AllConcreteNonFungible' | 'AbstractFungible' | 'AbstractNonFungible' | 'ConcreteFungible' | 'ConcreteNonFungible';
   }
 
-  /** @name XcmV1MultiassetAssetInstance (102) */
+  /** @name XcmV1MultiassetAssetInstance (103) */
   export interface XcmV1MultiassetAssetInstance extends Enum {
     readonly isUndefined: boolean;
     readonly isIndex: boolean;
@@ -1643,13 +1648,251 @@
     readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;
   }
 
-  /** @name PalletTemplateTransactionPaymentCall (204) */
+  /** @name PalletUnqSchedulerCall (204) */
+  export interface PalletUnqSchedulerCall extends Enum {
+    readonly isScheduleNamed: boolean;
+    readonly asScheduleNamed: {
+      readonly id: U8aFixed;
+      readonly when: u32;
+      readonly maybePeriodic: Option<ITuple<[u32, u32]>>;
+      readonly priority: u8;
+      readonly call: FrameSupportScheduleMaybeHashed;
+    } & Struct;
+    readonly isCancelNamed: boolean;
+    readonly asCancelNamed: {
+      readonly id: U8aFixed;
+    } & Struct;
+    readonly isScheduleNamedAfter: boolean;
+    readonly asScheduleNamedAfter: {
+      readonly id: U8aFixed;
+      readonly after: u32;
+      readonly maybePeriodic: Option<ITuple<[u32, u32]>>;
+      readonly priority: u8;
+      readonly call: FrameSupportScheduleMaybeHashed;
+    } & Struct;
+    readonly type: 'ScheduleNamed' | 'CancelNamed' | 'ScheduleNamedAfter';
+  }
+
+  /** @name FrameSupportScheduleMaybeHashed (206) */
+  export interface FrameSupportScheduleMaybeHashed extends Enum {
+    readonly isValue: boolean;
+    readonly asValue: Call;
+    readonly isHash: boolean;
+    readonly asHash: H256;
+    readonly type: 'Value' | 'Hash';
+  }
+
+  /** @name PalletTemplateTransactionPaymentCall (207) */
   export type PalletTemplateTransactionPaymentCall = Null;
 
-  /** @name PalletStructureCall (205) */
+  /** @name PalletStructureCall (208) */
   export type PalletStructureCall = Null;
 
-  /** @name PalletEvmCall (206) */
+  /** @name PalletRmrkCoreCall (209) */
+  export interface PalletRmrkCoreCall extends Enum {
+    readonly isCreateCollection: boolean;
+    readonly asCreateCollection: {
+      readonly metadata: Bytes;
+      readonly max: Option<u32>;
+      readonly symbol: Bytes;
+    } & Struct;
+    readonly isDestroyCollection: boolean;
+    readonly asDestroyCollection: {
+      readonly collectionId: u32;
+    } & Struct;
+    readonly isChangeCollectionIssuer: boolean;
+    readonly asChangeCollectionIssuer: {
+      readonly collectionId: u32;
+      readonly newIssuer: MultiAddress;
+    } & Struct;
+    readonly isLockCollection: boolean;
+    readonly asLockCollection: {
+      readonly collectionId: u32;
+    } & Struct;
+    readonly isMintNft: boolean;
+    readonly asMintNft: {
+      readonly owner: AccountId32;
+      readonly collectionId: u32;
+      readonly recipient: Option<AccountId32>;
+      readonly royaltyAmount: Option<Permill>;
+      readonly metadata: Bytes;
+      readonly transferable: bool;
+    } & Struct;
+    readonly isBurnNft: boolean;
+    readonly asBurnNft: {
+      readonly collectionId: u32;
+      readonly nftId: u32;
+    } & Struct;
+    readonly isSend: boolean;
+    readonly asSend: {
+      readonly rmrkCollectionId: u32;
+      readonly rmrkNftId: u32;
+      readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    } & Struct;
+    readonly isAcceptNft: boolean;
+    readonly asAcceptNft: {
+      readonly rmrkCollectionId: u32;
+      readonly rmrkNftId: u32;
+      readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    } & Struct;
+    readonly isRejectNft: boolean;
+    readonly asRejectNft: {
+      readonly rmrkCollectionId: u32;
+      readonly rmrkNftId: u32;
+    } & Struct;
+    readonly isAcceptResource: boolean;
+    readonly asAcceptResource: {
+      readonly rmrkCollectionId: u32;
+      readonly rmrkNftId: u32;
+      readonly rmrkResourceId: u32;
+    } & Struct;
+    readonly isAcceptResourceRemoval: boolean;
+    readonly asAcceptResourceRemoval: {
+      readonly rmrkCollectionId: u32;
+      readonly rmrkNftId: u32;
+      readonly rmrkResourceId: u32;
+    } & Struct;
+    readonly isSetProperty: boolean;
+    readonly asSetProperty: {
+      readonly rmrkCollectionId: Compact<u32>;
+      readonly maybeNftId: Option<u32>;
+      readonly key: Bytes;
+      readonly value: Bytes;
+    } & Struct;
+    readonly isSetPriority: boolean;
+    readonly asSetPriority: {
+      readonly rmrkCollectionId: u32;
+      readonly rmrkNftId: u32;
+      readonly priorities: Vec<u32>;
+    } & Struct;
+    readonly isAddBasicResource: boolean;
+    readonly asAddBasicResource: {
+      readonly rmrkCollectionId: u32;
+      readonly nftId: u32;
+      readonly resource: RmrkTraitsResourceBasicResource;
+    } & Struct;
+    readonly isAddComposableResource: boolean;
+    readonly asAddComposableResource: {
+      readonly rmrkCollectionId: u32;
+      readonly nftId: u32;
+      readonly resourceId: Bytes;
+      readonly resource: RmrkTraitsResourceComposableResource;
+    } & Struct;
+    readonly isAddSlotResource: boolean;
+    readonly asAddSlotResource: {
+      readonly rmrkCollectionId: u32;
+      readonly nftId: u32;
+      readonly resource: RmrkTraitsResourceSlotResource;
+    } & Struct;
+    readonly isRemoveResource: boolean;
+    readonly asRemoveResource: {
+      readonly rmrkCollectionId: u32;
+      readonly nftId: u32;
+      readonly resourceId: u32;
+    } & Struct;
+    readonly type: 'CreateCollection' | 'DestroyCollection' | 'ChangeCollectionIssuer' | 'LockCollection' | 'MintNft' | 'BurnNft' | 'Send' | 'AcceptNft' | 'RejectNft' | 'AcceptResource' | 'AcceptResourceRemoval' | 'SetProperty' | 'SetPriority' | 'AddBasicResource' | 'AddComposableResource' | 'AddSlotResource' | 'RemoveResource';
+  }
+
+  /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (213) */
+  export interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {
+    readonly isAccountId: boolean;
+    readonly asAccountId: AccountId32;
+    readonly isCollectionAndNftTuple: boolean;
+    readonly asCollectionAndNftTuple: ITuple<[u32, u32]>;
+    readonly type: 'AccountId' | 'CollectionAndNftTuple';
+  }
+
+  /** @name RmrkTraitsResourceBasicResource (217) */
+  export interface RmrkTraitsResourceBasicResource extends Struct {
+    readonly src: Option<Bytes>;
+    readonly metadata: Option<Bytes>;
+    readonly license: Option<Bytes>;
+    readonly thumb: Option<Bytes>;
+  }
+
+  /** @name RmrkTraitsResourceComposableResource (220) */
+  export interface RmrkTraitsResourceComposableResource extends Struct {
+    readonly parts: Vec<u32>;
+    readonly base: u32;
+    readonly src: Option<Bytes>;
+    readonly metadata: Option<Bytes>;
+    readonly license: Option<Bytes>;
+    readonly thumb: Option<Bytes>;
+  }
+
+  /** @name RmrkTraitsResourceSlotResource (222) */
+  export interface RmrkTraitsResourceSlotResource extends Struct {
+    readonly base: u32;
+    readonly src: Option<Bytes>;
+    readonly metadata: Option<Bytes>;
+    readonly slot: u32;
+    readonly license: Option<Bytes>;
+    readonly thumb: Option<Bytes>;
+  }
+
+  /** @name PalletRmrkEquipCall (223) */
+  export interface PalletRmrkEquipCall extends Enum {
+    readonly isCreateBase: boolean;
+    readonly asCreateBase: {
+      readonly baseType: Bytes;
+      readonly symbol: Bytes;
+      readonly parts: Vec<RmrkTraitsPartPartType>;
+    } & Struct;
+    readonly isThemeAdd: boolean;
+    readonly asThemeAdd: {
+      readonly baseId: u32;
+      readonly theme: RmrkTraitsTheme;
+    } & Struct;
+    readonly type: 'CreateBase' | 'ThemeAdd';
+  }
+
+  /** @name RmrkTraitsPartPartType (225) */
+  export interface RmrkTraitsPartPartType extends Enum {
+    readonly isFixedPart: boolean;
+    readonly asFixedPart: RmrkTraitsPartFixedPart;
+    readonly isSlotPart: boolean;
+    readonly asSlotPart: RmrkTraitsPartSlotPart;
+    readonly type: 'FixedPart' | 'SlotPart';
+  }
+
+  /** @name RmrkTraitsPartFixedPart (227) */
+  export interface RmrkTraitsPartFixedPart extends Struct {
+    readonly id: u32;
+    readonly z: u32;
+    readonly src: Bytes;
+  }
+
+  /** @name RmrkTraitsPartSlotPart (228) */
+  export interface RmrkTraitsPartSlotPart extends Struct {
+    readonly id: u32;
+    readonly equippable: RmrkTraitsPartEquippableList;
+    readonly src: Bytes;
+    readonly z: u32;
+  }
+
+  /** @name RmrkTraitsPartEquippableList (229) */
+  export interface RmrkTraitsPartEquippableList extends Enum {
+    readonly isAll: boolean;
+    readonly isEmpty: boolean;
+    readonly isCustom: boolean;
+    readonly asCustom: Vec<u32>;
+    readonly type: 'All' | 'Empty' | 'Custom';
+  }
+
+  /** @name RmrkTraitsTheme (231) */
+  export interface RmrkTraitsTheme extends Struct {
+    readonly name: Bytes;
+    readonly properties: Vec<RmrkTraitsThemeThemeProperty>;
+    readonly inherit: bool;
+  }
+
+  /** @name RmrkTraitsThemeThemeProperty (233) */
+  export interface RmrkTraitsThemeThemeProperty extends Struct {
+    readonly key: Bytes;
+    readonly value: Bytes;
+  }
+
+  /** @name PalletEvmCall (234) */
   export interface PalletEvmCall extends Enum {
     readonly isWithdraw: boolean;
     readonly asWithdraw: {
@@ -1694,7 +1937,7 @@
     readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2';
   }
 
-  /** @name PalletEthereumCall (212) */
+  /** @name PalletEthereumCall (240) */
   export interface PalletEthereumCall extends Enum {
     readonly isTransact: boolean;
     readonly asTransact: {
@@ -1703,7 +1946,7 @@
     readonly type: 'Transact';
   }
 
-  /** @name EthereumTransactionTransactionV2 (213) */
+  /** @name EthereumTransactionTransactionV2 (241) */
   export interface EthereumTransactionTransactionV2 extends Enum {
     readonly isLegacy: boolean;
     readonly asLegacy: EthereumTransactionLegacyTransaction;
@@ -1714,7 +1957,7 @@
     readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';
   }
 
-  /** @name EthereumTransactionLegacyTransaction (214) */
+  /** @name EthereumTransactionLegacyTransaction (242) */
   export interface EthereumTransactionLegacyTransaction extends Struct {
     readonly nonce: U256;
     readonly gasPrice: U256;
@@ -1725,7 +1968,7 @@
     readonly signature: EthereumTransactionTransactionSignature;
   }
 
-  /** @name EthereumTransactionTransactionAction (215) */
+  /** @name EthereumTransactionTransactionAction (243) */
   export interface EthereumTransactionTransactionAction extends Enum {
     readonly isCall: boolean;
     readonly asCall: H160;
@@ -1733,14 +1976,14 @@
     readonly type: 'Call' | 'Create';
   }
 
-  /** @name EthereumTransactionTransactionSignature (216) */
+  /** @name EthereumTransactionTransactionSignature (244) */
   export interface EthereumTransactionTransactionSignature extends Struct {
     readonly v: u64;
     readonly r: H256;
     readonly s: H256;
   }
 
-  /** @name EthereumTransactionEip2930Transaction (218) */
+  /** @name EthereumTransactionEip2930Transaction (246) */
   export interface EthereumTransactionEip2930Transaction extends Struct {
     readonly chainId: u64;
     readonly nonce: U256;
@@ -1755,13 +1998,13 @@
     readonly s: H256;
   }
 
-  /** @name EthereumTransactionAccessListItem (220) */
+  /** @name EthereumTransactionAccessListItem (248) */
   export interface EthereumTransactionAccessListItem extends Struct {
     readonly address: H160;
     readonly storageKeys: Vec<H256>;
   }
 
-  /** @name EthereumTransactionEip1559Transaction (221) */
+  /** @name EthereumTransactionEip1559Transaction (249) */
   export interface EthereumTransactionEip1559Transaction extends Struct {
     readonly chainId: u64;
     readonly nonce: U256;
@@ -1777,7 +2020,7 @@
     readonly s: H256;
   }
 
-  /** @name PalletEvmMigrationCall (222) */
+  /** @name PalletEvmMigrationCall (250) */
   export interface PalletEvmMigrationCall extends Enum {
     readonly isBegin: boolean;
     readonly asBegin: {
@@ -1796,7 +2039,7 @@
     readonly type: 'Begin' | 'SetData' | 'Finish';
   }
 
-  /** @name PalletSudoEvent (225) */
+  /** @name PalletSudoEvent (253) */
   export interface PalletSudoEvent extends Enum {
     readonly isSudid: boolean;
     readonly asSudid: {
@@ -1813,7 +2056,7 @@
     readonly type: 'Sudid' | 'KeyChanged' | 'SudoAsDone';
   }
 
-  /** @name SpRuntimeDispatchError (227) */
+  /** @name SpRuntimeDispatchError (255) */
   export interface SpRuntimeDispatchError extends Enum {
     readonly isOther: boolean;
     readonly isCannotLookup: boolean;
@@ -1832,13 +2075,13 @@
     readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic' | 'Transactional';
   }
 
-  /** @name SpRuntimeModuleError (228) */
+  /** @name SpRuntimeModuleError (256) */
   export interface SpRuntimeModuleError extends Struct {
     readonly index: u8;
     readonly error: U8aFixed;
   }
 
-  /** @name SpRuntimeTokenError (229) */
+  /** @name SpRuntimeTokenError (257) */
   export interface SpRuntimeTokenError extends Enum {
     readonly isNoFunds: boolean;
     readonly isWouldDie: boolean;
@@ -1850,7 +2093,7 @@
     readonly type: 'NoFunds' | 'WouldDie' | 'BelowMinimum' | 'CannotCreate' | 'UnknownAsset' | 'Frozen' | 'Unsupported';
   }
 
-  /** @name SpRuntimeArithmeticError (230) */
+  /** @name SpRuntimeArithmeticError (258) */
   export interface SpRuntimeArithmeticError extends Enum {
     readonly isUnderflow: boolean;
     readonly isOverflow: boolean;
@@ -1858,20 +2101,20 @@
     readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero';
   }
 
-  /** @name SpRuntimeTransactionalError (231) */
+  /** @name SpRuntimeTransactionalError (259) */
   export interface SpRuntimeTransactionalError extends Enum {
     readonly isLimitReached: boolean;
     readonly isNoLayer: boolean;
     readonly type: 'LimitReached' | 'NoLayer';
   }
 
-  /** @name PalletSudoError (232) */
+  /** @name PalletSudoError (260) */
   export interface PalletSudoError extends Enum {
     readonly isRequireSudo: boolean;
     readonly type: 'RequireSudo';
   }
 
-  /** @name FrameSystemAccountInfo (233) */
+  /** @name FrameSystemAccountInfo (261) */
   export interface FrameSystemAccountInfo extends Struct {
     readonly nonce: u32;
     readonly consumers: u32;
@@ -1880,19 +2123,19 @@
     readonly data: PalletBalancesAccountData;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassU64 (234) */
+  /** @name FrameSupportWeightsPerDispatchClassU64 (262) */
   export interface FrameSupportWeightsPerDispatchClassU64 extends Struct {
     readonly normal: u64;
     readonly operational: u64;
     readonly mandatory: u64;
   }
 
-  /** @name SpRuntimeDigest (235) */
+  /** @name SpRuntimeDigest (263) */
   export interface SpRuntimeDigest extends Struct {
     readonly logs: Vec<SpRuntimeDigestDigestItem>;
   }
 
-  /** @name SpRuntimeDigestDigestItem (237) */
+  /** @name SpRuntimeDigestDigestItem (265) */
   export interface SpRuntimeDigestDigestItem extends Enum {
     readonly isOther: boolean;
     readonly asOther: Bytes;
@@ -1906,14 +2149,14 @@
     readonly type: 'Other' | 'Consensus' | 'Seal' | 'PreRuntime' | 'RuntimeEnvironmentUpdated';
   }
 
-  /** @name FrameSystemEventRecord (239) */
+  /** @name FrameSystemEventRecord (267) */
   export interface FrameSystemEventRecord extends Struct {
     readonly phase: FrameSystemPhase;
     readonly event: Event;
     readonly topics: Vec<H256>;
   }
 
-  /** @name FrameSystemEvent (241) */
+  /** @name FrameSystemEvent (269) */
   export interface FrameSystemEvent extends Enum {
     readonly isExtrinsicSuccess: boolean;
     readonly asExtrinsicSuccess: {
@@ -1941,14 +2184,14 @@
     readonly type: 'ExtrinsicSuccess' | 'ExtrinsicFailed' | 'CodeUpdated' | 'NewAccount' | 'KilledAccount' | 'Remarked';
   }
 
-  /** @name FrameSupportWeightsDispatchInfo (242) */
+  /** @name FrameSupportWeightsDispatchInfo (270) */
   export interface FrameSupportWeightsDispatchInfo extends Struct {
     readonly weight: u64;
     readonly class: FrameSupportWeightsDispatchClass;
     readonly paysFee: FrameSupportWeightsPays;
   }
 
-  /** @name FrameSupportWeightsDispatchClass (243) */
+  /** @name FrameSupportWeightsDispatchClass (271) */
   export interface FrameSupportWeightsDispatchClass extends Enum {
     readonly isNormal: boolean;
     readonly isOperational: boolean;
@@ -1956,14 +2199,14 @@
     readonly type: 'Normal' | 'Operational' | 'Mandatory';
   }
 
-  /** @name FrameSupportWeightsPays (244) */
+  /** @name FrameSupportWeightsPays (272) */
   export interface FrameSupportWeightsPays extends Enum {
     readonly isYes: boolean;
     readonly isNo: boolean;
     readonly type: 'Yes' | 'No';
   }
 
-  /** @name OrmlVestingModuleEvent (245) */
+  /** @name OrmlVestingModuleEvent (273) */
   export interface OrmlVestingModuleEvent extends Enum {
     readonly isVestingScheduleAdded: boolean;
     readonly asVestingScheduleAdded: {
@@ -1983,7 +2226,7 @@
     readonly type: 'VestingScheduleAdded' | 'Claimed' | 'VestingSchedulesUpdated';
   }
 
-  /** @name CumulusPalletXcmpQueueEvent (246) */
+  /** @name CumulusPalletXcmpQueueEvent (274) */
   export interface CumulusPalletXcmpQueueEvent extends Enum {
     readonly isSuccess: boolean;
     readonly asSuccess: Option<H256>;
@@ -2004,7 +2247,7 @@
     readonly type: 'Success' | 'Fail' | 'BadVersion' | 'BadFormat' | 'UpwardMessageSent' | 'XcmpMessageSent' | 'OverweightEnqueued' | 'OverweightServiced';
   }
 
-  /** @name PalletXcmEvent (247) */
+  /** @name PalletXcmEvent (275) */
   export interface PalletXcmEvent extends Enum {
     readonly isAttempted: boolean;
     readonly asAttempted: XcmV2TraitsOutcome;
@@ -2041,7 +2284,7 @@
     readonly type: 'Attempted' | 'Sent' | 'UnexpectedResponse' | 'ResponseReady' | 'Notified' | 'NotifyOverweight' | 'NotifyDispatchError' | 'NotifyDecodeFailed' | 'InvalidResponder' | 'InvalidResponderVersion' | 'ResponseTaken' | 'AssetsTrapped' | 'VersionChangeNotified' | 'SupportedVersionChanged' | 'NotifyTargetSendFail' | 'NotifyTargetMigrationFail';
   }
 
-  /** @name XcmV2TraitsOutcome (248) */
+  /** @name XcmV2TraitsOutcome (276) */
   export interface XcmV2TraitsOutcome extends Enum {
     readonly isComplete: boolean;
     readonly asComplete: u64;
@@ -2052,7 +2295,7 @@
     readonly type: 'Complete' | 'Incomplete' | 'Error';
   }
 
-  /** @name CumulusPalletXcmEvent (250) */
+  /** @name CumulusPalletXcmEvent (278) */
   export interface CumulusPalletXcmEvent extends Enum {
     readonly isInvalidFormat: boolean;
     readonly asInvalidFormat: U8aFixed;
@@ -2063,7 +2306,7 @@
     readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward';
   }
 
-  /** @name CumulusPalletDmpQueueEvent (251) */
+  /** @name CumulusPalletDmpQueueEvent (279) */
   export interface CumulusPalletDmpQueueEvent extends Enum {
     readonly isInvalidFormat: boolean;
     readonly asInvalidFormat: U8aFixed;
@@ -2080,7 +2323,7 @@
     readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward' | 'WeightExhausted' | 'OverweightEnqueued' | 'OverweightServiced';
   }
 
-  /** @name PalletUniqueRawEvent (252) */
+  /** @name PalletUniqueRawEvent (280) */
   export interface PalletUniqueRawEvent extends Enum {
     readonly isCollectionSponsorRemoved: boolean;
     readonly asCollectionSponsorRemoved: u32;
@@ -2105,7 +2348,41 @@
     readonly type: 'CollectionSponsorRemoved' | 'CollectionAdminAdded' | 'CollectionOwnedChanged' | 'CollectionSponsorSet' | 'SponsorshipConfirmed' | 'CollectionAdminRemoved' | 'AllowListAddressRemoved' | 'AllowListAddressAdded' | 'CollectionLimitSet' | 'CollectionPermissionSet';
   }
 
-  /** @name PalletCommonEvent (253) */
+  /** @name PalletUnqSchedulerEvent (281) */
+  export interface PalletUnqSchedulerEvent extends Enum {
+    readonly isScheduled: boolean;
+    readonly asScheduled: {
+      readonly when: u32;
+      readonly index: u32;
+    } & Struct;
+    readonly isCanceled: boolean;
+    readonly asCanceled: {
+      readonly when: u32;
+      readonly index: u32;
+    } & Struct;
+    readonly isDispatched: boolean;
+    readonly asDispatched: {
+      readonly task: ITuple<[u32, u32]>;
+      readonly id: Option<U8aFixed>;
+      readonly result: Result<Null, SpRuntimeDispatchError>;
+    } & Struct;
+    readonly isCallLookupFailed: boolean;
+    readonly asCallLookupFailed: {
+      readonly task: ITuple<[u32, u32]>;
+      readonly id: Option<U8aFixed>;
+      readonly error: FrameSupportScheduleLookupError;
+    } & Struct;
+    readonly type: 'Scheduled' | 'Canceled' | 'Dispatched' | 'CallLookupFailed';
+  }
+
+  /** @name FrameSupportScheduleLookupError (283) */
+  export interface FrameSupportScheduleLookupError extends Enum {
+    readonly isUnknown: boolean;
+    readonly isBadFormat: boolean;
+    readonly type: 'Unknown' | 'BadFormat';
+  }
+
+  /** @name PalletCommonEvent (284) */
   export interface PalletCommonEvent extends Enum {
     readonly isCollectionCreated: boolean;
     readonly asCollectionCreated: ITuple<[u32, u8, AccountId32]>;
@@ -2132,14 +2409,114 @@
     readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
   }
 
-  /** @name PalletStructureEvent (254) */
+  /** @name PalletStructureEvent (285) */
   export interface PalletStructureEvent extends Enum {
     readonly isExecuted: boolean;
     readonly asExecuted: Result<Null, SpRuntimeDispatchError>;
     readonly type: 'Executed';
   }
 
-  /** @name PalletEvmEvent (255) */
+  /** @name PalletRmrkCoreEvent (286) */
+  export interface PalletRmrkCoreEvent extends Enum {
+    readonly isCollectionCreated: boolean;
+    readonly asCollectionCreated: {
+      readonly issuer: AccountId32;
+      readonly collectionId: u32;
+    } & Struct;
+    readonly isCollectionDestroyed: boolean;
+    readonly asCollectionDestroyed: {
+      readonly issuer: AccountId32;
+      readonly collectionId: u32;
+    } & Struct;
+    readonly isIssuerChanged: boolean;
+    readonly asIssuerChanged: {
+      readonly oldIssuer: AccountId32;
+      readonly newIssuer: AccountId32;
+      readonly collectionId: u32;
+    } & Struct;
+    readonly isCollectionLocked: boolean;
+    readonly asCollectionLocked: {
+      readonly issuer: AccountId32;
+      readonly collectionId: u32;
+    } & Struct;
+    readonly isNftMinted: boolean;
+    readonly asNftMinted: {
+      readonly owner: AccountId32;
+      readonly collectionId: u32;
+      readonly nftId: u32;
+    } & Struct;
+    readonly isNftBurned: boolean;
+    readonly asNftBurned: {
+      readonly owner: AccountId32;
+      readonly nftId: u32;
+    } & Struct;
+    readonly isNftSent: boolean;
+    readonly asNftSent: {
+      readonly sender: AccountId32;
+      readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+      readonly collectionId: u32;
+      readonly nftId: u32;
+      readonly approvalRequired: bool;
+    } & Struct;
+    readonly isNftAccepted: boolean;
+    readonly asNftAccepted: {
+      readonly sender: AccountId32;
+      readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+      readonly collectionId: u32;
+      readonly nftId: u32;
+    } & Struct;
+    readonly isNftRejected: boolean;
+    readonly asNftRejected: {
+      readonly sender: AccountId32;
+      readonly collectionId: u32;
+      readonly nftId: u32;
+    } & Struct;
+    readonly isPropertySet: boolean;
+    readonly asPropertySet: {
+      readonly collectionId: u32;
+      readonly maybeNftId: Option<u32>;
+      readonly key: Bytes;
+      readonly value: Bytes;
+    } & Struct;
+    readonly isResourceAdded: boolean;
+    readonly asResourceAdded: {
+      readonly nftId: u32;
+      readonly resourceId: u32;
+    } & Struct;
+    readonly isResourceRemoval: boolean;
+    readonly asResourceRemoval: {
+      readonly nftId: u32;
+      readonly resourceId: u32;
+    } & Struct;
+    readonly isResourceAccepted: boolean;
+    readonly asResourceAccepted: {
+      readonly nftId: u32;
+      readonly resourceId: u32;
+    } & Struct;
+    readonly isResourceRemovalAccepted: boolean;
+    readonly asResourceRemovalAccepted: {
+      readonly nftId: u32;
+      readonly resourceId: u32;
+    } & Struct;
+    readonly isPrioritySet: boolean;
+    readonly asPrioritySet: {
+      readonly collectionId: u32;
+      readonly nftId: u32;
+    } & Struct;
+    readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';
+  }
+
+  /** @name PalletRmrkEquipEvent (287) */
+  export interface PalletRmrkEquipEvent extends Enum {
+    readonly isBaseCreated: boolean;
+    readonly asBaseCreated: {
+      readonly issuer: AccountId32;
+      readonly baseId: u32;
+    } & Struct;
+    readonly type: 'BaseCreated';
+  }
+
+  /** @name PalletEvmEvent (288) */
   export interface PalletEvmEvent extends Enum {
     readonly isLog: boolean;
     readonly asLog: EthereumLog;
@@ -2158,21 +2535,21 @@
     readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
   }
 
-  /** @name EthereumLog (256) */
+  /** @name EthereumLog (289) */
   export interface EthereumLog extends Struct {
     readonly address: H160;
     readonly topics: Vec<H256>;
     readonly data: Bytes;
   }
 
-  /** @name PalletEthereumEvent (257) */
+  /** @name PalletEthereumEvent (290) */
   export interface PalletEthereumEvent extends Enum {
     readonly isExecuted: boolean;
     readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
     readonly type: 'Executed';
   }
 
-  /** @name EvmCoreErrorExitReason (258) */
+  /** @name EvmCoreErrorExitReason (291) */
   export interface EvmCoreErrorExitReason extends Enum {
     readonly isSucceed: boolean;
     readonly asSucceed: EvmCoreErrorExitSucceed;
@@ -2185,7 +2562,7 @@
     readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';
   }
 
-  /** @name EvmCoreErrorExitSucceed (259) */
+  /** @name EvmCoreErrorExitSucceed (292) */
   export interface EvmCoreErrorExitSucceed extends Enum {
     readonly isStopped: boolean;
     readonly isReturned: boolean;
@@ -2193,7 +2570,7 @@
     readonly type: 'Stopped' | 'Returned' | 'Suicided';
   }
 
-  /** @name EvmCoreErrorExitError (260) */
+  /** @name EvmCoreErrorExitError (293) */
   export interface EvmCoreErrorExitError extends Enum {
     readonly isStackUnderflow: boolean;
     readonly isStackOverflow: boolean;
@@ -2214,13 +2591,13 @@
     readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other' | 'InvalidCode';
   }
 
-  /** @name EvmCoreErrorExitRevert (263) */
+  /** @name EvmCoreErrorExitRevert (296) */
   export interface EvmCoreErrorExitRevert extends Enum {
     readonly isReverted: boolean;
     readonly type: 'Reverted';
   }
 
-  /** @name EvmCoreErrorExitFatal (264) */
+  /** @name EvmCoreErrorExitFatal (297) */
   export interface EvmCoreErrorExitFatal extends Enum {
     readonly isNotSupported: boolean;
     readonly isUnhandledInterrupt: boolean;
@@ -2231,7 +2608,7 @@
     readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';
   }
 
-  /** @name FrameSystemPhase (265) */
+  /** @name FrameSystemPhase (298) */
   export interface FrameSystemPhase extends Enum {
     readonly isApplyExtrinsic: boolean;
     readonly asApplyExtrinsic: u32;
@@ -2240,27 +2617,27 @@
     readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';
   }
 
-  /** @name FrameSystemLastRuntimeUpgradeInfo (267) */
+  /** @name FrameSystemLastRuntimeUpgradeInfo (300) */
   export interface FrameSystemLastRuntimeUpgradeInfo extends Struct {
     readonly specVersion: Compact<u32>;
     readonly specName: Text;
   }
 
-  /** @name FrameSystemLimitsBlockWeights (268) */
+  /** @name FrameSystemLimitsBlockWeights (301) */
   export interface FrameSystemLimitsBlockWeights extends Struct {
     readonly baseBlock: u64;
     readonly maxBlock: u64;
     readonly perClass: FrameSupportWeightsPerDispatchClassWeightsPerClass;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassWeightsPerClass (269) */
+  /** @name FrameSupportWeightsPerDispatchClassWeightsPerClass (302) */
   export interface FrameSupportWeightsPerDispatchClassWeightsPerClass extends Struct {
     readonly normal: FrameSystemLimitsWeightsPerClass;
     readonly operational: FrameSystemLimitsWeightsPerClass;
     readonly mandatory: FrameSystemLimitsWeightsPerClass;
   }
 
-  /** @name FrameSystemLimitsWeightsPerClass (270) */
+  /** @name FrameSystemLimitsWeightsPerClass (303) */
   export interface FrameSystemLimitsWeightsPerClass extends Struct {
     readonly baseExtrinsic: u64;
     readonly maxExtrinsic: Option<u64>;
@@ -2268,25 +2645,25 @@
     readonly reserved: Option<u64>;
   }
 
-  /** @name FrameSystemLimitsBlockLength (272) */
+  /** @name FrameSystemLimitsBlockLength (305) */
   export interface FrameSystemLimitsBlockLength extends Struct {
     readonly max: FrameSupportWeightsPerDispatchClassU32;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassU32 (273) */
+  /** @name FrameSupportWeightsPerDispatchClassU32 (306) */
   export interface FrameSupportWeightsPerDispatchClassU32 extends Struct {
     readonly normal: u32;
     readonly operational: u32;
     readonly mandatory: u32;
   }
 
-  /** @name FrameSupportWeightsRuntimeDbWeight (274) */
+  /** @name FrameSupportWeightsRuntimeDbWeight (307) */
   export interface FrameSupportWeightsRuntimeDbWeight extends Struct {
     readonly read: u64;
     readonly write: u64;
   }
 
-  /** @name SpVersionRuntimeVersion (275) */
+  /** @name SpVersionRuntimeVersion (308) */
   export interface SpVersionRuntimeVersion extends Struct {
     readonly specName: Text;
     readonly implName: Text;
@@ -2298,7 +2675,7 @@
     readonly stateVersion: u8;
   }
 
-  /** @name FrameSystemError (279) */
+  /** @name FrameSystemError (312) */
   export interface FrameSystemError extends Enum {
     readonly isInvalidSpecName: boolean;
     readonly isSpecVersionNeedsToIncrease: boolean;
@@ -2309,7 +2686,7 @@
     readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';
   }
 
-  /** @name OrmlVestingModuleError (281) */
+  /** @name OrmlVestingModuleError (314) */
   export interface OrmlVestingModuleError extends Enum {
     readonly isZeroVestingPeriod: boolean;
     readonly isZeroVestingPeriodCount: boolean;
@@ -2320,21 +2697,21 @@
     readonly type: 'ZeroVestingPeriod' | 'ZeroVestingPeriodCount' | 'InsufficientBalanceToLock' | 'TooManyVestingSchedules' | 'AmountLow' | 'MaxVestingSchedulesExceeded';
   }
 
-  /** @name CumulusPalletXcmpQueueInboundChannelDetails (283) */
+  /** @name CumulusPalletXcmpQueueInboundChannelDetails (316) */
   export interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct {
     readonly sender: u32;
     readonly state: CumulusPalletXcmpQueueInboundState;
     readonly messageMetadata: Vec<ITuple<[u32, PolkadotParachainPrimitivesXcmpMessageFormat]>>;
   }
 
-  /** @name CumulusPalletXcmpQueueInboundState (284) */
+  /** @name CumulusPalletXcmpQueueInboundState (317) */
   export interface CumulusPalletXcmpQueueInboundState extends Enum {
     readonly isOk: boolean;
     readonly isSuspended: boolean;
     readonly type: 'Ok' | 'Suspended';
   }
 
-  /** @name PolkadotParachainPrimitivesXcmpMessageFormat (287) */
+  /** @name PolkadotParachainPrimitivesXcmpMessageFormat (320) */
   export interface PolkadotParachainPrimitivesXcmpMessageFormat extends Enum {
     readonly isConcatenatedVersionedXcm: boolean;
     readonly isConcatenatedEncodedBlob: boolean;
@@ -2342,7 +2719,7 @@
     readonly type: 'ConcatenatedVersionedXcm' | 'ConcatenatedEncodedBlob' | 'Signals';
   }
 
-  /** @name CumulusPalletXcmpQueueOutboundChannelDetails (290) */
+  /** @name CumulusPalletXcmpQueueOutboundChannelDetails (323) */
   export interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct {
     readonly recipient: u32;
     readonly state: CumulusPalletXcmpQueueOutboundState;
@@ -2351,14 +2728,14 @@
     readonly lastIndex: u16;
   }
 
-  /** @name CumulusPalletXcmpQueueOutboundState (291) */
+  /** @name CumulusPalletXcmpQueueOutboundState (324) */
   export interface CumulusPalletXcmpQueueOutboundState extends Enum {
     readonly isOk: boolean;
     readonly isSuspended: boolean;
     readonly type: 'Ok' | 'Suspended';
   }
 
-  /** @name CumulusPalletXcmpQueueQueueConfigData (293) */
+  /** @name CumulusPalletXcmpQueueQueueConfigData (326) */
   export interface CumulusPalletXcmpQueueQueueConfigData extends Struct {
     readonly suspendThreshold: u32;
     readonly dropThreshold: u32;
@@ -2368,7 +2745,7 @@
     readonly xcmpMaxIndividualWeight: u64;
   }
 
-  /** @name CumulusPalletXcmpQueueError (295) */
+  /** @name CumulusPalletXcmpQueueError (328) */
   export interface CumulusPalletXcmpQueueError extends Enum {
     readonly isFailedToSend: boolean;
     readonly isBadXcmOrigin: boolean;
@@ -2378,7 +2755,7 @@
     readonly type: 'FailedToSend' | 'BadXcmOrigin' | 'BadXcm' | 'BadOverweightIndex' | 'WeightOverLimit';
   }
 
-  /** @name PalletXcmError (296) */
+  /** @name PalletXcmError (329) */
   export interface PalletXcmError extends Enum {
     readonly isUnreachable: boolean;
     readonly isSendFailure: boolean;
@@ -2396,29 +2773,29 @@
     readonly type: 'Unreachable' | 'SendFailure' | 'Filtered' | 'UnweighableMessage' | 'DestinationNotInvertible' | 'Empty' | 'CannotReanchor' | 'TooManyAssets' | 'InvalidOrigin' | 'BadVersion' | 'BadLocation' | 'NoSubscription' | 'AlreadySubscribed';
   }
 
-  /** @name CumulusPalletXcmError (297) */
+  /** @name CumulusPalletXcmError (330) */
   export type CumulusPalletXcmError = Null;
 
-  /** @name CumulusPalletDmpQueueConfigData (298) */
+  /** @name CumulusPalletDmpQueueConfigData (331) */
   export interface CumulusPalletDmpQueueConfigData extends Struct {
     readonly maxIndividual: u64;
   }
 
-  /** @name CumulusPalletDmpQueuePageIndexData (299) */
+  /** @name CumulusPalletDmpQueuePageIndexData (332) */
   export interface CumulusPalletDmpQueuePageIndexData extends Struct {
     readonly beginUsed: u32;
     readonly endUsed: u32;
     readonly overweightCount: u64;
   }
 
-  /** @name CumulusPalletDmpQueueError (302) */
+  /** @name CumulusPalletDmpQueueError (335) */
   export interface CumulusPalletDmpQueueError extends Enum {
     readonly isUnknown: boolean;
     readonly isOverLimit: boolean;
     readonly type: 'Unknown' | 'OverLimit';
   }
 
-  /** @name PalletUniqueError (306) */
+  /** @name PalletUniqueError (339) */
   export interface PalletUniqueError extends Enum {
     readonly isCollectionDecimalPointLimitExceeded: boolean;
     readonly isConfirmUnsetSponsorFail: boolean;
@@ -2426,7 +2803,75 @@
     readonly type: 'CollectionDecimalPointLimitExceeded' | 'ConfirmUnsetSponsorFail' | 'EmptyArgument';
   }
 
-  /** @name UpDataStructsCollection (307) */
+  /** @name PalletUnqSchedulerScheduledV3 (342) */
+  export interface PalletUnqSchedulerScheduledV3 extends Struct {
+    readonly maybeId: Option<U8aFixed>;
+    readonly priority: u8;
+    readonly call: FrameSupportScheduleMaybeHashed;
+    readonly maybePeriodic: Option<ITuple<[u32, u32]>>;
+    readonly origin: OpalRuntimeOriginCaller;
+  }
+
+  /** @name OpalRuntimeOriginCaller (343) */
+  export interface OpalRuntimeOriginCaller extends Enum {
+    readonly isVoid: boolean;
+    readonly isSystem: boolean;
+    readonly asSystem: FrameSupportDispatchRawOrigin;
+    readonly isPolkadotXcm: boolean;
+    readonly asPolkadotXcm: PalletXcmOrigin;
+    readonly isCumulusXcm: boolean;
+    readonly asCumulusXcm: CumulusPalletXcmOrigin;
+    readonly isEthereum: boolean;
+    readonly asEthereum: PalletEthereumRawOrigin;
+    readonly type: 'Void' | 'System' | 'PolkadotXcm' | 'CumulusXcm' | 'Ethereum';
+  }
+
+  /** @name FrameSupportDispatchRawOrigin (344) */
+  export interface FrameSupportDispatchRawOrigin extends Enum {
+    readonly isRoot: boolean;
+    readonly isSigned: boolean;
+    readonly asSigned: AccountId32;
+    readonly isNone: boolean;
+    readonly type: 'Root' | 'Signed' | 'None';
+  }
+
+  /** @name PalletXcmOrigin (345) */
+  export interface PalletXcmOrigin extends Enum {
+    readonly isXcm: boolean;
+    readonly asXcm: XcmV1MultiLocation;
+    readonly isResponse: boolean;
+    readonly asResponse: XcmV1MultiLocation;
+    readonly type: 'Xcm' | 'Response';
+  }
+
+  /** @name CumulusPalletXcmOrigin (346) */
+  export interface CumulusPalletXcmOrigin extends Enum {
+    readonly isRelay: boolean;
+    readonly isSiblingParachain: boolean;
+    readonly asSiblingParachain: u32;
+    readonly type: 'Relay' | 'SiblingParachain';
+  }
+
+  /** @name PalletEthereumRawOrigin (347) */
+  export interface PalletEthereumRawOrigin extends Enum {
+    readonly isEthereumTransaction: boolean;
+    readonly asEthereumTransaction: H160;
+    readonly type: 'EthereumTransaction';
+  }
+
+  /** @name SpCoreVoid (348) */
+  export type SpCoreVoid = Null;
+
+  /** @name PalletUnqSchedulerError (349) */
+  export interface PalletUnqSchedulerError extends Enum {
+    readonly isFailedToSchedule: boolean;
+    readonly isNotFound: boolean;
+    readonly isTargetBlockNumberInPast: boolean;
+    readonly isRescheduleNoChange: boolean;
+    readonly type: 'FailedToSchedule' | 'NotFound' | 'TargetBlockNumberInPast' | 'RescheduleNoChange';
+  }
+
+  /** @name UpDataStructsCollection (350) */
   export interface UpDataStructsCollection extends Struct {
     readonly owner: AccountId32;
     readonly mode: UpDataStructsCollectionMode;
@@ -2436,9 +2881,10 @@
     readonly sponsorship: UpDataStructsSponsorshipState;
     readonly limits: UpDataStructsCollectionLimits;
     readonly permissions: UpDataStructsCollectionPermissions;
+    readonly externalCollection: bool;
   }
 
-  /** @name UpDataStructsSponsorshipState (308) */
+  /** @name UpDataStructsSponsorshipState (351) */
   export interface UpDataStructsSponsorshipState extends Enum {
     readonly isDisabled: boolean;
     readonly isUnconfirmed: boolean;
@@ -2448,42 +2894,42 @@
     readonly type: 'Disabled' | 'Unconfirmed' | 'Confirmed';
   }
 
-  /** @name UpDataStructsProperties (309) */
+  /** @name UpDataStructsProperties (352) */
   export interface UpDataStructsProperties extends Struct {
     readonly map: UpDataStructsPropertiesMapBoundedVec;
     readonly consumedSpace: u32;
     readonly spaceLimit: u32;
   }
 
-  /** @name UpDataStructsPropertiesMapBoundedVec (310) */
+  /** @name UpDataStructsPropertiesMapBoundedVec (353) */
   export interface UpDataStructsPropertiesMapBoundedVec extends BTreeMap<Bytes, Bytes> {}
 
-  /** @name UpDataStructsPropertiesMapPropertyPermission (315) */
+  /** @name UpDataStructsPropertiesMapPropertyPermission (358) */
   export interface UpDataStructsPropertiesMapPropertyPermission extends BTreeMap<Bytes, UpDataStructsPropertyPermission> {}
 
-  /** @name UpDataStructsCollectionStats (322) */
+  /** @name UpDataStructsCollectionStats (365) */
   export interface UpDataStructsCollectionStats extends Struct {
     readonly created: u32;
     readonly destroyed: u32;
     readonly alive: u32;
   }
 
-  /** @name UpDataStructsTokenChild (323) */
+  /** @name UpDataStructsTokenChild (366) */
   export interface UpDataStructsTokenChild extends Struct {
     readonly token: u32;
     readonly collection: u32;
   }
 
-  /** @name PhantomTypeUpDataStructs (324) */
-  export interface PhantomTypeUpDataStructs extends Vec<ITuple<[UpDataStructsTokenData, UpDataStructsRpcCollection, UpDataStructsRmrkCollectionInfo, UpDataStructsRmrkNftInfo, UpDataStructsRmrkResourceInfo, UpDataStructsRmrkPropertyInfo, UpDataStructsRmrkBaseInfo, UpDataStructsRmrkPartType, UpDataStructsRmrkTheme, UpDataStructsRmrkNftChild]>> {}
+  /** @name PhantomTypeUpDataStructs (367) */
+  export interface PhantomTypeUpDataStructs extends Vec<ITuple<[UpDataStructsTokenData, UpDataStructsRpcCollection, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftNftInfo, RmrkTraitsResourceResourceInfo, RmrkTraitsPropertyPropertyInfo, RmrkTraitsBaseBaseInfo, RmrkTraitsPartPartType, RmrkTraitsTheme, RmrkTraitsNftNftChild]>> {}
 
-  /** @name UpDataStructsTokenData (326) */
+  /** @name UpDataStructsTokenData (369) */
   export interface UpDataStructsTokenData extends Struct {
     readonly properties: Vec<UpDataStructsProperty>;
     readonly owner: Option<PalletEvmAccountBasicCrossAccountIdRepr>;
   }
 
-  /** @name UpDataStructsRpcCollection (328) */
+  /** @name UpDataStructsRpcCollection (371) */
   export interface UpDataStructsRpcCollection extends Struct {
     readonly owner: AccountId32;
     readonly mode: UpDataStructsCollectionMode;
@@ -2495,10 +2941,11 @@
     readonly permissions: UpDataStructsCollectionPermissions;
     readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
     readonly properties: Vec<UpDataStructsProperty>;
+    readonly readOnly: bool;
   }
 
-  /** @name UpDataStructsRmrkCollectionInfo (329) */
-  export interface UpDataStructsRmrkCollectionInfo extends Struct {
+  /** @name RmrkTraitsCollectionCollectionInfo (372) */
+  export interface RmrkTraitsCollectionCollectionInfo extends Struct {
     readonly issuer: AccountId32;
     readonly metadata: Bytes;
     readonly max: Option<u32>;
@@ -2506,143 +2953,60 @@
     readonly nftsCount: u32;
   }
 
-  /** @name UpDataStructsRmrkNftInfo (332) */
-  export interface UpDataStructsRmrkNftInfo extends Struct {
-    readonly owner: UpDataStructsRmrkAccountIdOrCollectionNftTuple;
-    readonly royalty: Option<UpDataStructsRmrkRoyaltyInfo>;
+  /** @name RmrkTraitsNftNftInfo (373) */
+  export interface RmrkTraitsNftNftInfo extends Struct {
+    readonly owner: RmrkTraitsNftAccountIdOrCollectionNftTuple;
+    readonly royalty: Option<RmrkTraitsNftRoyaltyInfo>;
     readonly metadata: Bytes;
     readonly equipped: bool;
     readonly pending: bool;
   }
 
-  /** @name UpDataStructsRmrkAccountIdOrCollectionNftTuple (333) */
-  export interface UpDataStructsRmrkAccountIdOrCollectionNftTuple extends Enum {
-    readonly isAccountId: boolean;
-    readonly asAccountId: AccountId32;
-    readonly isCollectionAndNftTuple: boolean;
-    readonly asCollectionAndNftTuple: ITuple<[u32, u32]>;
-    readonly type: 'AccountId' | 'CollectionAndNftTuple';
-  }
-
-  /** @name UpDataStructsRmrkRoyaltyInfo (335) */
-  export interface UpDataStructsRmrkRoyaltyInfo extends Struct {
+  /** @name RmrkTraitsNftRoyaltyInfo (375) */
+  export interface RmrkTraitsNftRoyaltyInfo extends Struct {
     readonly recipient: AccountId32;
     readonly amount: Permill;
   }
 
-  /** @name UpDataStructsRmrkResourceInfo (336) */
-  export interface UpDataStructsRmrkResourceInfo extends Struct {
-    readonly id: Bytes;
-    readonly resource: UpDataStructsRmrkResourceTypes;
+  /** @name RmrkTraitsResourceResourceInfo (376) */
+  export interface RmrkTraitsResourceResourceInfo extends Struct {
+    readonly id: u32;
+    readonly resource: RmrkTraitsResourceResourceTypes;
     readonly pending: bool;
     readonly pendingRemoval: bool;
   }
 
-  /** @name UpDataStructsRmrkResourceTypes (339) */
-  export interface UpDataStructsRmrkResourceTypes extends Enum {
+  /** @name RmrkTraitsResourceResourceTypes (377) */
+  export interface RmrkTraitsResourceResourceTypes extends Enum {
     readonly isBasic: boolean;
-    readonly asBasic: UpDataStructsRmrkBasicResource;
+    readonly asBasic: RmrkTraitsResourceBasicResource;
     readonly isComposable: boolean;
-    readonly asComposable: UpDataStructsRmrkComposableResource;
+    readonly asComposable: RmrkTraitsResourceComposableResource;
     readonly isSlot: boolean;
-    readonly asSlot: UpDataStructsRmrkSlotResource;
+    readonly asSlot: RmrkTraitsResourceSlotResource;
     readonly type: 'Basic' | 'Composable' | 'Slot';
-  }
-
-  /** @name UpDataStructsRmrkBasicResource (340) */
-  export interface UpDataStructsRmrkBasicResource extends Struct {
-    readonly src: Option<Bytes>;
-    readonly metadata: Option<Bytes>;
-    readonly license: Option<Bytes>;
-    readonly thumb: Option<Bytes>;
   }
 
-  /** @name UpDataStructsRmrkComposableResource (342) */
-  export interface UpDataStructsRmrkComposableResource extends Struct {
-    readonly parts: Vec<u32>;
-    readonly base: u32;
-    readonly src: Option<Bytes>;
-    readonly metadata: Option<Bytes>;
-    readonly license: Option<Bytes>;
-    readonly thumb: Option<Bytes>;
-  }
-
-  /** @name UpDataStructsRmrkSlotResource (343) */
-  export interface UpDataStructsRmrkSlotResource extends Struct {
-    readonly base: u32;
-    readonly src: Option<Bytes>;
-    readonly metadata: Option<Bytes>;
-    readonly slot: u32;
-    readonly license: Option<Bytes>;
-    readonly thumb: Option<Bytes>;
-  }
-
-  /** @name UpDataStructsRmrkPropertyInfo (344) */
-  export interface UpDataStructsRmrkPropertyInfo extends Struct {
+  /** @name RmrkTraitsPropertyPropertyInfo (378) */
+  export interface RmrkTraitsPropertyPropertyInfo extends Struct {
     readonly key: Bytes;
     readonly value: Bytes;
   }
 
-  /** @name UpDataStructsRmrkBaseInfo (347) */
-  export interface UpDataStructsRmrkBaseInfo extends Struct {
+  /** @name RmrkTraitsBaseBaseInfo (379) */
+  export interface RmrkTraitsBaseBaseInfo extends Struct {
     readonly issuer: AccountId32;
     readonly baseType: Bytes;
     readonly symbol: Bytes;
-  }
-
-  /** @name UpDataStructsRmrkPartType (348) */
-  export interface UpDataStructsRmrkPartType extends Enum {
-    readonly isFixedPart: boolean;
-    readonly asFixedPart: UpDataStructsRmrkFixedPart;
-    readonly isSlotPart: boolean;
-    readonly asSlotPart: UpDataStructsRmrkSlotPart;
-    readonly type: 'FixedPart' | 'SlotPart';
-  }
-
-  /** @name UpDataStructsRmrkFixedPart (350) */
-  export interface UpDataStructsRmrkFixedPart extends Struct {
-    readonly id: u32;
-    readonly z: u32;
-    readonly src: Bytes;
-  }
-
-  /** @name UpDataStructsRmrkSlotPart (351) */
-  export interface UpDataStructsRmrkSlotPart extends Struct {
-    readonly id: u32;
-    readonly equippable: UpDataStructsRmrkEquippableList;
-    readonly src: Bytes;
-    readonly z: u32;
-  }
-
-  /** @name UpDataStructsRmrkEquippableList (352) */
-  export interface UpDataStructsRmrkEquippableList extends Enum {
-    readonly isAll: boolean;
-    readonly isEmpty: boolean;
-    readonly isCustom: boolean;
-    readonly asCustom: Vec<u32>;
-    readonly type: 'All' | 'Empty' | 'Custom';
   }
 
-  /** @name UpDataStructsRmrkTheme (353) */
-  export interface UpDataStructsRmrkTheme extends Struct {
-    readonly name: Bytes;
-    readonly properties: Vec<UpDataStructsRmrkThemeProperty>;
-    readonly inherit: bool;
-  }
-
-  /** @name UpDataStructsRmrkThemeProperty (355) */
-  export interface UpDataStructsRmrkThemeProperty extends Struct {
-    readonly key: Bytes;
-    readonly value: Bytes;
-  }
-
-  /** @name UpDataStructsRmrkNftChild (356) */
-  export interface UpDataStructsRmrkNftChild extends Struct {
+  /** @name RmrkTraitsNftNftChild (380) */
+  export interface RmrkTraitsNftNftChild extends Struct {
     readonly collectionId: u32;
     readonly nftId: u32;
   }
 
-  /** @name PalletCommonError (358) */
+  /** @name PalletCommonError (382) */
   export interface PalletCommonError extends Enum {
     readonly isCollectionNotFound: boolean;
     readonly isMustBeTokenOwner: boolean;
@@ -2677,10 +3041,12 @@
     readonly isPropertyKeyIsTooLong: boolean;
     readonly isInvalidCharacterInPropertyKey: boolean;
     readonly isEmptyPropertyKey: boolean;
-    readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'CantDestroyNotEmptyCollection' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
+    readonly isCollectionIsExternal: boolean;
+    readonly isCollectionIsInternal: boolean;
+    readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'CantDestroyNotEmptyCollection' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey' | 'CollectionIsExternal' | 'CollectionIsInternal';
   }
 
-  /** @name PalletFungibleError (360) */
+  /** @name PalletFungibleError (384) */
   export interface PalletFungibleError extends Enum {
     readonly isNotFungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isFungibleItemsHaveNoId: boolean;
@@ -2690,12 +3056,12 @@
     readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
   }
 
-  /** @name PalletRefungibleItemData (361) */
+  /** @name PalletRefungibleItemData (385) */
   export interface PalletRefungibleItemData extends Struct {
     readonly constData: Bytes;
   }
 
-  /** @name PalletRefungibleError (365) */
+  /** @name PalletRefungibleError (389) */
   export interface PalletRefungibleError extends Enum {
     readonly isNotRefungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isWrongRefungiblePieces: boolean;
@@ -2704,12 +3070,12 @@
     readonly type: 'NotRefungibleDataUsedToMintFungibleCollectionToken' | 'WrongRefungiblePieces' | 'RefungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
   }
 
-  /** @name PalletNonfungibleItemData (366) */
+  /** @name PalletNonfungibleItemData (390) */
   export interface PalletNonfungibleItemData extends Struct {
     readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
   }
 
-  /** @name PalletNonfungibleError (368) */
+  /** @name PalletNonfungibleError (392) */
   export interface PalletNonfungibleError extends Enum {
     readonly isNotNonfungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isNonfungibleItemsHaveNoAmount: boolean;
@@ -2717,7 +3083,7 @@
     readonly type: 'NotNonfungibleDataUsedToMintFungibleCollectionToken' | 'NonfungibleItemsHaveNoAmount' | 'CantBurnNftWithChildren';
   }
 
-  /** @name PalletStructureError (369) */
+  /** @name PalletStructureError (393) */
   export interface PalletStructureError extends Enum {
     readonly isOuroborosDetected: boolean;
     readonly isDepthLimit: boolean;
@@ -2725,7 +3091,38 @@
     readonly type: 'OuroborosDetected' | 'DepthLimit' | 'TokenNotFound';
   }
 
-  /** @name PalletEvmError (372) */
+  /** @name PalletRmrkCoreError (394) */
+  export interface PalletRmrkCoreError extends Enum {
+    readonly isCorruptedCollectionType: boolean;
+    readonly isNftTypeEncodeError: boolean;
+    readonly isRmrkPropertyKeyIsTooLong: boolean;
+    readonly isRmrkPropertyValueIsTooLong: boolean;
+    readonly isCollectionNotEmpty: boolean;
+    readonly isNoAvailableCollectionId: boolean;
+    readonly isNoAvailableNftId: boolean;
+    readonly isCollectionUnknown: boolean;
+    readonly isNoPermission: boolean;
+    readonly isNonTransferable: boolean;
+    readonly isCollectionFullOrLocked: boolean;
+    readonly isResourceDoesntExist: boolean;
+    readonly isCannotSendToDescendentOrSelf: boolean;
+    readonly isCannotAcceptNonOwnedNft: boolean;
+    readonly isCannotRejectNonOwnedNft: boolean;
+    readonly isResourceNotPending: boolean;
+    readonly type: 'CorruptedCollectionType' | 'NftTypeEncodeError' | 'RmrkPropertyKeyIsTooLong' | 'RmrkPropertyValueIsTooLong' | 'CollectionNotEmpty' | 'NoAvailableCollectionId' | 'NoAvailableNftId' | 'CollectionUnknown' | 'NoPermission' | 'NonTransferable' | 'CollectionFullOrLocked' | 'ResourceDoesntExist' | 'CannotSendToDescendentOrSelf' | 'CannotAcceptNonOwnedNft' | 'CannotRejectNonOwnedNft' | 'ResourceNotPending';
+  }
+
+  /** @name PalletRmrkEquipError (396) */
+  export interface PalletRmrkEquipError extends Enum {
+    readonly isPermissionError: boolean;
+    readonly isNoAvailableBaseId: boolean;
+    readonly isNoAvailablePartId: boolean;
+    readonly isBaseDoesntExist: boolean;
+    readonly isNeedsDefaultThemeFirst: boolean;
+    readonly type: 'PermissionError' | 'NoAvailableBaseId' | 'NoAvailablePartId' | 'BaseDoesntExist' | 'NeedsDefaultThemeFirst';
+  }
+
+  /** @name PalletEvmError (399) */
   export interface PalletEvmError extends Enum {
     readonly isBalanceLow: boolean;
     readonly isFeeOverflow: boolean;
@@ -2736,7 +3133,7 @@
     readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
   }
 
-  /** @name FpRpcTransactionStatus (375) */
+  /** @name FpRpcTransactionStatus (402) */
   export interface FpRpcTransactionStatus extends Struct {
     readonly transactionHash: H256;
     readonly transactionIndex: u32;
@@ -2747,10 +3144,10 @@
     readonly logsBloom: EthbloomBloom;
   }
 
-  /** @name EthbloomBloom (377) */
+  /** @name EthbloomBloom (404) */
   export interface EthbloomBloom extends U8aFixed {}
 
-  /** @name EthereumReceiptReceiptV3 (379) */
+  /** @name EthereumReceiptReceiptV3 (406) */
   export interface EthereumReceiptReceiptV3 extends Enum {
     readonly isLegacy: boolean;
     readonly asLegacy: EthereumReceiptEip658ReceiptData;
@@ -2761,7 +3158,7 @@
     readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';
   }
 
-  /** @name EthereumReceiptEip658ReceiptData (380) */
+  /** @name EthereumReceiptEip658ReceiptData (407) */
   export interface EthereumReceiptEip658ReceiptData extends Struct {
     readonly statusCode: u8;
     readonly usedGas: U256;
@@ -2769,14 +3166,14 @@
     readonly logs: Vec<EthereumLog>;
   }
 
-  /** @name EthereumBlock (381) */
+  /** @name EthereumBlock (408) */
   export interface EthereumBlock extends Struct {
     readonly header: EthereumHeader;
     readonly transactions: Vec<EthereumTransactionTransactionV2>;
     readonly ommers: Vec<EthereumHeader>;
   }
 
-  /** @name EthereumHeader (382) */
+  /** @name EthereumHeader (409) */
   export interface EthereumHeader extends Struct {
     readonly parentHash: H256;
     readonly ommersHash: H256;
@@ -2795,24 +3192,24 @@
     readonly nonce: EthereumTypesHashH64;
   }
 
-  /** @name EthereumTypesHashH64 (383) */
+  /** @name EthereumTypesHashH64 (410) */
   export interface EthereumTypesHashH64 extends U8aFixed {}
 
-  /** @name PalletEthereumError (388) */
+  /** @name PalletEthereumError (415) */
   export interface PalletEthereumError extends Enum {
     readonly isInvalidSignature: boolean;
     readonly isPreLogExists: boolean;
     readonly type: 'InvalidSignature' | 'PreLogExists';
   }
 
-  /** @name PalletEvmCoderSubstrateError (389) */
+  /** @name PalletEvmCoderSubstrateError (416) */
   export interface PalletEvmCoderSubstrateError extends Enum {
     readonly isOutOfGas: boolean;
     readonly isOutOfFund: boolean;
     readonly type: 'OutOfGas' | 'OutOfFund';
   }
 
-  /** @name PalletEvmContractHelpersSponsoringModeT (390) */
+  /** @name PalletEvmContractHelpersSponsoringModeT (417) */
   export interface PalletEvmContractHelpersSponsoringModeT extends Enum {
     readonly isDisabled: boolean;
     readonly isAllowlisted: boolean;
@@ -2820,20 +3217,20 @@
     readonly type: 'Disabled' | 'Allowlisted' | 'Generous';
   }
 
-  /** @name PalletEvmContractHelpersError (392) */
+  /** @name PalletEvmContractHelpersError (419) */
   export interface PalletEvmContractHelpersError extends Enum {
     readonly isNoPermission: boolean;
     readonly type: 'NoPermission';
   }
 
-  /** @name PalletEvmMigrationError (393) */
+  /** @name PalletEvmMigrationError (420) */
   export interface PalletEvmMigrationError extends Enum {
     readonly isAccountNotEmpty: boolean;
     readonly isAccountIsNotMigrating: boolean;
     readonly type: 'AccountNotEmpty' | 'AccountIsNotMigrating';
   }
 
-  /** @name SpRuntimeMultiSignature (395) */
+  /** @name SpRuntimeMultiSignature (422) */
   export interface SpRuntimeMultiSignature extends Enum {
     readonly isEd25519: boolean;
     readonly asEd25519: SpCoreEd25519Signature;
@@ -2844,34 +3241,34 @@
     readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa';
   }
 
-  /** @name SpCoreEd25519Signature (396) */
+  /** @name SpCoreEd25519Signature (423) */
   export interface SpCoreEd25519Signature extends U8aFixed {}
 
-  /** @name SpCoreSr25519Signature (398) */
+  /** @name SpCoreSr25519Signature (425) */
   export interface SpCoreSr25519Signature extends U8aFixed {}
 
-  /** @name SpCoreEcdsaSignature (399) */
+  /** @name SpCoreEcdsaSignature (426) */
   export interface SpCoreEcdsaSignature extends U8aFixed {}
 
-  /** @name FrameSystemExtensionsCheckSpecVersion (402) */
+  /** @name FrameSystemExtensionsCheckSpecVersion (429) */
   export type FrameSystemExtensionsCheckSpecVersion = Null;
 
-  /** @name FrameSystemExtensionsCheckGenesis (403) */
+  /** @name FrameSystemExtensionsCheckGenesis (430) */
   export type FrameSystemExtensionsCheckGenesis = Null;
 
-  /** @name FrameSystemExtensionsCheckNonce (406) */
+  /** @name FrameSystemExtensionsCheckNonce (433) */
   export interface FrameSystemExtensionsCheckNonce extends Compact<u32> {}
 
-  /** @name FrameSystemExtensionsCheckWeight (407) */
+  /** @name FrameSystemExtensionsCheckWeight (434) */
   export type FrameSystemExtensionsCheckWeight = Null;
 
-  /** @name PalletTemplateTransactionPaymentChargeTransactionPayment (408) */
+  /** @name PalletTemplateTransactionPaymentChargeTransactionPayment (435) */
   export interface PalletTemplateTransactionPaymentChargeTransactionPayment extends Compact<u128> {}
 
-  /** @name OpalRuntimeRuntime (409) */
+  /** @name OpalRuntimeRuntime (436) */
   export type OpalRuntimeRuntime = Null;
 
-  /** @name PalletEthereumFakeTransactionFinalizer (410) */
+  /** @name PalletEthereumFakeTransactionFinalizer (437) */
   export type PalletEthereumFakeTransactionFinalizer = Null;
 
 } // declare module
modifiedtests/src/interfaces/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types.ts
+++ b/tests/src/interfaces/types.ts
@@ -2,4 +2,5 @@
 /* eslint-disable */
 
 export * from './unique/types';
+export * from './rmrk/types';
 export * from './default/types';
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -50,6 +50,8 @@
   'unique',
   'nonfungible',
   'refungible',
+  'rmrkcore',
+  'rmrkequip',
   'scheduler',
   'charging',
 ];
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -46,33 +46,6 @@
     });
   });
 
-  it('Remove collection admin by admin.', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const collectionId = await createCollectionExpectSuccess();
-      const alice = privateKeyWrapper('//Alice');
-      const bob = privateKeyWrapper('//Bob');
-      const charlie = privateKeyWrapper('//Charlie');
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-      expect(collection.owner.toString()).to.be.eq(alice.address);
-      // first - add collection admin Bob
-      const addAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
-      await submitTransactionAsync(alice, addAdminTx);
-
-      const addAdminTx2 = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));
-      await submitTransactionAsync(alice, addAdminTx2);
-
-      const adminListAfterAddAdmin = await getAdminList(api, collectionId);
-      expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
-
-      // then remove bob from admins of collection
-      const removeAdminTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
-      await submitTransactionAsync(charlie, removeAdminTx);
-
-      const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);
-      expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(bob.address));
-    });
-  });
-
   it('Remove admin from collection that has no admins', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const alice = privateKeyWrapper('//Alice');
@@ -120,7 +93,7 @@
     });
   });
 
-  it('Regular user Can\'t remove collection admin', async () => {
+  it('Regular user can\'t remove collection admin', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const collectionId = await createCollectionExpectSuccess();
       const alice = privateKeyWrapper('//Alice');
@@ -137,4 +110,23 @@
       await createCollectionExpectSuccess();
     });
   });
+
+  it('Admin can\'t remove collection admin.', async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const alice = privateKeyWrapper('//Alice');
+      const bob = privateKeyWrapper('//Bob');
+      const charlie = privateKeyWrapper('//Charlie');
+
+      const adminListAfterAddAdmin = await getAdminList(api, collectionId);
+      expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
+
+      const removeAdminTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
+      await expect(submitTransactionAsync(charlie, removeAdminTx)).to.be.rejected;
+
+      const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);
+      expect(adminListAfterRemoveAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
+      expect(adminListAfterRemoveAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));
+    });
+  });
 });
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionSponsor.test.ts
+++ b/tests/src/removeCollectionSponsor.test.ts
@@ -31,7 +31,6 @@
   addCollectionAdminExpectSuccess,
   getCreatedCollectionCount,
 } from './util/helpers';
-import {Keyring} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 
 chai.use(chaiAsPromised);
@@ -43,10 +42,9 @@
 describe('integration test: ext. removeCollectionSponsor():', () => {
 
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
@@ -56,9 +54,9 @@
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
     await removeCollectionSponsorExpectSuccess(collectionId);
 
-    await usingApi(async (api) => {
+    await usingApi(async (api, privateKeyWrapper) => {
       // Find unused address
-      const zeroBalance = await findUnusedAddress(api);
+      const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
 
       // Mint token for unused address
       const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
@@ -99,10 +97,9 @@
 
 describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
   });
 
modifiedtests/src/removeFromContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/removeFromContractAllowList.test.ts
+++ b/tests/src/removeFromContractAllowList.test.ts
@@ -30,8 +30,8 @@
   });
 
   it('user is no longer allowlisted after removal', async () => {
-    await usingApi(async (api) => {
-      const [flipper, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       await addToContractAllowListExpectSuccess(deployer, flipper.address.toString(), bob.address);
       await removeFromContractAllowListExpectSuccess(deployer, flipper.address.toString(), bob.address);
@@ -41,8 +41,8 @@
   });
 
   it('user can\'t execute contract after removal', async () => {
-    await usingApi(async (api) => {
-      const [flipper, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
       await toggleContractAllowlistExpectSuccess(deployer, flipper.address.toString(), true);
 
       await addToContractAllowListExpectSuccess(deployer, flipper.address.toString(), bob.address);
@@ -54,8 +54,8 @@
   });
 
   it('can be called twice', async () => {
-    await usingApi(async (api) => {
-      const [flipper, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       await addToContractAllowListExpectSuccess(deployer, flipper.address.toString(), bob.address);
       await removeFromContractAllowListExpectSuccess(deployer, flipper.address.toString(), bob.address);
@@ -82,8 +82,8 @@
   });
 
   it('fails when executed by non owner', async () => {
-    await usingApi(async (api) => {
-      const [flipper] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper] = await deployFlipper(api, privateKeyWrapper);
 
       await removeFromContractAllowListExpectFailure(alice, flipper.address.toString(), bob.address);
     });
addedtests/src/rmrk/rmrk.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/rmrk/rmrk.test.ts
@@ -0,0 +1,232 @@
+import {expect} from 'chai';
+import privateKey from '../substrate/privateKey';
+import usingApi, {executeTransaction} from '../substrate/substrate-api';
+import {
+  createCollectionExpectSuccess,
+  createItemExpectSuccess,
+  getCreateCollectionResult,
+  getDetailedCollectionInfo,
+  getGenericResult,
+  normalizeAccountId,
+} from '../util/helpers';
+import {IKeyringPair} from '@polkadot/types/types';
+import {ApiPromise} from '@polkadot/api';
+
+let alice: IKeyringPair;
+let bob: IKeyringPair;
+
+async function createRmrkCollection(api: ApiPromise, sender: IKeyringPair): Promise<{uniqueId: number, rmrkId: number}> {
+  const tx = api.tx.rmrkCore.createCollection('metadata', null, 'symbol');
+  const events = await executeTransaction(api, sender, tx);
+
+  const uniqueResult = getCreateCollectionResult(events);
+  const rmrkResult = getGenericResult(events, 'rmrkCore', 'CollectionCreated', (data) => {
+    return parseInt(data[1].toString(), 10);
+  });
+
+  return {
+    uniqueId: uniqueResult.collectionId,
+    rmrkId: rmrkResult.data!,
+  };
+}
+
+async function createRmrkNft(api: ApiPromise, sender: IKeyringPair, collectionId: number): Promise<number> {
+  const tx = api.tx.rmrkCore.mintNft(
+    sender.address,
+    collectionId,
+    sender.address,
+    null,
+    'nft-metadata',
+    true,
+  );
+  const events = await executeTransaction(api, sender, tx);
+  const result = getGenericResult(events, 'rmrkCore', 'NftMinted', (data) => {
+    return parseInt(data[2].toString(), 10);
+  });
+
+  return result.data!;
+}
+
+describe('RMRK External Integration Test', () => {
+  before(async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+    });
+  });
+
+  it('Creates a new RMRK collection that is mapped to a different ID and is tagged as external', async () => {
+    await usingApi(async api => {
+      // throwaway collection to bump last Unique collection ID to test ID mapping
+      await createCollectionExpectSuccess();
+
+      const collectionIds = await createRmrkCollection(api, alice);
+
+      expect(collectionIds.rmrkId).to.be.lessThan(collectionIds.uniqueId, 'collection ID mapping');
+
+      const collection = (await getDetailedCollectionInfo(api, collectionIds.uniqueId))!;
+      expect(collection.readOnly.toHuman(), 'tagged external').to.be.true;
+    });
+  });
+});
+
+describe('Negative Integration Test: External Collections, Internal Ops', () => {
+  let uniqueCollectionId: number;
+  let rmrkCollectionId: number;
+  let rmrkNftId: number;
+
+  before(async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
+
+      const collectionIds = await createRmrkCollection(api, alice);
+      uniqueCollectionId = collectionIds.uniqueId;
+      rmrkCollectionId = collectionIds.rmrkId;
+
+      rmrkNftId = await createRmrkNft(api, alice, rmrkCollectionId);
+    });
+  });
+
+  it('[Negative] Forbids Unique operations with an external collection, handled by dispatch_call', async () => {
+    await usingApi(async api => {
+      // Collection item creation
+
+      const txCreateItem = api.tx.unique.createItem(uniqueCollectionId, normalizeAccountId(alice), 'NFT');
+      await expect(executeTransaction(api, alice, txCreateItem), 'creating item')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txCreateMultipleItems = api.tx.unique.createMultipleItems(uniqueCollectionId, normalizeAccountId(alice), [{NFT: {}}, {NFT: {}}]);
+      await expect(executeTransaction(api, alice, txCreateMultipleItems), 'creating multiple')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txCreateMultipleItemsEx = api.tx.unique.createMultipleItemsEx(uniqueCollectionId, {NFT: [{}]});
+      await expect(executeTransaction(api, alice, txCreateMultipleItemsEx), 'creating multiple ex')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      // Collection properties
+
+      const txSetCollectionProperties = api.tx.unique.setCollectionProperties(uniqueCollectionId, [{key: 'a', value: '1'}, {key: 'b'}]);
+      await expect(executeTransaction(api, alice, txSetCollectionProperties), 'setting collection properties')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txDeleteCollectionProperties = api.tx.unique.deleteCollectionProperties(uniqueCollectionId, ['a']);
+      await expect(executeTransaction(api, alice, txDeleteCollectionProperties), 'deleting collection properties')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txSetPropertyPermissions = api.tx.unique.setPropertyPermissions(uniqueCollectionId, [{key: 'a', permission: {mutable: true}}]);
+      await expect(executeTransaction(api, alice, txSetPropertyPermissions), 'setting property permissions')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      // NFT
+
+      const txBurn = api.tx.unique.burnItem(uniqueCollectionId, rmrkNftId, 1);
+      await expect(executeTransaction(api, alice, txBurn), 'burning').to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txBurnFrom = api.tx.unique.burnFrom(uniqueCollectionId, normalizeAccountId(alice), rmrkNftId, 1);
+      await expect(executeTransaction(api, alice, txBurnFrom), 'burning-from').to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txTransfer = api.tx.unique.transfer(normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1);
+      await expect(executeTransaction(api, alice, txTransfer), 'transferring').to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txApprove = api.tx.unique.approve(normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1);
+      await expect(executeTransaction(api, alice, txApprove), 'approving').to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txTransferFrom = api.tx.unique.transferFrom(normalizeAccountId(alice), normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1);
+      await expect(executeTransaction(api, alice, txTransferFrom), 'transferring-from').to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      // NFT properties
+
+      const txSetTokenProperties = api.tx.unique.setTokenProperties(uniqueCollectionId, rmrkNftId, [{key: 'a', value: '2'}]);
+      await expect(executeTransaction(api, alice, txSetTokenProperties), 'setting token properties')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txDeleteTokenProperties = api.tx.unique.deleteTokenProperties(uniqueCollectionId, rmrkNftId, ['a']);
+      await expect(executeTransaction(api, alice, txDeleteTokenProperties), 'deleting token properties')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+    });
+  });
+
+  it('[Negative] Forbids Unique collection operations with an external collection', async () => {
+    await usingApi(async api => {
+      const txDestroyCollection = api.tx.unique.destroyCollection(uniqueCollectionId);
+      await expect(executeTransaction(api, alice, txDestroyCollection), 'destroying collection')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      // Allow list
+
+      const txAddAllowList = api.tx.unique.addToAllowList(uniqueCollectionId, normalizeAccountId(bob));
+      await expect(executeTransaction(api, alice, txAddAllowList), 'adding to allow list')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txRemoveAllowList = api.tx.unique.removeFromAllowList(uniqueCollectionId, normalizeAccountId(bob));
+      await expect(executeTransaction(api, alice, txRemoveAllowList), 'removing from allowlist')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      // Owner / Admin / Sponsor
+
+      const txChangeOwner = api.tx.unique.changeCollectionOwner(uniqueCollectionId, bob.address);
+      await expect(executeTransaction(api, alice, txChangeOwner), 'changing owner')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txAddAdmin = api.tx.unique.addCollectionAdmin(uniqueCollectionId, normalizeAccountId(bob));
+      await expect(executeTransaction(api, alice, txAddAdmin), 'adding admin')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txRemoveAdmin = api.tx.unique.removeCollectionAdmin(uniqueCollectionId, normalizeAccountId(bob));
+      await expect(executeTransaction(api, alice, txRemoveAdmin), 'removing admin')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txAddCollectionSponsor = api.tx.unique.setCollectionSponsor(uniqueCollectionId, bob.address);
+      await expect(executeTransaction(api, alice, txAddCollectionSponsor), 'setting sponsor')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txConfirmCollectionSponsor = api.tx.unique.confirmSponsorship(uniqueCollectionId);
+      await expect(executeTransaction(api, alice, txConfirmCollectionSponsor), 'confirming sponsor')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txRemoveCollectionSponsor = api.tx.unique.removeCollectionSponsor(uniqueCollectionId);
+      await expect(executeTransaction(api, alice, txRemoveCollectionSponsor), 'removing sponsor')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+      
+      // Limits / permissions / transfers
+
+      const txSetTransfers = api.tx.unique.setTransfersEnabledFlag(uniqueCollectionId, true);
+      await expect(executeTransaction(api, alice, txSetTransfers), 'setting transfers enabled flag')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txSetLimits = api.tx.unique.setCollectionLimits(uniqueCollectionId, {transfersEnabled: false});
+      await expect(executeTransaction(api, alice, txSetLimits), 'setting collection limits')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+
+      const txSetPermissions = api.tx.unique.setCollectionPermissions(uniqueCollectionId, {access: 'AllowList'});
+      await expect(executeTransaction(api, alice, txSetPermissions), 'setting collection permissions')
+        .to.be.rejectedWith(/common\.CollectionIsExternal/);
+    });
+  });
+});
+
+describe('Negative Integration Test: Internal Collections, External Ops', () => {
+  let collectionId: number;
+  let nftId: number;
+
+  before(async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
+
+      collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+      nftId = await createItemExpectSuccess(alice, collectionId, 'NFT');
+    });
+  });
+
+  it('[Negative] Forbids RMRK operations with the internal collection and NFT (due to the lack of mapping)', async () => {
+    await usingApi(async api => {
+      const txChangeOwner = api.tx.rmrkCore.changeCollectionIssuer(collectionId, bob.address);
+      await expect(executeTransaction(api, alice, txChangeOwner), 'changing collection issuer')
+        .to.be.rejectedWith(/rmrkCore\.CollectionUnknown/);
+
+      const txBurnItem = api.tx.rmrkCore.burnNft(collectionId, nftId);
+      await expect(executeTransaction(api, alice, txBurnItem), 'burning NFT').to.be.rejectedWith(/rmrkCore\.CollectionUnknown/);
+    });
+  });
+});
\ No newline at end of file
modifiedtests/src/rpc.load.tsdiffbeforeafterboth
--- a/tests/src/rpc.load.ts
+++ b/tests/src/rpc.load.ts
@@ -54,13 +54,12 @@
   });
 }
 
-async function prepareDeployer(api: ApiPromise) {
+async function prepareDeployer(api: ApiPromise, privateKeyWrapper: ((account: string) => IKeyringPair)) {
   // Find unused address
-  const deployer = await findUnusedAddress(api);
+  const deployer = await findUnusedAddress(api, privateKeyWrapper);
 
   // Transfer balance to it
-  const keyring = new Keyring({type: 'sr25519'});
-  const alice = keyring.addFromUri('//Alice');
+  const alice = privateKeyWrapper('//Alice');
   const amount = BigInt(endowment) + 10n**15n;
   const tx = api.tx.balances.transfer(deployer.address, amount);
   await submitTransactionAsync(alice, tx);
@@ -68,11 +67,11 @@
   return deployer;
 }
 
-async function deployLoadTester(api: ApiPromise): Promise<[Contract, IKeyringPair]> {
+async function deployLoadTester(api: ApiPromise, privateKeyWrapper: ((account: string) => IKeyringPair)): Promise<[Contract, IKeyringPair]> {
   const metadata = JSON.parse(fs.readFileSync('./src/load_test_sc/metadata.json').toString('utf-8'));
   const abi = new Abi(metadata);
 
-  const deployer = await prepareDeployer(api);
+  const deployer = await prepareDeployer(api, privateKeyWrapper);
 
   const wasm = fs.readFileSync('./src/load_test_sc/loadtester.wasm');
 
@@ -123,7 +122,7 @@
     await usingApi(async (api, privateKeyWrapper) => {
 
       // Deploy smart contract
-      const [contract, deployer] = await deployLoadTester(api);
+      const [contract, deployer] = await deployLoadTester(api, privateKeyWrapper);
 
       // Fill smart contract up with data
       const bob = privateKeyWrapper('//Bob');
modifiedtests/src/scheduler.test.tsdiffbeforeafterboth
--- a/tests/src/scheduler.test.ts
+++ b/tests/src/scheduler.test.ts
@@ -16,7 +16,6 @@
 
 import chai, {expect} from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import privateKey from './substrate/privateKey';
 import {
   default as usingApi, 
   submitTransactionAsync,
@@ -52,9 +51,9 @@
   let scheduledIdSlider: number;
 
   before(async() => {
-    await usingApi(async () => {
-      alice = privateKey('//Alice');
-      bob = privateKey('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
     });
 
     scheduledIdBase = '0x' + '0'.repeat(31);
@@ -116,9 +115,9 @@
   });
 
   it('Schedules and dispatches a transaction even if the caller has no funds at the time of the dispatch', async () => {
-    await usingApi(async (api) => {
+    await usingApi(async (api, privateKeyWrapper) => {
       // Find an empty, unused account
-      const zeroBalance = await findUnusedAddress(api);
+      const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
 
       const collectionId = await createCollectionExpectSuccess();
 
@@ -156,8 +155,8 @@
   it('Sponsor going bankrupt does not impact a scheduled transaction', async () => {
     const collectionId = await createCollectionExpectSuccess();
 
-    await usingApi(async (api) => {
-      const zeroBalance = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
       const balanceTx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);
       await submitTransactionAsync(alice, balanceTx);
 
@@ -186,8 +185,8 @@
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
 
-    await usingApi(async (api) => {
-      const zeroBalance = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
 
       await enablePublicMintingExpectSuccess(alice, collectionId);
       await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -15,7 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits
-import {ApiPromise, Keyring} from '@polkadot/api';
+import {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
@@ -44,9 +44,8 @@
 describe('setCollectionLimits positive', () => {
   let tx;
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
       collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
     });
   });
@@ -121,10 +120,9 @@
 describe('setCollectionLimits negative', () => {
   let tx;
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
       collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
     });
   });
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -24,7 +24,6 @@
   addCollectionAdminExpectSuccess,
   getCreatedCollectionCount,
 } from './util/helpers';
-import {Keyring} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 
 chai.use(chaiAsPromised);
@@ -36,10 +35,10 @@
 describe('integration test: ext. setCollectionSponsor():', () => {
 
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
+      charlie = privateKeyWrapper('//Charlie');
     });
   });
 
@@ -63,9 +62,6 @@
   });
   it('Replace collection sponsor', async () => {
     const collectionId = await createCollectionExpectSuccess();
-
-    const keyring = new Keyring({type: 'sr25519'});
-    const charlie = keyring.addFromUri('//Charlie');
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await setCollectionSponsorExpectSuccess(collectionId, charlie.address);
   });
@@ -73,11 +69,10 @@
 
 describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {
   before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
-      charlie = keyring.addFromUri('//Charlie');
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
+      charlie = privateKeyWrapper('//Charlie');
     });
   });
 
modifiedtests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth
--- a/tests/src/setContractSponsoringRateLimit.test.ts
+++ b/tests/src/setContractSponsoringRateLimit.test.ts
@@ -27,10 +27,10 @@
 
 describe.skip('Integration Test setContractSponsoringRateLimit', () => {
   it('ensure sponsored contract can\'t be called twice without pause for free', async () => {
-    await usingApi(async (api) => {
-      const user = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const user = await findUnusedAddress(api, privateKeyWrapper);
 
-      const [flipper, deployer] = await deployFlipper(api);
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
       await setContractSponsoringRateLimitExpectSuccess(deployer, flipper.address, 10);
       await toggleFlipValueExpectSuccess(user, flipper);
@@ -39,10 +39,10 @@
   });
 
   it('ensure sponsored contract can be called twice with pause for free', async () => {
-    await usingApi(async (api) => {
-      const user = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const user = await findUnusedAddress(api, privateKeyWrapper);
 
-      const [flipper, deployer] = await deployFlipper(api);
+      const [flipper, deployer] = await deployFlipper(api, privateKeyWrapper);
       await enableContractSponsoringExpectSuccess(deployer, flipper.address, true);
       await setContractSponsoringRateLimitExpectSuccess(deployer, flipper.address, 1);
       await toggleFlipValueExpectSuccess(user, flipper);
@@ -62,16 +62,16 @@
   });
 
   it('fails when called for non-contract address', async () => {
-    await usingApi(async (api) => {
-      const user = await findUnusedAddress(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const user = await findUnusedAddress(api, privateKeyWrapper);
 
       await setContractSponsoringRateLimitExpectFailure(alice, user.address, 1);
     });
   });
 
   it('fails when called by non-owning user', async () => {
-    await usingApi(async (api) => {
-      const [flipper] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [flipper] = await deployFlipper(api, privateKeyWrapper);
 
       await setContractSponsoringRateLimitExpectFailure(alice, flipper.address, 1);
     });
modifiedtests/src/substrate/substrate-api.tsdiffbeforeafterboth
--- a/tests/src/substrate/substrate-api.ts
+++ b/tests/src/substrate/substrate-api.ts
@@ -42,7 +42,7 @@
     },
     rpc: {
       unique: defs.unique.rpc,
-      // TODO free RMRK! rmrk: defs.rmrk.rpc,
+      rmrk: defs.rmrk.rpc,
       eth: {
         feeHistory: {
           description: 'Dummy',
@@ -88,7 +88,7 @@
     await promisifySubstrate(api, async () => {
       if (api) {
         await api.isReadyOrError;
-        const ss58Format = (api.registry.getChainProperties())!.toHuman().ss58Format;
+        const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;
         const privateKeyWrapper = (account: string) => privateKey(account, Number(ss58Format));
         result = await action(api, privateKeyWrapper);
       }
modifiedtests/src/toggleContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/toggleContractAllowList.test.ts
+++ b/tests/src/toggleContractAllowList.test.ts
@@ -34,8 +34,8 @@
 describe.skip('Integration Test toggleContractAllowList', () => {
 
   it('Enable allow list contract mode', async () => {
-    await usingApi(async api => {
-      const [contract, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [contract, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       const enabledBefore = (await api.query.unique.contractAllowListEnabled(contract.address)).toJSON();
       const enableAllowListTx = api.tx.unique.toggleContractAllowList(contract.address, true);
@@ -52,7 +52,7 @@
     await usingApi(async (api, privateKeyWrapper) => {
       const bob = privateKeyWrapper('//Bob');
 
-      const [contract, deployer] = await deployFlipper(api);
+      const [contract, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       let flipValueBefore = await getFlipValue(contract, deployer);
       const flip = contract.tx.flip(value, gasLimit);
@@ -111,8 +111,8 @@
   });
 
   it('Enabling allow list repeatedly should not produce errors', async () => {
-    await usingApi(async api => {
-      const [contract, deployer] = await deployFlipper(api);
+    await usingApi(async (api, privateKeyWrapper) => {
+      const [contract, deployer] = await deployFlipper(api, privateKeyWrapper);
 
       const enabledBefore = (await api.query.unique.contractAllowListEnabled(contract.address)).toJSON();
       const enableAllowListTx = api.tx.unique.toggleContractAllowList(contract.address, true);
@@ -151,7 +151,7 @@
   it('Enable allow list using a non-owner address', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const bob = privateKeyWrapper('//Bob');
-      const [contract] = await deployFlipper(api);
+      const [contract] = await deployFlipper(api, privateKeyWrapper);
 
       const enabledBefore = (await api.query.unique.contractAllowListEnabled(contract.address)).toJSON();
       const enableAllowListTx = api.tx.unique.toggleContractAllowList(contract.address, true);
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -17,7 +17,6 @@
 import {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import {expect} from 'chai';
-import {alicesPublicKey, bobsPublicKey} from './accounts';
 import getBalance from './substrate/get-balance';
 import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
 import {
@@ -47,19 +46,24 @@
 let charlie: IKeyringPair;
 
 describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+  before(async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      bob = privateKeyWrapper('//Bob');
+    });
+  });
+  
   it('Balance transfers and check balance', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
-      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
+      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alice.address, bob.address]);
 
-      const alicePrivateKey = privateKeyWrapper('//Alice');
-
-      const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);
-      const events = await submitTransactionAsync(alicePrivateKey, transfer);
+      const transfer = api.tx.balances.transfer(bob.address, 1n);
+      const events = await submitTransactionAsync(alice, transfer);
       const result = getCreateItemResult(events);
       // tslint:disable-next-line:no-unused-expression
       expect(result.success).to.be.true;
 
-      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
+      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alice.address, bob.address]);
 
       // tslint:disable-next-line:no-unused-expression
       expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
@@ -69,11 +73,11 @@
   });
 
   it('Inability to pay fees error message is correct', async () => {
-    await usingApi(async (api) => {
+    await usingApi(async (api, privateKeyWrapper) => {
       // Find unused address
-      const pk = await findUnusedAddress(api);
+      const pk = await findUnusedAddress(api, privateKeyWrapper);
 
-      const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n);
+      const badTransfer = api.tx.balances.transfer(bob.address, 1n);
       // const events = await submitTransactionAsync(pk, badTransfer);
       const badTransaction = async () => {
         const events = await submitTransactionAsync(pk, badTransfer);
@@ -87,8 +91,6 @@
 
   it('User can transfer owned token', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
-      const alice = privateKeyWrapper('//Alice');
-      const bob = privateKeyWrapper('//Bob');
       // nft
       const nftCollectionId = await createCollectionExpectSuccess();
       const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
@@ -114,8 +116,6 @@
 
   it('Collection admin can transfer owned token', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
-      const alice = privateKeyWrapper('//Alice');
-      const bob = privateKeyWrapper('//Bob');
       // nft
       const nftCollectionId = await createCollectionExpectSuccess();
       await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
@@ -316,7 +316,6 @@
 describe('Transfers to self (potentially over substrate-evm boundary)', () => {
   itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const alice = privateKeyWrapper('//Alice');
     const aliceProxy = subToEth(alice.address);
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
     await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');
@@ -328,7 +327,6 @@
 
   itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const alice = privateKeyWrapper('//Alice');
     const aliceProxy = subToEth(alice.address);
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
     const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
@@ -340,7 +338,6 @@
 
   itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const alice = privateKeyWrapper('//Alice');
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
     const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
     await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');
@@ -351,7 +348,6 @@
 
   itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const alice = privateKeyWrapper('//Alice');
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
     const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
     await transferExpectFailure(collectionId, tokenId, alice, alice , 11);
modifiedtests/src/util/contracthelpers.tsdiffbeforeafterboth
--- a/tests/src/util/contracthelpers.ts
+++ b/tests/src/util/contracthelpers.ts
@@ -20,7 +20,7 @@
 import fs from 'fs';
 import {Abi, CodePromise, ContractPromise as Contract} from '@polkadot/api-contract';
 import {IKeyringPair} from '@polkadot/types/types';
-import {ApiPromise, Keyring} from '@polkadot/api';
+import {ApiPromise} from '@polkadot/api';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -45,13 +45,12 @@
   });
 }
 
-async function prepareDeployer(api: ApiPromise) {
+async function prepareDeployer(api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair) {
   // Find unused address
-  const deployer = await findUnusedAddress(api);
+  const deployer = await findUnusedAddress(api, privateKeyWrapper);
 
   // Transfer balance to it
-  const keyring = new Keyring({type: 'sr25519'});
-  const alice = keyring.addFromUri('//Alice');
+  const alice = privateKeyWrapper('//Alice');
   const amount = BigInt(endowment) + 10n**15n;
   const tx = api.tx.balances.transfer(deployer.address, amount);
   await submitTransactionAsync(alice, tx);
@@ -59,11 +58,11 @@
   return deployer;
 }
 
-export async function deployFlipper(api: ApiPromise): Promise<[Contract, IKeyringPair]> {
+export async function deployFlipper(api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair): Promise<[Contract, IKeyringPair]> {
   const metadata = JSON.parse(fs.readFileSync('./src/flipper/metadata.json').toString('utf-8'));
   const abi = new Abi(metadata);
 
-  const deployer = await prepareDeployer(api);
+  const deployer = await prepareDeployer(api, privateKeyWrapper);
 
   const wasm = fs.readFileSync('./src/flipper/flipper.wasm');
 
@@ -99,11 +98,11 @@
   await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
 }
 
-export async function deployTransferContract(api: ApiPromise): Promise<[Contract, IKeyringPair]> {
+export async function deployTransferContract(api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair): Promise<[Contract, IKeyringPair]> {
   const metadata = JSON.parse(fs.readFileSync('./src/transfer_contract/metadata.json').toString('utf-8'));
   const abi = new Abi(metadata);
 
-  const deployer = await prepareDeployer(api);
+  const deployer = await prepareDeployer(api, privateKeyWrapper);
 
   const wasm = fs.readFileSync('./src/transfer_contract/nft_transfer.wasm');
 
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -16,14 +16,14 @@
 
 import '../interfaces/augment-api-rpc';
 import '../interfaces/augment-api-query';
-import {ApiPromise, Keyring} from '@polkadot/api';
+import {ApiPromise} from '@polkadot/api';
 import type {AccountId, EventRecord, Event} from '@polkadot/types/interfaces';
+import type {GenericEventData} from '@polkadot/types';
 import {AnyTuple, IEvent, IKeyringPair} from '@polkadot/types/types';
 import {evmToAddress} from '@polkadot/util-crypto';
 import BN from 'bn.js';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {alicesPublicKey} from '../accounts';
 import {default as usingApi, executeTransaction, submitTransactionAsync, submitTransactionExpectFailAsync} from '../substrate/substrate-api';
 import {hexToStr, strToUTF16, utf16ToStr} from './util';
 import {UpDataStructsRpcCollection, UpDataStructsCreateItemData, UpDataStructsProperty} from '@polkadot/types/lookup';
@@ -40,7 +40,7 @@
 
 export function normalizeAccountId(input: string | AccountId | CrossAccountId | IKeyringPair): CrossAccountId {
   if (typeof input === 'string') {
-    if (input.length === 48 || input.length === 47) {
+    if (input.length >= 47) {
       return {Substrate: input};
     } else if (input.length === 42 && input.startsWith('0x')) {
       return {Ethereum: input.toLowerCase()};
@@ -88,9 +88,10 @@
 const CENTIUNIQUE = 10n * MILLIUNIQUE;
 export const UNIQUE = 100n * CENTIUNIQUE;
 
-type GenericResult = {
-  success: boolean,
-};
+interface GenericResult<T> {
+  success: boolean;
+  data: T | null;
+}
 
 interface CreateCollectionResult {
   success: boolean;
@@ -170,91 +171,87 @@
   return event.event as T;
 }
 
-export function getGenericResult(events: EventRecord[]): GenericResult {
-  const result: GenericResult = {
-    success: false,
-  };
-  events.forEach(({event: {method}}) => {
+export function getGenericResult<T>(events: EventRecord[]): GenericResult<T>;
+export function getGenericResult<T>(
+  events: EventRecord[],
+  expectSection: string,
+  expectMethod: string,
+  extractAction: (data: GenericEventData) => T
+): GenericResult<T>;
+
+export function getGenericResult<T>(
+  events: EventRecord[],
+  expectSection?: string,
+  expectMethod?: string,
+  extractAction?: (data: GenericEventData) => T,
+): GenericResult<T> {
+  let success = false;
+  let successData = null;
+
+  events.forEach(({event: {data, method, section}}) => {
     // console.log(`    ${phase}: ${section}.${method}:: ${data}`);
     if (method === 'ExtrinsicSuccess') {
-      result.success = true;
+      success = true;
+    } else if ((expectSection == section) && (expectMethod == method)) {
+      successData = extractAction!(data);
     }
   });
+
+  const result: GenericResult<T> = {
+    success,
+    data: successData,
+  };
   return result;
 }
-
 
-
 export function getCreateCollectionResult(events: EventRecord[]): CreateCollectionResult {
-  let success = false;
-  let collectionId = 0;
-  events.forEach(({event: {data, method, section}}) => {
-    // console.log(`    ${phase}: ${section}.${method}:: ${data}`);
-    if (method == 'ExtrinsicSuccess') {
-      success = true;
-    } else if ((section == 'common') && (method == 'CollectionCreated')) {
-      collectionId = parseInt(data[0].toString(), 10);
-    }
-  });
+  const genericResult = getGenericResult(events, 'common', 'CollectionCreated', (data) => parseInt(data[0].toString(), 10));
   const result: CreateCollectionResult = {
-    success,
-    collectionId,
+    success: genericResult.success,
+    collectionId: genericResult.data ?? 0,
   };
   return result;
 }
 
 export function getCreateItemsResult(events: EventRecord[]): CreateItemResult[] {
-  let success = false;
-  let collectionId = 0;
-  let itemId = 0;
-  let recipient;
+  const results: CreateItemResult[] = [];
+  
+  const genericResult = getGenericResult<CreateItemResult[]>(events, 'common', 'ItemCreated', (data) => {
+    const collectionId = parseInt(data[0].toString(), 10);
+    const itemId = parseInt(data[1].toString(), 10);
+    const recipient = normalizeAccountId(data[2].toJSON() as any);
 
-  const results : CreateItemResult[]  = [];
-
-  events.forEach(({event: {data, method, section}}) => {
-    // console.log(`    ${phase}: ${section}.${method}:: ${data}`);
-    if (method == 'ExtrinsicSuccess') {
-      success = true;
-    } else if ((section == 'common') && (method == 'ItemCreated')) {
-      collectionId = parseInt(data[0].toString(), 10);
-      itemId = parseInt(data[1].toString(), 10);
-      recipient = normalizeAccountId(data[2].toJSON() as any);
-
-      const itemRes: CreateItemResult = {
-        success,
-        collectionId,
-        itemId,
-        recipient,
-      };
+    const itemRes: CreateItemResult = {
+      success: true,
+      collectionId,
+      itemId,
+      recipient,
+    };
 
-      results.push(itemRes);
-    }
+    results.push(itemRes);
+    return results;
   });
 
+  if (!genericResult.success) return [];
   return results;
 }
 
 export function getCreateItemResult(events: EventRecord[]): CreateItemResult {
-  let success = false;
-  let collectionId = 0;
-  let itemId = 0;
-  let recipient;
-  events.forEach(({event: {data, method, section}}) => {
-    // console.log(`    ${phase}: ${section}.${method}:: ${data}`);
-    if (method == 'ExtrinsicSuccess') {
-      success = true;
-    } else if ((section == 'common') && (method == 'ItemCreated')) {
-      collectionId = parseInt(data[0].toString(), 10);
-      itemId = parseInt(data[1].toString(), 10);
-      recipient = normalizeAccountId(data[2].toJSON() as any);
-    }
-  });
+  const genericResult = getGenericResult<[number, number, CrossAccountId?]>(events, 'common', 'ItemCreated', (data) => [
+    parseInt(data[0].toString(), 10),
+    parseInt(data[1].toString(), 10),
+    normalizeAccountId(data[2].toJSON() as any),
+  ]);
+
+  if (genericResult.data == null) genericResult.data = [0, 0];
+
   const result: CreateItemResult = {
-    success,
-    collectionId,
-    itemId,
-    recipient,
+    success: genericResult.success,
+    collectionId: genericResult.data[0],
+    itemId: genericResult.data[1],
+    recipient: genericResult.data![2],
   };
+  
   return result;
 }
 
@@ -363,7 +360,7 @@
     // tslint:disable-next-line:no-unused-expression
     expect(collection).to.be.not.null;
     expect(collectionCountAfter).to.be.equal(collectionCountBefore + 1, 'Error: NFT collection NOT created.');
-    expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicesPublicKey));
+    expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicePrivateKey));
     expect(utf16ToStr(collection.name.toJSON() as any)).to.be.equal(name);
     expect(utf16ToStr(collection.description.toJSON() as any)).to.be.equal(description);
     expect(hexToStr(collection.tokenPrefix.toJSON())).to.be.equal(tokenPrefix);
@@ -411,7 +408,7 @@
     // tslint:disable-next-line:no-unused-expression
     expect(collection).to.be.not.null;
     expect(collectionCountAfter).to.be.equal(collectionCountBefore + 1, 'Error: NFT collection NOT created.');
-    expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicesPublicKey));
+    expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicePrivateKey));
     expect(utf16ToStr(collection.name.toJSON() as any)).to.be.equal(name);
     expect(utf16ToStr(collection.description.toJSON() as any)).to.be.equal(description);
     expect(hexToStr(collection.tokenPrefix.toJSON())).to.be.equal(tokenPrefix);
@@ -482,13 +479,12 @@
   });
 }
 
-export async function findUnusedAddress(api: ApiPromise, seedAddition = ''): Promise<IKeyringPair> {
+export async function findUnusedAddress(api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair, seedAddition = ''): Promise<IKeyringPair> {
   let bal = 0n;
   let unused;
   do {
     const randomSeed = 'seed' + Math.floor(Math.random() * Math.floor(10000)) + seedAddition;
-    const keyring = new Keyring({type: 'sr25519'});
-    unused = keyring.addFromUri(`//${randomSeed}`);
+    unused = privateKeyWrapper(`//${randomSeed}`);
     bal = (await api.query.system.account(unused.address)).data.free.toBigInt();
   } while (bal !== 0n);
   return unused;
@@ -498,8 +494,8 @@
   return (await api.rpc.unique.allowance(collectionId, normalizeAccountId(owner), normalizeAccountId(approved), tokenId)).toBigInt();
 }
 
-export function findUnusedAddresses(api: ApiPromise, amount: number): Promise<IKeyringPair[]> {
-  return Promise.all(new Array(amount).fill(null).map(() => findUnusedAddress(api, '_' + Date.now())));
+export function findUnusedAddresses(api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair, amount: number): Promise<IKeyringPair[]> {
+  return Promise.all(new Array(amount).fill(null).map(() => findUnusedAddress(api, privateKeyWrapper, '_' + Date.now())));
 }
 
 export async function findNotExistingCollection(api: ApiPromise): Promise<number> {
@@ -868,7 +864,7 @@
     }
     const transferFromTx = api.tx.unique.transferFrom(normalizeAccountId(accountFrom), to, collectionId, tokenId, value);
     const events = await submitTransactionAsync(accountApproved, transferFromTx);
-    const result = getCreateItemResult(events);
+    const result = getGenericResult(events);
     // tslint:disable-next-line:no-unused-expression
     expect(result.success).to.be.true;
     if (type === 'NFT') {
modifiedtests/src/xcmTransfer.test.tsdiffbeforeafterboth
--- a/tests/src/xcmTransfer.test.ts
+++ b/tests/src/xcmTransfer.test.ts
@@ -24,7 +24,6 @@
 import {getGenericResult} from './util/helpers';
 import waitNewBlocks from './substrate/wait-new-blocks';
 import getBalance from './substrate/get-balance';
-import {alicesPublicKey} from './accounts';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -144,7 +143,7 @@
     let balanceBefore: bigint;
     
     await usingApi(async (api) => {
-      [balanceBefore] = await getBalance(api, [alicesPublicKey]);
+      [balanceBefore] = await getBalance(api, [alice.address]);
     });
 
     await usingApi(async (api) => {
@@ -181,7 +180,7 @@
     await usingApi(async (api) => {
       // todo do something about instant sealing, where there might not be any new blocks
       await waitNewBlocks(api, 3);
-      const [balanceAfter] = await getBalance(api, [alicesPublicKey]);
+      const [balanceAfter] = await getBalance(api, [alice.address]);
       expect(balanceAfter > balanceBefore).to.be.true;
     });
   });
modifiedtests/yarn.lockdiffbeforeafterboth
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -146,9 +146,9 @@
     js-tokens "^4.0.0"
 
 "@babel/parser@^7.16.7", "@babel/parser@^7.18.0":
-  version "7.18.3"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.3.tgz#39e99c7b0c4c56cef4d1eed8de9f506411c2ebc2"
-  integrity sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==
+  version "7.18.4"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef"
+  integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==
 
 "@babel/register@^7.17.7":
   version "7.17.7"
@@ -194,9 +194,9 @@
     globals "^11.1.0"
 
 "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.18.2":
-  version "7.18.2"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.2.tgz#191abfed79ebe6f4242f643a9a5cbaa36b10b091"
-  integrity sha512-0On6B8A4/+mFUto5WERt3EEuG1NznDirvwca1O8UwXQHVY8g3R7OzYgxXdOfMwLO08UrpUD/2+3Bclyq+/C94Q==
+  version "7.18.4"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354"
+  integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==
   dependencies:
     "@babel/helper-validator-identifier" "^7.16.7"
     to-fast-properties "^2.0.0"
@@ -223,7 +223,7 @@
     minimatch "^3.1.2"
     strip-json-comments "^3.1.1"
 
-"@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.3":
+"@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.4":
   version "2.6.4"
   resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.4.tgz#1b3cdd3aa4ee3b0ca366756fc35e4a03022a01cc"
   integrity sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==
@@ -232,12 +232,12 @@
     ethereumjs-util "^7.1.4"
 
 "@ethereumjs/tx@^3.3.2":
-  version "3.5.1"
-  resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.1.tgz#8d941b83a602b4a89949c879615f7ea9a90e6671"
-  integrity sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==
+  version "3.5.2"
+  resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c"
+  integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==
   dependencies:
-    "@ethereumjs/common" "^2.6.3"
-    ethereumjs-util "^7.1.4"
+    "@ethereumjs/common" "^2.6.4"
+    ethereumjs-util "^7.1.5"
 
 "@ethersproject/abi@5.0.7":
   version "5.0.7"
@@ -508,142 +508,142 @@
     "@nodelib/fs.scandir" "2.1.5"
     fastq "^1.6.0"
 
-"@polkadot/api-augment@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-8.6.2.tgz#33f58f612583d9ddbe6ad6607765c947b063a5d0"
-  integrity sha512-4qz/0ukMpYTO0QjPufV4bB0cMmCFHYsrDNT23KXwus2mSkn19nRN01Nhf8JqVAAqK1cMXfioQmL3Lmpfke6L/w==
+"@polkadot/api-augment@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-8.7.2-11.tgz#7f174f830c181d82863eb41f48e24fd6bbde3065"
+  integrity sha512-yKsuxjez1ArwSEZJ+g8mausm38CgOtaWBG5ob5cmO9M2v45HBXy3Kmviqr8Dputtu23deT85p7m/8RFLlAnzSA==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/api-base" "8.6.2"
-    "@polkadot/rpc-augment" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-augment" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/api-base" "8.7.2-11"
+    "@polkadot/rpc-augment" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-augment" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/api-base@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-8.6.2.tgz#54ca8292662c896ef46ae3f33bf4efb053f36690"
-  integrity sha512-x3AKw0BJZNYuVTOo4Nkv0wzjk2sK5GKmdN7TA7CmST2SZ+2CRiFFVXb4vXjZRp9wyJJWCuRFX+JhIXwlzWQVoA==
+"@polkadot/api-base@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-8.7.2-11.tgz#7e297a0ca283a58bc9d8d11c1edb099bc61da9f1"
+  integrity sha512-WQE5uvb7W7AKSfy4ekW2i6mJJzZYLMS/eNPNXYpURW/cRPt9NhT9lNz2Ae2d7gaWgWil+jNLecXTHTUzxobRbA==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/rpc-core" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/rpc-core" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
     rxjs "^7.5.5"
 
-"@polkadot/api-contract@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-8.6.2.tgz#09811f7591916762fa7f1dee34de8fe4b7448187"
-  integrity sha512-FWrH7x7qBN0KgsuyymaPrD5B20pKUr6CjmFaR1Ej86+ZnHbRML7q9TrWTFrD2P3+Irx7dy1ubDwVhjcysC3h2Q==
+"@polkadot/api-contract@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-8.7.2-11.tgz#9487394286e536a7b1edfb6296529722fa63a43a"
+  integrity sha512-vOi4FX33ttkotJDzSum0nFUworWJ2+yfDejZkC33mM8zb+ne0Quggfz2nQqiKS2lgkj2z4YwJbsf/9paRQeS3w==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/api" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/types-create" "8.6.2"
-    "@polkadot/util" "^9.3.1"
-    "@polkadot/util-crypto" "^9.3.1"
+    "@polkadot/api" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/types-create" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
+    "@polkadot/util-crypto" "^9.4.1"
     rxjs "^7.5.5"
 
-"@polkadot/api-derive@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-8.6.2.tgz#14019905b2aad6839d57b679c9b7cd42b2faeea7"
-  integrity sha512-ts7DSIeNpH4OH18+mrjq3KObcfHOd6A7C3Ddo2NZv7WmVbUZ9PoJ41jUQZ51szbgILY748ewNlhVsfd/qdVnTg==
+"@polkadot/api-derive@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-8.7.2-11.tgz#21e315d554a8cd31bb1f3b10077960e35391a311"
+  integrity sha512-8fkYidDgNjJcWHtiRfJQaI4H386uGZh5Ie0t21KG4sSC5R+Lbnm0CJwIX4scJvQ/U+38gCyQW07b+Pxt9oDwvg==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/api" "8.6.2"
-    "@polkadot/api-augment" "8.6.2"
-    "@polkadot/api-base" "8.6.2"
-    "@polkadot/rpc-core" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/util" "^9.3.1"
-    "@polkadot/util-crypto" "^9.3.1"
+    "@polkadot/api" "8.7.2-11"
+    "@polkadot/api-augment" "8.7.2-11"
+    "@polkadot/api-base" "8.7.2-11"
+    "@polkadot/rpc-core" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
+    "@polkadot/util-crypto" "^9.4.1"
     rxjs "^7.5.5"
 
-"@polkadot/api@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-8.6.2.tgz#058048e69f55646074b23936dbeb654ec4bbf641"
-  integrity sha512-dmgz9msxQG/K2ol7X0jlcZR1cPtw2qA9OhJ7GxGDc1t0WQiPtU/VRgZg4hBV2qR3n3V4fmbojQwPjBELzfhL+Q==
+"@polkadot/api@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-8.7.2-11.tgz#d76ad24f96fc9eba49825c11277105d12bf5e05c"
+  integrity sha512-eFQtZOJOVK5IbNSjvrk1JrOZJrtZRjaecMAhnQiglMPoIfQJiRbnXhUslGbXsgFoJsfWW6DAVY5aJi/PjuF9OQ==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/api-augment" "8.6.2"
-    "@polkadot/api-base" "8.6.2"
-    "@polkadot/api-derive" "8.6.2"
-    "@polkadot/keyring" "^9.3.1"
-    "@polkadot/rpc-augment" "8.6.2"
-    "@polkadot/rpc-core" "8.6.2"
-    "@polkadot/rpc-provider" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-augment" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/types-create" "8.6.2"
-    "@polkadot/types-known" "8.6.2"
-    "@polkadot/util" "^9.3.1"
-    "@polkadot/util-crypto" "^9.3.1"
+    "@polkadot/api-augment" "8.7.2-11"
+    "@polkadot/api-base" "8.7.2-11"
+    "@polkadot/api-derive" "8.7.2-11"
+    "@polkadot/keyring" "^9.4.1"
+    "@polkadot/rpc-augment" "8.7.2-11"
+    "@polkadot/rpc-core" "8.7.2-11"
+    "@polkadot/rpc-provider" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-augment" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/types-create" "8.7.2-11"
+    "@polkadot/types-known" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
+    "@polkadot/util-crypto" "^9.4.1"
     eventemitter3 "^4.0.7"
     rxjs "^7.5.5"
 
-"@polkadot/keyring@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-9.3.1.tgz#bc90c4ef4c7a46cc92df3e3651cf95ebc1b9c20d"
-  integrity sha512-eoBWRhCzvcVHfpxJlmbKpe8HYjHRc1nkqPR8bnIEb+N8DyN38O7zOHVmy14VOGba1p/+nShULSEVLdfoCD5l3Q==
+"@polkadot/keyring@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-9.4.1.tgz#4bc8d1c1962756841742abac0d7e4ef233d9c2a9"
+  integrity sha512-op6Tj8E9GHeZYvEss38FRUrX+GlBj6qiwF4BlFrAvPqjPnRn8TT9NhRLroiCwvxeNg3uMtEF/5xB+vvdI0I6qw==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/util" "9.3.1"
-    "@polkadot/util-crypto" "9.3.1"
+    "@polkadot/util" "9.4.1"
+    "@polkadot/util-crypto" "9.4.1"
 
-"@polkadot/networks@9.3.1", "@polkadot/networks@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-9.3.1.tgz#1290a21ff86e0b8021b98454c4b61b7ef9bf55d8"
-  integrity sha512-7OUvO5hqXIeijlhTqhFy84lJzA7LRh6In2AbfOUHK6ES1np53Hcas+yEMC2EFNOdBYEsSjnfCjnp4Wd5t7LIHQ==
+"@polkadot/networks@9.4.1", "@polkadot/networks@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-9.4.1.tgz#acdf3d64421ce0e3d3ba68797fc29a28ee40c185"
+  integrity sha512-ibH8bZ2/XMXv0XEsP1fGOqNnm2mg1rHo5kHXSJ3QBcZJFh1+xkI4Ovl2xrFfZ+SYATA3Wsl5R6knqimk2EqyJQ==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/util" "9.3.1"
-    "@substrate/ss58-registry" "^1.20.0"
+    "@polkadot/util" "9.4.1"
+    "@substrate/ss58-registry" "^1.22.0"
 
-"@polkadot/rpc-augment@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-8.6.2.tgz#365c53a1789fb8f2b03e47d0a1660e28e28d03e5"
-  integrity sha512-1iUFTpkegFK6xRYohI0xN/tR6tIttfwwlP4FxlqkXhdeqd2aJx+KUkhsefK2yANfsnRl1//VGPfAMyQuePZAzg==
+"@polkadot/rpc-augment@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-8.7.2-11.tgz#b118303653fb6f80688c62600fde2ed489e1c974"
+  integrity sha512-/h50Kzz/UZwhsV+g7bwGWf0fkVvlWIQ/zaA7H9xtuE4VGvmZRE4Uu06011ToVWNyAwM5xQfXBx1gUznRhem+pg==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/rpc-core" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/rpc-core" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/rpc-core@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-8.6.2.tgz#6072ec27f01c8a6024517b99c8d3295d7d492a85"
-  integrity sha512-AJjzjgnKA3BZgYb3+eqECfIV/mBKH3xO0yn4fhf9O3vgUzJZgEr7JgGMyH0jxnBIAUp84VKlloRDwtRSElCa9A==
+"@polkadot/rpc-core@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-8.7.2-11.tgz#9c31a34bc2f70e4dab40f9ba08ca9b89c8f3e5c0"
+  integrity sha512-DyHYgzBusMFfsDJ/2VBaVTNHRwZ2cf/woaeJA/ijJbxK2Ke/sg9UW6zr+3Ip8T62GnSNnJoSHMOaMdqvebkNVQ==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/rpc-augment" "8.6.2"
-    "@polkadot/rpc-provider" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/rpc-augment" "8.7.2-11"
+    "@polkadot/rpc-provider" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
     rxjs "^7.5.5"
 
-"@polkadot/rpc-provider@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-8.6.2.tgz#266e7ea7a9e233f33bf3aac2f7e0a3da76f9e98a"
-  integrity sha512-hUu4Jk3aVJd3Rqag3KkrUoEJqZh+RoppVWYYBUbWltmVv7rz0JJSYs6r+O7vKpEUqJk3Xfiy6tcKU7ajDTRCLw==
+"@polkadot/rpc-provider@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-8.7.2-11.tgz#1f4ef542aee83e0c4e1b2a126ed00ade7c818660"
+  integrity sha512-LE5kKEMxL4mZ+dLbU8lOPG2GuPYliYtX1SnXv509zAgUjSCWW9fkdeMBF3tFCjSJJcUmle3mlxG8kYuAqNUScA==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/keyring" "^9.3.1"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-support" "8.6.2"
-    "@polkadot/util" "^9.3.1"
-    "@polkadot/util-crypto" "^9.3.1"
-    "@polkadot/x-fetch" "^9.3.1"
-    "@polkadot/x-global" "^9.3.1"
-    "@polkadot/x-ws" "^9.3.1"
+    "@polkadot/keyring" "^9.4.1"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-support" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
+    "@polkadot/util-crypto" "^9.4.1"
+    "@polkadot/x-fetch" "^9.4.1"
+    "@polkadot/x-global" "^9.4.1"
+    "@polkadot/x-ws" "^9.4.1"
     "@substrate/connect" "0.7.5"
     eventemitter3 "^4.0.7"
-    mock-socket "^9.1.4"
-    nock "^13.2.4"
+    mock-socket "^9.1.5"
+    nock "^13.2.6"
 
 "@polkadot/ts@0.4.22":
   version "0.4.22"
@@ -652,117 +652,117 @@
   dependencies:
     "@types/chrome" "^0.0.171"
 
-"@polkadot/typegen@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/typegen/-/typegen-8.6.2.tgz#52024396c79eb5567a960324d992ce49323aace7"
-  integrity sha512-sQGbffUGoTtFQlGmEy0wBwWReRRh1PN7lQfZtJD/op9GMAVzSwqQmqIyCQkQC/nvafYgzKVFylzjJFHRRucECQ==
+"@polkadot/typegen@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/typegen/-/typegen-8.7.2-11.tgz#047c3c91f4b34f0188853bed606fd12f6a0fbf4d"
+  integrity sha512-YZpyT8LJFm3akFurrxHpRWxZU50yKvrfdgyZpJh+JJOhSIIDtkx58JNj2+lv0QvhUFOUkd4IWap9bbCPmeLf6w==
   dependencies:
     "@babel/core" "^7.18.2"
     "@babel/register" "^7.17.7"
     "@babel/runtime" "^7.18.3"
-    "@polkadot/api" "8.6.2"
-    "@polkadot/api-augment" "8.6.2"
-    "@polkadot/rpc-augment" "8.6.2"
-    "@polkadot/rpc-provider" "8.6.2"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-augment" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/types-create" "8.6.2"
-    "@polkadot/types-support" "8.6.2"
-    "@polkadot/util" "^9.3.1"
-    "@polkadot/x-ws" "^9.3.1"
+    "@polkadot/api" "8.7.2-11"
+    "@polkadot/api-augment" "8.7.2-11"
+    "@polkadot/rpc-augment" "8.7.2-11"
+    "@polkadot/rpc-provider" "8.7.2-11"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-augment" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/types-create" "8.7.2-11"
+    "@polkadot/types-support" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
+    "@polkadot/x-ws" "^9.4.1"
     handlebars "^4.7.7"
     websocket "^1.0.34"
     yargs "^17.5.1"
 
-"@polkadot/types-augment@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-8.6.2.tgz#60392a09c842e32d429bcef08582cb6b5894889a"
-  integrity sha512-pY0siJ+2Jba4Vp0z7iif02pvkFZksWvCfmO19OH3lnY176mFwCJGnqvg8V1HIKAwbYZ3g4N2OSoWhB8zyKF63w==
+"@polkadot/types-augment@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-8.7.2-11.tgz#c63105c76f8d85f7e642f8e81e16c3ffc3b3e7c4"
+  integrity sha512-1meIbpS0Synfdz+Jo90jc/utxwbwl9XQiH5WoFCUYLlbtE/H/yQcIoeme5o6gr/q7BalFQMYYwGBfctGT/KGjA==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/types-codec@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-8.6.2.tgz#1cbfe1c44b4c2a67a8e3cff20b561940a731c4b6"
-  integrity sha512-A8be8y0Spu/lgKH0cif+vTXOTHzRkavrQNCH0oJ2uhdLpWUiwjLWFd6i7C/Nha1TxxECFTa0GzgM7l+uYVRRNQ==
+"@polkadot/types-codec@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-8.7.2-11.tgz#a852d3493062ee1052f7a837d07cce4146f2c67e"
+  integrity sha512-ZvRBiVo5IwZ+vcbKIMv6l0kRG2bVpBmU+pCPdWV9zGtKpgumz1FTvxBmjXoNo6OJVX23fKNMF8qBD/DEiC9ZwA==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/types-create@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-8.6.2.tgz#92c8bb7aac8f22731b467ba80e5decaf00239d40"
-  integrity sha512-4amHTHOXDmHVf3DJENoBpTJ9a+O7dyBkRdehrFOBf84qQAA9DfvkoGjiVehDd+Txce7WnOyC8Ugo2Th3jhY+6A==
+"@polkadot/types-create@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-8.7.2-11.tgz#2489409155d55c941a322349d740e9f8f8325147"
+  integrity sha512-489UaZP7JKfZ2Fn0oDQ32setAiV7vv9Q3Kg4a+j4m2TGEEXAVeiNE4Uvijmsw3ayLTtzO9hL0WtMpFWa8GlIMg==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/types-known@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-8.6.2.tgz#6172bf20719d659fc5e968226ece0de029b84ee1"
-  integrity sha512-R8AazycMaOE49+AfjHJ+w+L10RB6wdjprIu0H6UU3oxKWR4fSvYFaEfuscAU7cywzfLnWAbB3wXTJzf2hCbcXg==
+"@polkadot/types-known@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-8.7.2-11.tgz#89cb0cdea197ed3887b30948a560b0cd13b39c23"
+  integrity sha512-ulPQCmwJTJ/MGJGVJZfjWEGq28HGl7D4sOrigbfLOlo6/KyFl2p5H4GUFeF/s+/lGfUQsxfu4Q6QgXDZAOkB1A==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/networks" "^9.3.1"
-    "@polkadot/types" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/types-create" "8.6.2"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/networks" "^9.4.1"
+    "@polkadot/types" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/types-create" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/types-support@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-8.6.2.tgz#0f099eed3725c8904012fdf7432f82ada8ab567c"
-  integrity sha512-z54SOCtIeCoK6DmEKvT7+c3sJl/ek4XpA8EQHcJ5mWl0GrR8iv5pliuqltcJuBG54YQxxgUKg1JJEtnFfcWkRA==
+"@polkadot/types-support@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-8.7.2-11.tgz#ed08331ba1faf7a803e35aafa0692eefd28baa90"
+  integrity sha512-oflUi0eahFMoS3Sxz6EKjZKNl7GMRnd91kClEV0FzR1wEha+3CL1BCXTGV3n8YoJtfztUUNInVHPQTvMW78WvQ==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/util" "^9.3.1"
+    "@polkadot/util" "^9.4.1"
 
-"@polkadot/types@8.6.2":
-  version "8.6.2"
-  resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-8.6.2.tgz#4a0aad232a21b2c7465d4825e52b0565f0cc3b1d"
-  integrity sha512-T35bTk0HojZPJGiJw5t1GFZhg+LU1S1xkZ4EmhxlxjK31dVJVVzwgafdp/fMaSWUKmr32X9mvxVIErtUtUUQ+A==
+"@polkadot/types@8.7.2-11":
+  version "8.7.2-11"
+  resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-8.7.2-11.tgz#84b1dca2896fec4af23d4096fa810b59f44071ac"
+  integrity sha512-PSreCXr/csWpMVqtByEj7Pk5j+JEqxOiipsP+PdtOJaRnWtBMFpMqs7Fj2uULVYqFJKKPyp+JofnRDRcH1YDYg==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/keyring" "^9.3.1"
-    "@polkadot/types-augment" "8.6.2"
-    "@polkadot/types-codec" "8.6.2"
-    "@polkadot/types-create" "8.6.2"
-    "@polkadot/util" "^9.3.1"
-    "@polkadot/util-crypto" "^9.3.1"
+    "@polkadot/keyring" "^9.4.1"
+    "@polkadot/types-augment" "8.7.2-11"
+    "@polkadot/types-codec" "8.7.2-11"
+    "@polkadot/types-create" "8.7.2-11"
+    "@polkadot/util" "^9.4.1"
+    "@polkadot/util-crypto" "^9.4.1"
     rxjs "^7.5.5"
 
-"@polkadot/util-crypto@9.3.1", "@polkadot/util-crypto@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-9.3.1.tgz#9595c7dc6744ab4cd78eade574a2ab1741fc4768"
-  integrity sha512-4Vd/FDMLhw9ceUVbBeafjvroHqWN2y85oydhiSN8WCr57ezsaknNPagovEGpUcUAWcrnRDngsxHRWmUmghEF6A==
+"@polkadot/util-crypto@9.4.1", "@polkadot/util-crypto@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-9.4.1.tgz#af50d9b3e3fcf9760ee8eb262b1cc61614c21d98"
+  integrity sha512-V6xMOjdd8Kt/QmXlcDYM4WJDAmKuH4vWSlIcMmkFHnwH/NtYVdYIDZswLQHKL8gjLijPfVTHpWaJqNFhGpZJEg==
   dependencies:
     "@babel/runtime" "^7.18.3"
     "@noble/hashes" "1.0.0"
     "@noble/secp256k1" "1.5.5"
-    "@polkadot/networks" "9.3.1"
-    "@polkadot/util" "9.3.1"
+    "@polkadot/networks" "9.4.1"
+    "@polkadot/util" "9.4.1"
     "@polkadot/wasm-crypto" "^6.1.1"
-    "@polkadot/x-bigint" "9.3.1"
-    "@polkadot/x-randomvalues" "9.3.1"
+    "@polkadot/x-bigint" "9.4.1"
+    "@polkadot/x-randomvalues" "9.4.1"
     "@scure/base" "1.0.0"
     ed2curve "^0.3.0"
     tweetnacl "^1.0.3"
 
-"@polkadot/util@9.3.1", "@polkadot/util@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-9.3.1.tgz#cae1bc0b8e68450a3f0c0a0c636f9f82e524549c"
-  integrity sha512-WVsihsFMhM0eLylP5LybNh5opD3nzYBdPEIuHf5IiGbhk0pVQEWE3mqcR2fSvSDv3ArQG5KE5cq26JZDVunZlw==
+"@polkadot/util@9.4.1", "@polkadot/util@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-9.4.1.tgz#49446e88b1231b0716bf6b4eb4818145f08a1294"
+  integrity sha512-z0HcnIe3zMWyK1s09wQIwc1M8gDKygSF9tDAbC8H9KDeIRZB2ldhwWEFx/1DJGOgFFrmRfkxeC6dcDpfzQhFow==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-bigint" "9.3.1"
-    "@polkadot/x-global" "9.3.1"
-    "@polkadot/x-textdecoder" "9.3.1"
-    "@polkadot/x-textencoder" "9.3.1"
+    "@polkadot/x-bigint" "9.4.1"
+    "@polkadot/x-global" "9.4.1"
+    "@polkadot/x-textdecoder" "9.4.1"
+    "@polkadot/x-textencoder" "9.4.1"
     "@types/bn.js" "^5.1.0"
     bn.js "^5.2.1"
     ip-regex "^4.3.0"
@@ -818,62 +818,62 @@
   dependencies:
     "@babel/runtime" "^7.17.9"
 
-"@polkadot/x-bigint@9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-9.3.1.tgz#d83b2c6cce1bb859954764d465c27316c0f9a2ca"
-  integrity sha512-eBukzcqxLwAbCNZzfcLhgTtgjOlNVRnS8SETun1ChMzLG7Ytm65qx8wleIpeYQ/vDIT07pA1sDmw+4Bhg+5ALw==
+"@polkadot/x-bigint@9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-9.4.1.tgz#0a7c6b5743a6fb81ab6a1c3a48a584e774c37910"
+  integrity sha512-KlbXboegENoyrpjj+eXfY13vsqrXgk4620zCAUhKNH622ogdvAepHbY/DpV6w0FLEC6MwN9zd5cRuDBEXVeWiw==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-global" "9.3.1"
+    "@polkadot/x-global" "9.4.1"
 
-"@polkadot/x-fetch@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-9.3.1.tgz#9d6e878abd6f2309414beecded6b8aad70bb3109"
-  integrity sha512-ypWxDxJ0Lq2enRf1+XcHBNRNxm1UFcrYJbsrGZkaP+AOZdPQLWrFB/JigSXTXOS3KnuxWecqLwiFOHis4GicXg==
+"@polkadot/x-fetch@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-9.4.1.tgz#92802d3880db826a90bf1be90174a9fc73fc044a"
+  integrity sha512-CZFPZKgy09TOF5pOFRVVhGrAaAPdSMyrUSKwdO2I8DzdIE1tmjnol50dlnZja5t8zTD0n1uIY1H4CEWwc5NF/g==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-global" "9.3.1"
+    "@polkadot/x-global" "9.4.1"
     "@types/node-fetch" "^2.6.1"
     node-fetch "^2.6.7"
 
-"@polkadot/x-global@9.3.1", "@polkadot/x-global@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-9.3.1.tgz#0bae8c93178f5616a93714f4abd98cd5199ec2a7"
-  integrity sha512-D/6wtyaZNDMIJ73fEoZbeDyULs1rBZc/pfLlSczo9efthOheZTY6KUIvPPrZFGd0b817j5Kex3ABcx7uYgWOjw==
+"@polkadot/x-global@9.4.1", "@polkadot/x-global@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-9.4.1.tgz#3bd44862ea2b7e0fb2de766dfa4d56bb46d19e17"
+  integrity sha512-eN4oZeRdIKQeUPNN7OtH5XeYp349d8V9+gW6W0BmCfB2lTg8TDlG1Nj+Cyxpjl9DNF5CiKudTq72zr0dDSRbwA==
   dependencies:
     "@babel/runtime" "^7.18.3"
 
-"@polkadot/x-randomvalues@9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-9.3.1.tgz#cc2af3dbbd0cd81da0b9cc39d03d43ab24fca946"
-  integrity sha512-3X9aIKXweeZXAmwUsJIEwssHKVNxDbGH3A4IkqzUcxne7QyODjLSwAD84n6mDSye00gnqk6L0rb/IwF2Vf+PqA==
+"@polkadot/x-randomvalues@9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-9.4.1.tgz#ab995b3a22aee6bffc18490e636e1a7409f36a15"
+  integrity sha512-TLOQw3JNPgCrcq9WO2ipdeG8scsSreu3m9hwj3n7nX/QKlVzSf4G5bxJo5TW1dwcUdHwBuVox+3zgCmo+NPh+Q==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-global" "9.3.1"
+    "@polkadot/x-global" "9.4.1"
 
-"@polkadot/x-textdecoder@9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-9.3.1.tgz#e449fb2adadbbf4e3e0ff95da969e634829fe07e"
-  integrity sha512-YJgcVUYvuGOkRcBVKTmE6ZXB7VpzMmhCy+DfHDijbnuRDywK0uM8zwXK7hCuPLwfZ8iLX/APpzM5ryNaleiIiA==
+"@polkadot/x-textdecoder@9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-9.4.1.tgz#1d891b82f4192d92dd373d14ea4b5654d0130484"
+  integrity sha512-yLulcgVASFUBJqrvS6Ssy0ko9teAfbu1ajH0r3Jjnqkpmmz2DJ1CS7tAktVa7THd4GHPGeKAVfxl+BbV/LZl+w==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-global" "9.3.1"
+    "@polkadot/x-global" "9.4.1"
 
-"@polkadot/x-textencoder@9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-9.3.1.tgz#537f014f9fd7c22238b336d159d2cbaa6003aba2"
-  integrity sha512-f0hnI5iV/JmwJGPzKAeJ4R9ojuFJWbIM9NIg+Q53Fg6PmJUpY2xQVh1BjzSwRy+lFy0ubfB7Fw9A8KBkDYxCSw==
+"@polkadot/x-textencoder@9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-9.4.1.tgz#09c47727d7713884cf82fd773e478487fe39d479"
+  integrity sha512-/47wa31jBa43ULqMO60vzcJigTG+ZAGNcyT5r6hFLrQzRzc8nIBjIOD8YWtnKM92r9NvlNv2wJhdamqyU0mntg==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-global" "9.3.1"
+    "@polkadot/x-global" "9.4.1"
 
-"@polkadot/x-ws@^9.3.1":
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-9.3.1.tgz#c30194a2d421b919d310668af97ee650a03e43d2"
-  integrity sha512-9WoahcxygKcA7RWOeijW5Kzw6QG7QDc0MPFmygiNMuOqVeEP54c4Yrw1DirZnmRbedhms/OieskPDX4JvxlFmg==
+"@polkadot/x-ws@^9.4.1":
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-9.4.1.tgz#c48f2ef3e80532f4b366b57b6661429b46a16155"
+  integrity sha512-zQjVxXgHsBVn27u4bjY01cFO6XWxgv2b3MMOpNHTKTAs8SLEmFf0LcT7fBShimyyudyTeJld5pHApJ4qp1OXxA==
   dependencies:
     "@babel/runtime" "^7.18.3"
-    "@polkadot/x-global" "9.3.1"
+    "@polkadot/x-global" "9.4.1"
     "@types/websocket" "^1.0.5"
     websocket "^1.0.34"
 
@@ -910,10 +910,10 @@
     pako "^2.0.4"
     websocket "^1.0.32"
 
-"@substrate/ss58-registry@^1.20.0":
-  version "1.20.0"
-  resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.20.0.tgz#a12fd6884eab4167b123a4ccafe94efe4d0109aa"
-  integrity sha512-0YyH7iYbn3yuzKjpRP9gKB4O+Xg6Ciszokz3h5wrRZMz/474rhjpmR+SF1NRvVdNv+rNl3ua/o45D8CPq++TUg==
+"@substrate/ss58-registry@^1.22.0":
+  version "1.22.0"
+  resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.22.0.tgz#d115bc5dcab8c0f5800e05e4ef265949042b13ec"
+  integrity sha512-IKqrPY0B3AeIXEc5/JGgEhPZLy+SmVyQf+k0SIGcNSTqt1GLI3gQFEOFwSScJdem+iYZQUrn6YPPxC3TpdSC3A==
 
 "@szmarczak/http-timer@^1.1.2":
   version "1.1.2"
@@ -1012,14 +1012,14 @@
     form-data "^3.0.0"
 
 "@types/node@*", "@types/node@^17.0.35":
-  version "17.0.35"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.35.tgz#635b7586086d51fb40de0a2ec9d1014a5283ba4a"
-  integrity sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==
+  version "17.0.41"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.41.tgz#1607b2fd3da014ae5d4d1b31bc792a39348dfb9b"
+  integrity sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw==
 
 "@types/node@^12.12.6":
-  version "12.20.52"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.52.tgz#2fd2dc6bfa185601b15457398d4ba1ef27f81251"
-  integrity sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==
+  version "12.20.55"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
+  integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
 
 "@types/pbkdf2@^3.0.0":
   version "3.1.0"
@@ -1043,13 +1043,13 @@
     "@types/node" "*"
 
 "@typescript-eslint/eslint-plugin@^5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.26.0.tgz#c1f98ccba9d345e38992975d3ca56ed6260643c2"
-  integrity sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.1.tgz#fdf59c905354139046b41b3ed95d1609913d0758"
+  integrity sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.26.0"
-    "@typescript-eslint/type-utils" "5.26.0"
-    "@typescript-eslint/utils" "5.26.0"
+    "@typescript-eslint/scope-manager" "5.27.1"
+    "@typescript-eslint/type-utils" "5.27.1"
+    "@typescript-eslint/utils" "5.27.1"
     debug "^4.3.4"
     functional-red-black-tree "^1.0.1"
     ignore "^5.2.0"
@@ -1058,68 +1058,68 @@
     tsutils "^3.21.0"
 
 "@typescript-eslint/parser@^5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.26.0.tgz#a61b14205fe2ab7533deb4d35e604add9a4ceee2"
-  integrity sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.27.1.tgz#3a4dcaa67e45e0427b6ca7bb7165122c8b569639"
+  integrity sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.26.0"
-    "@typescript-eslint/types" "5.26.0"
-    "@typescript-eslint/typescript-estree" "5.26.0"
+    "@typescript-eslint/scope-manager" "5.27.1"
+    "@typescript-eslint/types" "5.27.1"
+    "@typescript-eslint/typescript-estree" "5.27.1"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz#44209c7f649d1a120f0717e0e82da856e9871339"
-  integrity sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==
+"@typescript-eslint/scope-manager@5.27.1":
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.27.1.tgz#4d1504392d01fe5f76f4a5825991ec78b7b7894d"
+  integrity sha512-fQEOSa/QroWE6fAEg+bJxtRZJTH8NTskggybogHt4H9Da8zd4cJji76gA5SBlR0MgtwF7rebxTbDKB49YUCpAg==
   dependencies:
-    "@typescript-eslint/types" "5.26.0"
-    "@typescript-eslint/visitor-keys" "5.26.0"
+    "@typescript-eslint/types" "5.27.1"
+    "@typescript-eslint/visitor-keys" "5.27.1"
 
-"@typescript-eslint/type-utils@5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.26.0.tgz#937dee97702361744a3815c58991acf078230013"
-  integrity sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==
+"@typescript-eslint/type-utils@5.27.1":
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.27.1.tgz#369f695199f74c1876e395ebea202582eb1d4166"
+  integrity sha512-+UC1vVUWaDHRnC2cQrCJ4QtVjpjjCgjNFpg8b03nERmkHv9JV9X5M19D7UFMd+/G7T/sgFwX2pGmWK38rqyvXw==
   dependencies:
-    "@typescript-eslint/utils" "5.26.0"
+    "@typescript-eslint/utils" "5.27.1"
     debug "^4.3.4"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.26.0.tgz#cb204bb154d3c103d9cc4d225f311b08219469f3"
-  integrity sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==
+"@typescript-eslint/types@5.27.1":
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.27.1.tgz#34e3e629501349d38be6ae97841298c03a6ffbf1"
+  integrity sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==
 
-"@typescript-eslint/typescript-estree@5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz#16cbceedb0011c2ed4f607255f3ee1e6e43b88c3"
-  integrity sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==
+"@typescript-eslint/typescript-estree@5.27.1":
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.1.tgz#7621ee78607331821c16fffc21fc7a452d7bc808"
+  integrity sha512-DnZvvq3TAJ5ke+hk0LklvxwYsnXpRdqUY5gaVS0D4raKtbznPz71UJGnPTHEFo0GDxqLOLdMkkmVZjSpET1hFw==
   dependencies:
-    "@typescript-eslint/types" "5.26.0"
-    "@typescript-eslint/visitor-keys" "5.26.0"
+    "@typescript-eslint/types" "5.27.1"
+    "@typescript-eslint/visitor-keys" "5.27.1"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.26.0.tgz#896b8480eb124096e99c8b240460bb4298afcfb4"
-  integrity sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==
+"@typescript-eslint/utils@5.27.1":
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.27.1.tgz#b4678b68a94bc3b85bf08f243812a6868ac5128f"
+  integrity sha512-mZ9WEn1ZLDaVrhRaYgzbkXBkTPghPFsup8zDbbsYTxC5OmqrFE7skkKS/sraVsLP3TcT3Ki5CSyEFBRkLH/H/w==
   dependencies:
     "@types/json-schema" "^7.0.9"
-    "@typescript-eslint/scope-manager" "5.26.0"
-    "@typescript-eslint/types" "5.26.0"
-    "@typescript-eslint/typescript-estree" "5.26.0"
+    "@typescript-eslint/scope-manager" "5.27.1"
+    "@typescript-eslint/types" "5.27.1"
+    "@typescript-eslint/typescript-estree" "5.27.1"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
 
-"@typescript-eslint/visitor-keys@5.26.0":
-  version "5.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz#7195f756e367f789c0e83035297c45b417b57f57"
-  integrity sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==
+"@typescript-eslint/visitor-keys@5.27.1":
+  version "5.27.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.1.tgz#05a62666f2a89769dac2e6baa48f74e8472983af"
+  integrity sha512-xYs6ffo01nhdJgPieyk7HAOpjhTsx7r/oB9LWEhwAXgwn33tkr+W8DI2ChboqhZlC4q3TC6geDYPoiX8ROqyOQ==
   dependencies:
-    "@typescript-eslint/types" "5.26.0"
+    "@typescript-eslint/types" "5.27.1"
     eslint-visitor-keys "^3.3.0"
 
 "@ungap/promise-all-settled@1.1.2":
@@ -1428,14 +1428,14 @@
     safe-buffer "^5.2.0"
 
 browserslist@^4.20.2:
-  version "4.20.3"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf"
-  integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==
+  version "4.20.4"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.4.tgz#98096c9042af689ee1e0271333dbc564b8ce4477"
+  integrity sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==
   dependencies:
-    caniuse-lite "^1.0.30001332"
-    electron-to-chromium "^1.4.118"
+    caniuse-lite "^1.0.30001349"
+    electron-to-chromium "^1.4.147"
     escalade "^3.1.1"
-    node-releases "^2.0.3"
+    node-releases "^2.0.5"
     picocolors "^1.0.0"
 
 bs58@^4.0.0:
@@ -1528,10 +1528,10 @@
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
   integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
 
-caniuse-lite@^1.0.30001332:
-  version "1.0.30001344"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz#8a1e7fdc4db9c2ec79a05e9fd68eb93a761888bb"
-  integrity sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==
+caniuse-lite@^1.0.30001349:
+  version "1.0.30001352"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz#cc6f5da3f983979ad1e2cdbae0505dccaa7c6a12"
+  integrity sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==
 
 caseless@~0.12.0:
   version "0.12.0"
@@ -1970,12 +1970,12 @@
 duplexer3@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
-  integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
+  integrity sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==
 
 ecc-jsbn@~0.1.1:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
-  integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
+  integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
   dependencies:
     jsbn "~0.1.0"
     safer-buffer "^2.1.0"
@@ -1990,12 +1990,12 @@
 ee-first@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-  integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
+  integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
 
-electron-to-chromium@^1.4.118:
-  version "1.4.140"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.140.tgz#1b5836b7244aff341a11c8efd63dfe003dee4a19"
-  integrity sha512-NLz5va823QfJBYOO/hLV4AfU4Crmkl/6Hl2pH3qdJcmi0ySZ3YTWHxOlDm3uJOFBEPy3pIhu8gKQo6prQTWKKA==
+electron-to-chromium@^1.4.147:
+  version "1.4.150"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.150.tgz#89f0e12505462d5df7e56c5b91aff7e1dfdd33ec"
+  integrity sha512-MP3oBer0X7ZeS9GJ0H6lmkn561UxiwOIY9TTkdxVY7lI9G6GVCKfgJaHaDcakwdKxBXA4T3ybeswH/WBIN/KTA==
 
 elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4:
   version "6.5.4"
@@ -2018,7 +2018,7 @@
 encodeurl@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
-  integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
+  integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
 
 end-of-stream@^1.1.0:
   version "1.4.4"
@@ -2077,7 +2077,7 @@
 es6-iterator@^2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
-  integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
+  integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==
   dependencies:
     d "1"
     es5-ext "^0.10.35"
@@ -2099,7 +2099,7 @@
 escape-html@~1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
-  integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
+  integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
 
 escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
   version "4.0.0"
@@ -2109,7 +2109,7 @@
 escape-string-regexp@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-  integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+  integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
 
 eslint-scope@^5.1.1:
   version "5.1.1"
@@ -2145,9 +2145,9 @@
   integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
 
 eslint@^8.16.0:
-  version "8.16.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.16.0.tgz#6d936e2d524599f2a86c708483b4c372c5d3bbae"
-  integrity sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==
+  version "8.17.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.17.0.tgz#1cfc4b6b6912f77d24b874ca1506b0fe09328c21"
+  integrity sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==
   dependencies:
     "@eslint/eslintrc" "^1.3.0"
     "@humanwhocodes/config-array" "^0.9.2"
@@ -2226,12 +2226,12 @@
 etag@~1.8.1:
   version "1.8.1"
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
-  integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
+  integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
 
 eth-ens-namehash@2.0.8:
   version "2.0.8"
   resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf"
-  integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88=
+  integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==
   dependencies:
     idna-uts46-hx "^2.3.1"
     js-sha3 "^0.5.7"
@@ -2285,10 +2285,10 @@
     secp256k1 "^4.0.1"
     setimmediate "^1.0.5"
 
-ethereumjs-util@^7.0.10, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.4:
-  version "7.1.4"
-  resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458"
-  integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==
+ethereumjs-util@^7.0.10, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5:
+  version "7.1.5"
+  resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181"
+  integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==
   dependencies:
     "@types/bn.js" "^5.1.0"
     bn.js "^5.1.2"
@@ -2299,7 +2299,7 @@
 ethjs-unit@0.1.6:
   version "0.1.6"
   resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699"
-  integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=
+  integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==
   dependencies:
     bn.js "4.11.6"
     number-to-bn "1.7.0"
@@ -2374,7 +2374,7 @@
 extsprintf@1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
-  integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
+  integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
 
 extsprintf@^1.2.0:
   version "1.4.1"
@@ -2405,7 +2405,7 @@
 fast-levenshtein@^2.0.6:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
-  integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
+  integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
 
 fastq@^1.6.0:
   version "1.13.0"
@@ -2507,7 +2507,7 @@
 forever-agent@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
-  integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+  integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
 
 form-data@^3.0.0:
   version "3.0.1"
@@ -2535,7 +2535,7 @@
 fresh@0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
-  integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
+  integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
 
 fs-extra@^4.0.2:
   version "4.0.3"
@@ -2556,7 +2556,7 @@
 fs.realpath@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
+  integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
 
 fsevents@~2.3.2:
   version "2.3.2"
@@ -2581,7 +2581,7 @@
 functional-red-black-tree@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
-  integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+  integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==
 
 functions-have-names@^1.2.2:
   version "1.2.3"
@@ -2601,21 +2601,21 @@
 get-func-name@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
-  integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
+  integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
 
 get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
-  integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
+  integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
   dependencies:
     function-bind "^1.1.1"
     has "^1.0.3"
-    has-symbols "^1.0.1"
+    has-symbols "^1.0.3"
 
 get-stream@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
-  integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
+  integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==
 
 get-stream@^4.1.0:
   version "4.1.0"
@@ -2642,7 +2642,7 @@
 getpass@^0.1.1:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
-  integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
+  integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
   dependencies:
     assert-plus "^1.0.0"
 
@@ -2773,7 +2773,7 @@
 har-schema@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
-  integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
+  integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
 
 har-validator@~5.1.3:
   version "5.1.5"
@@ -2791,7 +2791,7 @@
 has-flag@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
-  integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+  integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
 
 has-flag@^4.0.0:
   version "4.0.0"
@@ -2861,7 +2861,7 @@
 hmac-drbg@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
-  integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
+  integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
   dependencies:
     hash.js "^1.0.3"
     minimalistic-assert "^1.0.0"
@@ -2886,12 +2886,12 @@
 http-https@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b"
-  integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=
+  integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==
 
 http-signature@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
-  integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
+  integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
   dependencies:
     assert-plus "^1.0.0"
     jsprim "^1.2.2"
@@ -2932,12 +2932,12 @@
 imurmurhash@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
-  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+  integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
 
 inflight@^1.0.4:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
-  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+  integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
   dependencies:
     once "^1.3.0"
     wrappy "1"
@@ -3011,7 +3011,7 @@
 is-extglob@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
-  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+  integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
 
 is-fullwidth-code-point@^3.0.0:
   version "3.0.0"
@@ -3040,7 +3040,7 @@
 is-hex-prefixed@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554"
-  integrity sha1-fY035q135dEnFIkTxXPggtd39VQ=
+  integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==
 
 is-negative-zero@^2.0.2:
   version "2.0.2"
@@ -3067,7 +3067,7 @@
 is-plain-obj@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
-  integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
+  integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
 
 is-plain-obj@^2.1.0:
   version "2.1.0"
@@ -3104,7 +3104,7 @@
 is-stream@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-  integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+  integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
 
 is-string@^1.0.5, is-string@^1.0.7:
   version "1.0.7"
@@ -3134,7 +3134,7 @@
 is-typedarray@^1.0.0, is-typedarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
-  integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+  integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
 
 is-unicode-supported@^0.1.0:
   version "0.1.0"
@@ -3151,17 +3151,17 @@
 isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
-  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+  integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
 
 isobject@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
-  integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
+  integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
 
 isstream@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
-  integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+  integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
 
 isurl@^1.0.0-alpha5:
   version "1.0.0"
@@ -3179,7 +3179,7 @@
 js-sha3@^0.5.7:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7"
-  integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=
+  integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==
 
 js-tokens@^4.0.0:
   version "4.0.0"
@@ -3196,7 +3196,7 @@
 jsbn@~0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
-  integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+  integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
 
 jsesc@^2.5.1:
   version "2.5.2"
@@ -3206,7 +3206,7 @@
 json-buffer@3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
-  integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
+  integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==
 
 json-schema-traverse@^0.4.1:
   version "0.4.1"
@@ -3221,12 +3221,12 @@
 json-stable-stringify-without-jsonify@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
-  integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
+  integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
 
 json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
-  integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
+  integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
 
 json5@^2.2.1:
   version "2.2.1"
@@ -3236,7 +3236,7 @@
 jsonfile@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
-  integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
+  integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
   optionalDependencies:
     graceful-fs "^4.1.6"
 
@@ -3299,10 +3299,10 @@
   resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
   integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
 
-lodash.set@^4.3.2:
-  version "4.3.2"
-  resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
-  integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
+lodash@^4.17.21:
+  version "4.17.21"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 
 log-symbols@4.1.0:
   version "4.1.0"
@@ -3361,17 +3361,17 @@
 media-typer@0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
-  integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
+  integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
 
 memorystream@^0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
-  integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=
+  integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==
 
 merge-descriptors@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
-  integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
+  integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
 
 merge2@^1.3.0, merge2@^1.4.1:
   version "1.4.1"
@@ -3381,7 +3381,7 @@
 methods@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
-  integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
+  integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
 
 micromatch@^4.0.4:
   version "4.0.5"
@@ -3429,7 +3429,7 @@
 min-document@^2.19.0:
   version "2.19.0"
   resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
-  integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
+  integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==
   dependencies:
     dom-walk "^0.1.0"
 
@@ -3441,7 +3441,7 @@
 minimalistic-crypto-utils@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
-  integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
+  integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
 
 minimatch@5.0.1:
   version "5.0.1"
@@ -3480,7 +3480,7 @@
 mkdirp-promise@^5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
-  integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=
+  integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==
   dependencies:
     mkdirp "*"
 
@@ -3529,15 +3529,15 @@
   resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18"
   integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==
 
-mock-socket@^9.1.4:
-  version "9.1.4"
-  resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.1.4.tgz#9295cb9c95d3b2730a7bc067008f055635d8fc75"
-  integrity sha512-zc7jF8FId8pD9ojxWLcXrv4c2nEFOb6o8giPb45yQ6BfQX1tWuUktHNFSiy+KBt0VhYtHNt5MFIzclt0LIynEA==
+mock-socket@^9.1.5:
+  version "9.1.5"
+  resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.1.5.tgz#2c4e44922ad556843b6dfe09d14ed8041fa2cdeb"
+  integrity sha512-3DeNIcsQixWHHKk6NdoBhWI4t1VMj5/HzfnI1rE/pLl5qKx7+gd4DNA07ehTaZ6MoUU053si6Hd+YtiM/tQZfg==
 
 ms@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
-  integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+  integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
 
 ms@2.1.2:
   version "2.1.2"
@@ -3592,7 +3592,7 @@
 nano-json-stream-parser@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f"
-  integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=
+  integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==
 
 nanoid@3.3.3:
   version "3.3.3"
@@ -3602,7 +3602,7 @@
 natural-compare@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
-  integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
+  integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
 
 negotiator@0.6.3:
   version "0.6.3"
@@ -3619,14 +3619,14 @@
   resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
   integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
 
-nock@^13.2.4:
-  version "13.2.4"
-  resolved "https://registry.yarnpkg.com/nock/-/nock-13.2.4.tgz#43a309d93143ee5cdcca91358614e7bde56d20e1"
-  integrity sha512-8GPznwxcPNCH/h8B+XZcKjYPXnUV5clOKCjAqyjsiqA++MpNx9E9+t8YPp0MbThO+KauRo7aZJ1WuIZmOrT2Ug==
+nock@^13.2.6:
+  version "13.2.6"
+  resolved "https://registry.yarnpkg.com/nock/-/nock-13.2.6.tgz#35e419cd9d385ffa67e59523d9699e41b29e1a03"
+  integrity sha512-GbyeSwSEP0FYouzETZ0l/XNm5tNcDNcXJKw3LCAb+mx8bZSwg1wEEvdL0FAyg5TkBJYiWSCtw6ag4XfmBy60FA==
   dependencies:
     debug "^4.1.0"
     json-stringify-safe "^5.0.1"
-    lodash.set "^4.3.2"
+    lodash "^4.17.21"
     propagate "^2.0.0"
 
 node-addon-api@^2.0.0:
@@ -3646,7 +3646,7 @@
   resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4"
   integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==
 
-node-releases@^2.0.3:
+node-releases@^2.0.5:
   version "2.0.5"
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666"
   integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==
@@ -3664,7 +3664,7 @@
 number-to-bn@1.7.0:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0"
-  integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=
+  integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==
   dependencies:
     bn.js "4.11.6"
     strip-hex-prefix "1.0.0"
@@ -3677,7 +3677,7 @@
 object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
-  integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
+  integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
 
 object-inspect@^1.12.0, object-inspect@^1.9.0:
   version "1.12.2"
@@ -3702,7 +3702,7 @@
 oboe@2.1.5:
   version "2.1.5"
   resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd"
-  integrity sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=
+  integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==
   dependencies:
     http-https "^1.0.0"
 
@@ -3716,7 +3716,7 @@
 once@^1.3.0, once@^1.3.1, once@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
-  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+  integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
   dependencies:
     wrappy "1"
 
@@ -3735,7 +3735,7 @@
 os-tmpdir@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
-  integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
+  integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
 
 p-cancelable@^0.3.0:
   version "0.3.0"
@@ -3750,7 +3750,7 @@
 p-finally@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
-  integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
+  integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
 
 p-limit@^2.0.0:
   version "2.3.0"
@@ -3783,7 +3783,7 @@
 p-timeout@^1.1.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
-  integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=
+  integrity sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==
   dependencies:
     p-finally "^1.0.0"
 
@@ -3828,7 +3828,7 @@
 path-exists@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
-  integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+  integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
 
 path-exists@^4.0.0:
   version "4.0.0"
@@ -3838,7 +3838,7 @@
 path-is-absolute@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
-  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
+  integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
 
 path-key@^3.1.0:
   version "3.1.1"
@@ -3848,7 +3848,7 @@
 path-to-regexp@0.1.7:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
-  integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
+  integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
 
 path-type@^4.0.0:
   version "4.0.0"
@@ -3874,7 +3874,7 @@
 performance-now@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
-  integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+  integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
 
 picocolors@^1.0.0:
   version "1.0.0"
@@ -3911,17 +3911,17 @@
 prepend-http@^1.0.1:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
-  integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
+  integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==
 
 prepend-http@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
-  integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
+  integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==
 
 process@^0.11.10:
   version "0.11.10"
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
-  integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
+  integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
 
 propagate@^2.0.0:
   version "2.0.1"
@@ -3964,7 +3964,7 @@
 punycode@2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
-  integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=
+  integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==
 
 punycode@^2.1.0, punycode@^2.1.1:
   version "2.1.1"
@@ -4091,7 +4091,7 @@
 require-directory@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
-  integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
+  integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
 
 resolve-from@^4.0.0:
   version "4.0.0"
@@ -4101,7 +4101,7 @@
 responselike@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
-  integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
+  integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==
   dependencies:
     lowercase-keys "^1.0.0"
 
@@ -4242,7 +4242,7 @@
 setimmediate@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
-  integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
+  integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
 
 setprototypeof@1.2.0:
   version "1.2.0"
@@ -4353,7 +4353,7 @@
 strict-uri-encode@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
-  integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
+  integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==
 
 string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
@@ -4399,7 +4399,7 @@
 strip-hex-prefix@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f"
-  integrity sha1-DF8VX+8RUTczd96du1iNoFUA428=
+  integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==
   dependencies:
     is-hex-prefixed "1.0.0"
 
@@ -4512,9 +4512,9 @@
   integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
 
 ts-node@^10.8.0:
-  version "10.8.0"
-  resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.8.0.tgz#3ceb5ac3e67ae8025c1950626aafbdecb55d82ce"
-  integrity sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==
+  version "10.8.1"
+  resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.8.1.tgz#ea2bd3459011b52699d7e88daa55a45a1af4f066"
+  integrity sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==
   dependencies:
     "@cspotcode/source-map-support" "^0.8.0"
     "@tsconfig/node10" "^1.0.7"
@@ -4607,14 +4607,14 @@
     is-typedarray "^1.0.0"
 
 typescript@^4.7.2:
-  version "4.7.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.2.tgz#1f9aa2ceb9af87cca227813b4310fff0b51593c4"
-  integrity sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==
+  version "4.7.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d"
+  integrity sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==
 
 uglify-js@^3.1.4:
-  version "3.15.5"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.5.tgz#2b10f9e0bfb3f5c15a8e8404393b6361eaeb33b3"
-  integrity sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==
+  version "3.16.0"
+  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.0.tgz#b778ba0831ca102c1d8ecbdec2d2bdfcc7353190"
+  integrity sha512-FEikl6bR30n0T3amyBh3LoiBdqHRy/f4H80+My34HOesOKyHfOsxAPAxOoqC0JUnC1amnO0IwkYC3sko51caSw==
 
 ultron@~1.1.0:
   version "1.1.1"