git.delta.rocks / unique-network / refs/commits / 64ceec5bba92

difftreelog

Merge pull request #298 from UniqueNetwork/feature/create-multiple-items-ex

kozyrevdev2022-03-01parents: #c9e84df #9d95058.patch.diff
in: master
Add createMultipleItemsEx call

27 files changed

modified.maintain/frame-weight-template.hbsdiffbeforeafterboth
--- a/.maintain/frame-weight-template.hbs
+++ b/.maintain/frame-weight-template.hbs
@@ -7,7 +7,7 @@
 //! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}}
 
 // Executed Command:
-{{#each args as |arg|~}}
+{{#each args as |arg|}}
 // {{arg}}
 {{/each}}
 
@@ -21,76 +21,80 @@
 
 /// Weight functions needed for {{pallet}}.
 pub trait WeightInfo {
-	{{~#each benchmarks as |benchmark|}}
+	{{#each benchmarks as |benchmark|}}
 	fn {{benchmark.name~}}
 	(
 		{{~#each benchmark.components as |c| ~}}
 		{{c.name}}: u32, {{/each~}}
 	) -> Weight;
-	{{~/each}}
+	{{/each}}
 }
 
 /// Weights for {{pallet}} using the Substrate node and recommended hardware.
 pub struct SubstrateWeight<T>(PhantomData<T>);
+{{#if (eq pallet "frame_system")}}
+impl<T: crate::Config> WeightInfo for SubstrateWeight<T> {
+{{else}}
 impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
-	{{~#each benchmarks as |benchmark|}}
-	{{~#each benchmark.comments as |comment|}}
+{{/if}}
+	{{#each benchmarks as |benchmark|}}
+	{{#each benchmark.comments as |comment|}}
 	// {{comment}}
-	{{~/each}}
+	{{/each}}
 	fn {{benchmark.name~}}
 	(
 		{{~#each benchmark.components as |c| ~}}
 		{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
 	) -> Weight {
 		({{underscore benchmark.base_weight}} as Weight)
-			{{~#each benchmark.component_weight as |cw|}}
+			{{#each benchmark.component_weight as |cw|}}
 			// Standard Error: {{underscore cw.error}}
 			.saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
-			{{~/each}}
-			{{~#if (ne benchmark.base_reads "0")}}
+			{{/each}}
+			{{#if (ne benchmark.base_reads "0")}}
 			.saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}} as Weight))
-			{{~/if}}
-			{{~#each benchmark.component_reads as |cr|}}
+			{{/if}}
+			{{#each benchmark.component_reads as |cr|}}
 			.saturating_add(T::DbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight)))
-			{{~/each}}
-			{{~#if (ne benchmark.base_writes "0")}}
+			{{/each}}
+			{{#if (ne benchmark.base_writes "0")}}
 			.saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}} as Weight))
-			{{~/if}}
-			{{~#each benchmark.component_writes as |cw|}}
+			{{/if}}
+			{{#each benchmark.component_writes as |cw|}}
 			.saturating_add(T::DbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)))
-			{{~/each}}
+			{{/each}}
 	}
-	{{~/each}}
+	{{/each}}
 }
 
 // For backwards compatibility and tests
 impl WeightInfo for () {
-	{{~#each benchmarks as |benchmark|}}
-	{{~#each benchmark.comments as |comment|}}
+	{{#each benchmarks as |benchmark|}}
+	{{#each benchmark.comments as |comment|}}
 	// {{comment}}
-	{{~/each}}
+	{{/each}}
 	fn {{benchmark.name~}}
 	(
 		{{~#each benchmark.components as |c| ~}}
 		{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
 	) -> Weight {
 		({{underscore benchmark.base_weight}} as Weight)
-			{{~#each benchmark.component_weight as |cw|}}
+			{{#each benchmark.component_weight as |cw|}}
 			// Standard Error: {{underscore cw.error}}
 			.saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
-			{{~/each}}
-			{{~#if (ne benchmark.base_reads "0")}}
+			{{/each}}
+			{{#if (ne benchmark.base_reads "0")}}
 			.saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}} as Weight))
-			{{~/if}}
-			{{~#each benchmark.component_reads as |cr|}}
+			{{/if}}
+			{{#each benchmark.component_reads as |cr|}}
 			.saturating_add(RocksDbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight)))
-			{{~/each}}
-			{{~#if (ne benchmark.base_writes "0")}}
+			{{/each}}
+			{{#if (ne benchmark.base_writes "0")}}
 			.saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}} as Weight))
-			{{~/if}}
-			{{~#each benchmark.component_writes as |cw|}}
+			{{/if}}
+			{{#each benchmark.component_writes as |cw|}}
 			.saturating_add(RocksDbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)))
-			{{~/each}}
+			{{/each}}
 	}
-	{{~/each}}
+	{{/each}}
 }
modifiedpallets/common/src/benchmarking.rsdiffbeforeafterboth
1use sp_std::vec::Vec;1use sp_std::vec::Vec;
2use crate::{Config, CollectionHandle};2use crate::{Config, CollectionHandle};
3use up_data_structs::{3use up_data_structs::{
4 CollectionMode, Collection, CollectionId, MAX_COLLECTION_NAME_LENGTH,4 CollectionMode, CreateCollectionData, CollectionId, MAX_COLLECTION_NAME_LENGTH,
5 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, OFFCHAIN_SCHEMA_LIMIT,5 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, OFFCHAIN_SCHEMA_LIMIT,
6 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT,6 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT,
7};7};
8use frame_support::traits::{Currency, Get};8use frame_support::{
9 traits::{Currency, Get},
10 pallet_prelude::ConstU32,
11 BoundedVec,
12};
9use core::convert::TryInto;13use core::convert::TryInto;
10use sp_runtime::DispatchError;14use sp_runtime::DispatchError;
1115
12pub fn create_data(size: usize) -> Vec<u8> {16pub fn create_data<const S: u32>() -> BoundedVec<u8, ConstU32<S>> {
17 create_var_data::<S>(S)
18}
19pub fn create_u16_data<const S: u32>() -> BoundedVec<u16, ConstU32<S>> {
20 (0..S)
13 (0..size).map(|v| (v & 0xff) as u8).collect()21 .map(|v| (v & 0xffff) as u16)
22 .collect::<Vec<_>>()
23 .try_into()
24 .unwrap()
14}25}
15pub fn create_u16_data(size: usize) -> Vec<u16> {26pub fn create_var_data<const S: u32>(size: u32) -> BoundedVec<u8, ConstU32<S>> {
27 assert!(
28 size <= S,
29 "size ({}) should be less within bound ({})",
30 size,
31 S
32 );
16 (0..size).map(|v| (v & 0xffff) as u16).collect()33 (0..size)
34 .map(|v| (v & 0xff) as u8)
35 .collect::<Vec<_>>()
36 .try_into()
37 .unwrap()
17}38}
1839
19pub fn create_collection_raw<T: Config, R>(40pub fn create_collection_raw<T: Config, R>(
20 owner: T::AccountId,41 owner: T::AccountId,
21 mode: CollectionMode,42 mode: CollectionMode,
22 handler: impl FnOnce(Collection<T::AccountId>) -> Result<CollectionId, DispatchError>,43 handler: impl FnOnce(
44 T::AccountId,
45 CreateCollectionData<T::AccountId>,
46 ) -> Result<CollectionId, DispatchError>,
23 cast: impl FnOnce(CollectionHandle<T>) -> R,47 cast: impl FnOnce(CollectionHandle<T>) -> R,
24) -> Result<R, DispatchError> {48) -> Result<R, DispatchError> {
25 T::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());49 T::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());
26 let name = create_u16_data(MAX_COLLECTION_NAME_LENGTH)50 let name = create_u16_data::<MAX_COLLECTION_NAME_LENGTH>();
27 .try_into()
28 .unwrap();
29 let description = create_u16_data(MAX_COLLECTION_DESCRIPTION_LENGTH)51 let description = create_u16_data::<MAX_COLLECTION_DESCRIPTION_LENGTH>();
30 .try_into()
31 .unwrap();
32 let token_prefix = create_data(MAX_TOKEN_PREFIX_LENGTH).try_into().unwrap();52 let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
33 let offchain_schema = create_data(OFFCHAIN_SCHEMA_LIMIT as usize)53 let offchain_schema = create_data::<OFFCHAIN_SCHEMA_LIMIT>();
34 .try_into()
35 .unwrap();
36 let variable_on_chain_schema = create_data(VARIABLE_ON_CHAIN_SCHEMA_LIMIT as usize)54 let variable_on_chain_schema = create_data::<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>();
37 .try_into()
38 .unwrap();
39 let const_on_chain_schema = create_data(CONST_ON_CHAIN_SCHEMA_LIMIT as usize)55 let const_on_chain_schema = create_data::<CONST_ON_CHAIN_SCHEMA_LIMIT>();
40 .try_into()
41 .unwrap();
42 handler(Collection {56 handler(
43 owner,57 owner,
58 CreateCollectionData {
44 mode,59 mode,
45 access: Default::default(),
46 name,60 name,
47 description,61 description,
48 token_prefix,62 token_prefix,
49 mint_mode: true,
50 offchain_schema,63 offchain_schema,
51 schema_version: Default::default(),
52 sponsorship: Default::default(),
53 limits: Default::default(),
54 variable_on_chain_schema,64 variable_on_chain_schema,
55 const_on_chain_schema,65 const_on_chain_schema,
56 meta_update_permission: Default::default(),66 ..Default::default()
67 },
57 })68 )
58 .and_then(CollectionHandle::try_get)69 .and_then(CollectionHandle::try_get)
59 .map(cast)70 .map(cast)
60}71}
6172
73/// Helper macros, which handles all benchmarking preparation in semi-declarative way
74///
75/// `name` is a substrate account
76/// - name: sub[(id)]
77/// `name` is a collection with owner `owner`
78/// - name: collection(owner)
79/// `name` is a cross account based on substrate
80/// - name: cross_sub[(id)]
81/// `name` is a cross account, which maps to substrate account `name`
82/// - name: cross_from_sub
83/// `name` is a cross account, which maps to substrate account `other_name`
84/// - name: cross_from_sub(other_name)
62#[macro_export]85#[macro_export]
63macro_rules! bench_init {86macro_rules! bench_init {
64 ($name:ident: sub $(($id:expr))?; $($rest:tt)*) => {87 ($name:ident: sub $(($id:expr))?; $($rest:tt)*) => {
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -17,7 +17,7 @@
 	TokenId, Weight, WithdrawReasons, CollectionStats, MAX_TOKEN_OWNERSHIP, CollectionMode,
 	NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
 	REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT, CUSTOM_DATA_LIMIT, CollectionLimits,
-	CustomDataLimit, CreateCollectionData, SponsorshipState,
+	CustomDataLimit, CreateCollectionData, SponsorshipState, CreateItemExData,
 };
 pub use pallet::*;
 use sp_core::H160;
@@ -624,9 +624,10 @@
 }
 
 /// Worst cases
-pub trait CommonWeightInfo {
+pub trait CommonWeightInfo<CrossAccountId> {
 	fn create_item() -> Weight;
 	fn create_multiple_items(amount: u32) -> Weight;
+	fn create_multiple_items_ex(cost: &CreateItemExData<CrossAccountId>) -> Weight;
 	fn burn_item() -> Weight;
 	fn transfer() -> Weight;
 	fn approve() -> Weight;
@@ -648,6 +649,11 @@
 		to: T::CrossAccountId,
 		data: Vec<CreateItemData>,
 	) -> DispatchResultWithPostInfo;
+	fn create_multiple_items_ex(
+		&self,
+		sender: T::CrossAccountId,
+		data: CreateItemExData<T::CrossAccountId>,
+	) -> DispatchResultWithPostInfo;
 	fn burn_item(
 		&self,
 		sender: T::CrossAccountId,
modifiedpallets/fungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/fungible/src/benchmarking.rs
+++ b/pallets/fungible/src/benchmarking.rs
@@ -4,7 +4,7 @@
 use sp_std::prelude::*;
 use pallet_common::benchmarking::create_collection_raw;
 use frame_benchmarking::{benchmarks, account};
-use up_data_structs::{CollectionMode};
+use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH};
 use pallet_common::bench_init;
 
 const SEED: u32 = 1;
@@ -26,6 +26,18 @@
 		};
 	}: {<Pallet<T>>::create_item(&collection, &sender, (to, 200))?}
 
+	create_multiple_items_ex {
+		let b in 0..MAX_ITEMS_PER_BATCH;
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			sender: cross_from_sub(owner);
+		};
+		let data = (0..b).map(|i| {
+			bench_init!(to: cross_sub(i););
+			(to, 200)
+		}).collect::<BTreeMap<_, _>>().try_into().unwrap();
+	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data)}
+
 	burn_item {
 		bench_init!{
 			owner: sub; collection: collection(owner);
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -1,7 +1,7 @@
 use core::marker::PhantomData;
 
 use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};
-use up_data_structs::TokenId;
+use up_data_structs::{TokenId, CreateItemExData};
 use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
 use sp_runtime::ArithmeticError;
 use sp_std::{vec::Vec, vec};
@@ -12,7 +12,7 @@
 };
 
 pub struct CommonWeights<T: Config>(PhantomData<T>);
-impl<T: Config> CommonWeightInfo for CommonWeights<T> {
+impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
 	fn create_item() -> Weight {
 		<SelfWeightOf<T>>::create_item()
 	}
@@ -21,6 +21,15 @@
 		Self::create_item()
 	}
 
+	fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
+		match data {
+			CreateItemExData::Fungible(f) => {
+				<SelfWeightOf<T>>::create_multiple_items_ex(f.len() as u32)
+			}
+			_ => 0,
+		}
+	}
+
 	fn burn_item() -> Weight {
 		<SelfWeightOf<T>>::burn_item()
 	}
@@ -87,6 +96,23 @@
 		)
 	}
 
+	fn create_multiple_items_ex(
+		&self,
+		sender: <T>::CrossAccountId,
+		data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,
+	) -> DispatchResultWithPostInfo {
+		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);
+		let data = match data {
+			up_data_structs::CreateItemExData::Fungible(f) => f,
+			_ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),
+		};
+
+		with_weight(
+			<Pallet<T>>::create_multiple_items(self, &sender, data.into_inner()),
+			weight,
+		)
+	}
+
 	fn burn_item(
 		&self,
 		sender: T::CrossAccountId,
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -9,7 +9,7 @@
 use pallet_evm_coder_substrate::WithRecorder;
 use sp_core::H160;
 use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
-use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
+use sp_std::collections::btree_map::BTreeMap;
 
 pub use pallet::*;
 
@@ -222,7 +222,7 @@
 	pub fn create_multiple_items(
 		collection: &FungibleHandle<T>,
 		sender: &T::CrossAccountId,
-		data: Vec<CreateItemData<T>>,
+		data: BTreeMap<T::CrossAccountId, u128>,
 	) -> DispatchResult {
 		if !collection.is_owner_or_admin(sender) {
 			ensure!(
@@ -235,23 +235,19 @@
 				collection.check_allowlist(owner)?;
 			}
 		}
-
-		let mut balances = BTreeMap::new();
 
 		let total_supply = data
 			.iter()
-			.map(|u| u.1)
+			.map(|(_, v)| *v)
 			.try_fold(<TotalSupply<T>>::get(collection.id), |acc, v| {
 				acc.checked_add(v)
 			})
 			.ok_or(ArithmeticError::Overflow)?;
 
-		for (user, amount) in data.into_iter() {
-			let balance = balances
-				.entry(user.clone())
-				.or_insert_with(|| <Balance<T>>::get((collection.id, user)));
-			*balance = (*balance)
-				.checked_add(amount)
+		let mut balances = data;
+		for (k, v) in balances.iter_mut() {
+			*v = <Balance<T>>::get((collection.id, &k))
+				.checked_add(*v)
 				.ok_or(ArithmeticError::Overflow)?;
 		}
 
@@ -396,6 +392,6 @@
 		sender: &T::CrossAccountId,
 		data: CreateItemData<T>,
 	) -> DispatchResult {
-		Self::create_multiple_items(collection, sender, vec![data])
+		Self::create_multiple_items(collection, sender, [(data.0, data.1)].into_iter().collect())
 	}
 }
modifiedpallets/fungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/fungible/src/weights.rs
+++ b/pallets/fungible/src/weights.rs
@@ -33,6 +33,7 @@
 /// Weight functions needed for pallet_fungible.
 pub trait WeightInfo {
 	fn create_item() -> Weight;
+	fn create_multiple_items_ex(b: u32, ) -> Weight;
 	fn burn_item() -> Weight;
 	fn transfer() -> Weight;
 	fn approve() -> Weight;
@@ -51,6 +52,17 @@
 			.saturating_add(T::DbWeight::get().writes(2 as Weight))
 	}
 	// Storage: Fungible TotalSupply (r:1 w:1)
+	// Storage: Fungible Balance (r:4 w:4)
+	fn create_multiple_items_ex(b: u32, ) -> Weight {
+		(1_055_000 as Weight)
+			// Standard Error: 22_000
+			.saturating_add((5_273_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	// Storage: Fungible TotalSupply (r:1 w:1)
 	// Storage: Fungible Balance (r:1 w:1)
 	fn burn_item() -> Weight {
 		(14_096_000 as Weight)
@@ -97,6 +109,17 @@
 			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
 	}
 	// Storage: Fungible TotalSupply (r:1 w:1)
+	// Storage: Fungible Balance (r:4 w:4)
+	fn create_multiple_items_ex(b: u32, ) -> Weight {
+		(1_055_000 as Weight)
+			// Standard Error: 22_000
+			.saturating_add((5_273_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	// Storage: Fungible TotalSupply (r:1 w:1)
 	// Storage: Fungible Balance (r:1 w:1)
 	fn burn_item() -> Weight {
 		(14_096_000 as Weight)
modifiedpallets/inflation/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/inflation/src/benchmarking.rs
+++ b/pallets/inflation/src/benchmarking.rs
@@ -1,7 +1,7 @@
 #![cfg(feature = "runtime-benchmarks")]
 
 use super::*;
-use crate::Module as Inflation;
+use crate::Pallet as Inflation;
 
 use frame_benchmarking::{benchmarks};
 use frame_support::traits::OnInitialize;
modifiedpallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -2,18 +2,18 @@
 use crate::{Pallet, Config, NonfungibleHandle};
 
 use sp_std::prelude::*;
-use pallet_common::benchmarking::{create_collection_raw, create_data};
+use pallet_common::benchmarking::{create_collection_raw, create_data, create_var_data};
 use frame_benchmarking::{benchmarks, account};
-use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH};
+use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, CUSTOM_DATA_LIMIT};
 use pallet_common::bench_init;
 use core::convert::TryInto;
 
 const SEED: u32 = 1;
 
 fn create_max_item_data<T: Config>(owner: T::CrossAccountId) -> CreateItemData<T> {
-	let const_data = create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap();
-	let variable_data = create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap();
-	CreateItemData {
+	let const_data = create_data::<CUSTOM_DATA_LIMIT>();
+	let variable_data = create_data::<CUSTOM_DATA_LIMIT>();
+	CreateItemData::<T> {
 		const_data,
 		variable_data,
 		owner,
@@ -24,7 +24,7 @@
 	sender: &T::CrossAccountId,
 	owner: T::CrossAccountId,
 ) -> Result<TokenId, DispatchError> {
-	<Pallet<T>>::create_item(&collection, sender, create_max_item_data(owner))?;
+	<Pallet<T>>::create_item(&collection, sender, create_max_item_data::<T>(owner))?;
 	Ok(TokenId(<TokensMinted<T>>::get(&collection.id)))
 }
 
@@ -53,7 +53,19 @@
 			owner: sub; collection: collection(owner);
 			sender: cross_from_sub(owner); to: cross_sub;
 		};
-		let data = (0..b).map(|_| create_max_item_data(to.clone())).collect();
+		let data = (0..b).map(|_| create_max_item_data::<T>(to.clone())).collect();
+	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data)?}
+
+	create_multiple_items_ex {
+		let b in 0..MAX_ITEMS_PER_BATCH;
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			sender: cross_from_sub(owner);
+		};
+		let data = (0..b).map(|i| {
+			bench_init!(to: cross_sub(i););
+			create_max_item_data::<T>(to)
+		}).collect();
 	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data)?}
 
 	burn_item {
@@ -105,6 +117,6 @@
 			owner: cross_from_sub; sender: cross_sub;
 		};
 		let item = create_max_item(&collection, &owner, sender.clone())?;
-		let data = create_data(b as usize);
+		let data = create_var_data(b).try_into().unwrap();
 	}: {<Pallet<T>>::set_variable_metadata(&collection, &sender, item, data)?}
 }
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -1,7 +1,7 @@
 use core::marker::PhantomData;
 
 use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};
-use up_data_structs::{TokenId, CustomDataLimit};
+use up_data_structs::{TokenId, CustomDataLimit, CreateItemExData};
 use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
 use sp_runtime::DispatchError;
 use sp_std::vec::Vec;
@@ -12,11 +12,18 @@
 };
 
 pub struct CommonWeights<T: Config>(PhantomData<T>);
-impl<T: Config> CommonWeightInfo for CommonWeights<T> {
+impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
 	fn create_item() -> Weight {
 		<SelfWeightOf<T>>::create_item()
 	}
 
+	fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
+		match data {
+			CreateItemExData::NFT(t) => <SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32),
+			_ => 0,
+		}
+	}
+
 	fn create_multiple_items(amount: u32) -> Weight {
 		<SelfWeightOf<T>>::create_multiple_items(amount)
 	}
@@ -51,7 +58,7 @@
 	to: &T::CrossAccountId,
 ) -> Result<CreateItemData<T>, DispatchError> {
 	match data {
-		up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData {
+		up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData::<T> {
 			const_data: data.const_data,
 			variable_data: data.variable_data,
 			owner: to.clone(),
@@ -68,7 +75,7 @@
 		data: up_data_structs::CreateItemData,
 	) -> DispatchResultWithPostInfo {
 		with_weight(
-			<Pallet<T>>::create_item(self, &sender, map_create_data(data, &to)?),
+			<Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),
 			<CommonWeights<T>>::create_item(),
 		)
 	}
@@ -91,6 +98,23 @@
 		)
 	}
 
+	fn create_multiple_items_ex(
+		&self,
+		sender: <T>::CrossAccountId,
+		data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,
+	) -> DispatchResultWithPostInfo {
+		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);
+		let data = match data {
+			up_data_structs::CreateItemExData::NFT(nft) => nft,
+			_ => fail!(Error::<T>::NotNonfungibleDataUsedToMintFungibleCollectionToken),
+		};
+
+		with_weight(
+			<Pallet<T>>::create_multiple_items(self, &sender, data.into_inner()),
+			weight,
+		)
+	}
+
 	fn burn_item(
 		&self,
 		sender: T::CrossAccountId,
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -232,7 +232,7 @@
 		<Pallet<T>>::create_item(
 			self,
 			&caller,
-			CreateItemData {
+			CreateItemData::<T> {
 				const_data: BoundedVec::default(),
 				variable_data: BoundedVec::default(),
 				owner: to,
@@ -268,7 +268,7 @@
 		<Pallet<T>>::create_item(
 			self,
 			&caller,
-			CreateItemData {
+			CreateItemData::<T> {
 				const_data: Vec::<u8>::from(token_uri)
 					.try_into()
 					.map_err(|_| "token uri is too long")?,
@@ -376,7 +376,7 @@
 			expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;
 		}
 		let data = (0..total_tokens)
-			.map(|_| CreateItemData {
+			.map(|_| CreateItemData::<T> {
 				const_data: BoundedVec::default(),
 				variable_data: BoundedVec::default(),
 				owner: to.clone(),
@@ -409,7 +409,7 @@
 			}
 			expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;
 
-			data.push(CreateItemData {
+			data.push(CreateItemData::<T> {
 				const_data: Vec::<u8>::from(token_uri)
 					.try_into()
 					.map_err(|_| "token uri is too long")?,
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -2,7 +2,9 @@
 
 use erc::ERC721Events;
 use frame_support::{BoundedVec, ensure};
-use up_data_structs::{AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData};
+use up_data_structs::{
+	AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,
+};
 use pallet_common::{
 	Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, account::CrossAccountId,
 };
@@ -22,11 +24,7 @@
 pub mod erc;
 pub mod weights;
 
-pub struct CreateItemData<T: Config> {
-	pub const_data: BoundedVec<u8, CustomDataLimit>,
-	pub variable_data: BoundedVec<u8, CustomDataLimit>,
-	pub owner: T::CrossAccountId,
-}
+pub type CreateItemData<T> = CreateNftExData<<T as pallet_common::Config>::CrossAccountId>;
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
 #[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
modifiedpallets/nonfungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -34,6 +34,7 @@
 pub trait WeightInfo {
 	fn create_item() -> Weight;
 	fn create_multiple_items(b: u32, ) -> Weight;
+	fn create_multiple_items_ex(b: u32, ) -> Weight;
 	fn burn_item() -> Weight;
 	fn transfer() -> Weight;
 	fn approve() -> Weight;
@@ -66,6 +67,19 @@
 			.saturating_add(T::DbWeight::get().writes(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))
 	}
+	// Storage: Nonfungible TokensMinted (r:1 w:1)
+	// Storage: Nonfungible AccountBalance (r:4 w:4)
+	// Storage: Nonfungible TokenData (r:0 w:4)
+	// Storage: Nonfungible Owned (r:0 w:4)
+	fn create_multiple_items_ex(b: u32, ) -> Weight {
+		(2_090_000 as Weight)
+			// Standard Error: 10_000
+			.saturating_add((9_230_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))
+	}
 	// Storage: Nonfungible TokenData (r:1 w:1)
 	// Storage: Nonfungible TokensBurnt (r:1 w:1)
 	// Storage: Nonfungible Allowance (r:1 w:0)
@@ -140,6 +154,19 @@
 			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))
 	}
+	// Storage: Nonfungible TokensMinted (r:1 w:1)
+	// Storage: Nonfungible AccountBalance (r:4 w:4)
+	// Storage: Nonfungible TokenData (r:0 w:4)
+	// Storage: Nonfungible Owned (r:0 w:4)
+	fn create_multiple_items_ex(b: u32, ) -> Weight {
+		(2_090_000 as Weight)
+			// Standard Error: 10_000
+			.saturating_add((9_230_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))
+	}
 	// Storage: Nonfungible TokenData (r:1 w:1)
 	// Storage: Nonfungible TokensBurnt (r:1 w:1)
 	// Storage: Nonfungible Allowance (r:1 w:0)
modifiedpallets/refungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -2,24 +2,28 @@
 use crate::{Pallet, Config, RefungibleHandle};
 
 use sp_std::prelude::*;
-use pallet_common::benchmarking::{create_collection_raw, create_data};
+use pallet_common::benchmarking::{create_collection_raw, create_data, create_var_data};
 use frame_benchmarking::{benchmarks, account};
-use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH};
+use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, CUSTOM_DATA_LIMIT};
 use pallet_common::bench_init;
 use core::convert::TryInto;
 use core::iter::IntoIterator;
 
 const SEED: u32 = 1;
 
-fn create_max_item_data<T: Config>(
-	users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,
-) -> CreateItemData<T> {
-	let const_data = create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap();
-	let variable_data = create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap();
-	CreateItemData {
+fn create_max_item_data<CrossAccountId: Ord>(
+	users: impl IntoIterator<Item = (CrossAccountId, u128)>,
+) -> CreateRefungibleExData<CrossAccountId> {
+	let const_data = create_data::<CUSTOM_DATA_LIMIT>();
+	let variable_data = create_data::<CUSTOM_DATA_LIMIT>();
+	CreateRefungibleExData {
 		const_data,
 		variable_data,
-		users: users.into_iter().collect(),
+		users: users
+			.into_iter()
+			.collect::<BTreeMap<_, _>>()
+			.try_into()
+			.unwrap(),
 	}
 }
 fn create_max_item<T: Config>(
@@ -27,7 +31,8 @@
 	sender: &T::CrossAccountId,
 	users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,
 ) -> Result<TokenId, DispatchError> {
-	<Pallet<T>>::create_item(&collection, sender, create_max_item_data(users))?;
+	let data: CreateRefungibleExData<T::CrossAccountId> = create_max_item_data(users);
+	<Pallet<T>>::create_item(&collection, sender, data)?;
 	Ok(TokenId(<TokensMinted<T>>::get(&collection.id)))
 }
 
@@ -56,6 +61,30 @@
 		let data = (0..b).map(|_| create_max_item_data([(to.clone(), 200)])).collect();
 	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data)?}
 
+	create_multiple_items_ex_multiple_items {
+		let b in 0..MAX_ITEMS_PER_BATCH;
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			sender: cross_from_sub(owner);
+		};
+		let data = (0..b).map(|t| {
+			bench_init!(to: cross_sub(t););
+			create_max_item_data([(to, 200)])
+		}).collect();
+	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data)?}
+
+	create_multiple_items_ex_multiple_owners {
+		let b in 0..MAX_ITEMS_PER_BATCH;
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			sender: cross_from_sub(owner);
+		};
+		let data = vec![create_max_item_data((0..b).map(|u| {
+			bench_init!(to: cross_sub(u););
+			(to, 200)
+		}))].try_into().unwrap();
+	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data)?}
+
 	// Other user left, token data is kept
 	burn_item_partial {
 		bench_init!{
@@ -166,6 +195,6 @@
 			sender: cross_from_sub(owner);
 		};
 		let item = create_max_item(&collection, &sender, [(sender.clone(), 200)])?;
-		let data = create_data(b as usize);
+		let data = create_var_data(b).try_into().unwrap();
 	}: {<Pallet<T>>::set_variable_metadata(&collection, &sender, item, data)?}
 }
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -2,14 +2,14 @@
 
 use sp_std::collections::btree_map::BTreeMap;
 use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};
-use up_data_structs::{TokenId, CustomDataLimit};
+use up_data_structs::{TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData};
 use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
 use sp_runtime::DispatchError;
-use sp_std::vec::Vec;
+use sp_std::{vec::Vec, vec};
 
 use crate::{
-	AccountBalance, Allowance, Balance, Config, CreateItemData, Error, Owned, Pallet,
-	RefungibleHandle, SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,
+	AccountBalance, Allowance, Balance, Config, Error, Owned, Pallet, RefungibleHandle,
+	SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,
 };
 
 macro_rules! max_weight_of {
@@ -22,7 +22,7 @@
 }
 
 pub struct CommonWeights<T: Config>(PhantomData<T>);
-impl<T: Config> CommonWeightInfo for CommonWeights<T> {
+impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
 	fn create_item() -> Weight {
 		<SelfWeightOf<T>>::create_item()
 	}
@@ -31,6 +31,18 @@
 		<SelfWeightOf<T>>::create_multiple_items(amount)
 	}
 
+	fn create_multiple_items_ex(call: &CreateItemExData<T::CrossAccountId>) -> Weight {
+		match call {
+			CreateItemExData::RefungibleMultipleOwners(i) => {
+				<SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32)
+			}
+			CreateItemExData::RefungibleMultipleItems(i) => {
+				<SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32)
+			}
+			_ => 0,
+		}
+	}
+
 	fn burn_item() -> Weight {
 		max_weight_of!(burn_item_partial(), burn_item_fully())
 	}
@@ -69,15 +81,15 @@
 fn map_create_data<T: Config>(
 	data: up_data_structs::CreateItemData,
 	to: &T::CrossAccountId,
-) -> Result<CreateItemData<T>, DispatchError> {
+) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {
 	match data {
-		up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateItemData {
+		up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {
 			const_data: data.const_data,
 			variable_data: data.variable_data,
 			users: {
 				let mut out = BTreeMap::new();
 				out.insert(to.clone(), data.pieces);
-				out
+				out.try_into().expect("limit > 0")
 			},
 		}),
 		_ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),
@@ -92,7 +104,7 @@
 		data: up_data_structs::CreateItemData,
 	) -> DispatchResultWithPostInfo {
 		with_weight(
-			<Pallet<T>>::create_item(self, &sender, map_create_data(data, &to)?),
+			<Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),
 			<CommonWeights<T>>::create_item(),
 		)
 	}
@@ -115,6 +127,28 @@
 		)
 	}
 
+	fn create_multiple_items_ex(
+		&self,
+		sender: <T>::CrossAccountId,
+		data: CreateItemExData<T::CrossAccountId>,
+	) -> DispatchResultWithPostInfo {
+		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);
+		let data = match data {
+			CreateItemExData::RefungibleMultipleOwners(r) => vec![r],
+			CreateItemExData::RefungibleMultipleItems(r)
+				if r.iter().all(|i| i.users.len() == 1) =>
+			{
+				r.into_inner()
+			}
+			_ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),
+		};
+
+		with_weight(
+			<Pallet<T>>::create_multiple_items(self, &sender, data),
+			weight,
+		)
+	}
+
 	fn burn_item(
 		&self,
 		sender: T::CrossAccountId,
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -2,7 +2,8 @@
 
 use frame_support::{ensure, BoundedVec};
 use up_data_structs::{
-	AccessMode, CollectionId, CustomDataLimit, MAX_REFUNGIBLE_PIECES, TokenId, CreateCollectionData,
+	AccessMode, CollectionId, CustomDataLimit, MAX_REFUNGIBLE_PIECES, TokenId,
+	CreateCollectionData, CreateRefungibleExData,
 };
 use pallet_common::{
 	Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,
@@ -19,11 +20,6 @@
 pub mod common;
 pub mod erc;
 pub mod weights;
-pub struct CreateItemData<T: Config> {
-	pub const_data: BoundedVec<u8, CustomDataLimit>,
-	pub variable_data: BoundedVec<u8, CustomDataLimit>,
-	pub users: BTreeMap<T::CrossAccountId, u128>,
-}
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
 #[derive(Encode, Decode, Default, TypeInfo, MaxEncodedLen)]
@@ -361,7 +357,7 @@
 	pub fn create_multiple_items(
 		collection: &RefungibleHandle<T>,
 		sender: &T::CrossAccountId,
-		data: Vec<CreateItemData<T>>,
+		data: Vec<CreateRefungibleExData<T::CrossAccountId>>,
 	) -> DispatchResult {
 		if !collection.is_owner_or_admin(sender) {
 			ensure!(
@@ -606,7 +602,7 @@
 	pub fn create_item(
 		collection: &RefungibleHandle<T>,
 		sender: &T::CrossAccountId,
-		data: CreateItemData<T>,
+		data: CreateRefungibleExData<T::CrossAccountId>,
 	) -> DispatchResult {
 		Self::create_multiple_items(collection, sender, vec![data])
 	}
modifiedpallets/refungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/refungible/src/weights.rs
+++ b/pallets/refungible/src/weights.rs
@@ -34,6 +34,8 @@
 pub trait WeightInfo {
 	fn create_item() -> Weight;
 	fn create_multiple_items(b: u32, ) -> Weight;
+	fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight;
+	fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight;
 	fn burn_item_partial() -> Weight;
 	fn burn_item_fully() -> Weight;
 	fn transfer_normal() -> Weight;
@@ -77,6 +79,36 @@
 			.saturating_add(T::DbWeight::get().writes(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
 	}
+	// Storage: Refungible TokensMinted (r:1 w:1)
+	// Storage: Refungible AccountBalance (r:4 w:4)
+	// Storage: Refungible Balance (r:0 w:4)
+	// Storage: Refungible TotalSupply (r:0 w:4)
+	// Storage: Refungible TokenData (r:0 w:4)
+	// Storage: Refungible Owned (r:0 w:4)
+	fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {
+		(11_953_000 as Weight)
+			// Standard Error: 27_000
+			.saturating_add((10_775_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(b as Weight)))
+	}
+	// Storage: Refungible TokensMinted (r:1 w:1)
+	// Storage: Refungible TotalSupply (r:0 w:1)
+	// Storage: Refungible TokenData (r:0 w:1)
+	// Storage: Refungible AccountBalance (r:4 w:4)
+	// Storage: Refungible Balance (r:0 w:4)
+	// Storage: Refungible Owned (r:0 w:4)
+	fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {
+		(0 as Weight)
+			// Standard Error: 13_000
+			.saturating_add((8_528_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(T::DbWeight::get().writes(3 as Weight))
+			.saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))
+	}
 	// Storage: Refungible TotalSupply (r:1 w:1)
 	// Storage: Refungible Balance (r:1 w:1)
 	// Storage: Refungible AccountBalance (r:1 w:1)
@@ -215,6 +247,36 @@
 			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
 	}
+	// Storage: Refungible TokensMinted (r:1 w:1)
+	// Storage: Refungible AccountBalance (r:4 w:4)
+	// Storage: Refungible Balance (r:0 w:4)
+	// Storage: Refungible TotalSupply (r:0 w:4)
+	// Storage: Refungible TokenData (r:0 w:4)
+	// Storage: Refungible Owned (r:0 w:4)
+	fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {
+		(11_953_000 as Weight)
+			// Standard Error: 27_000
+			.saturating_add((10_775_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((5 as Weight).saturating_mul(b as Weight)))
+	}
+	// Storage: Refungible TokensMinted (r:1 w:1)
+	// Storage: Refungible TotalSupply (r:0 w:1)
+	// Storage: Refungible TokenData (r:0 w:1)
+	// Storage: Refungible AccountBalance (r:4 w:4)
+	// Storage: Refungible Balance (r:0 w:4)
+	// Storage: Refungible Owned (r:0 w:4)
+	fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {
+		(0 as Weight)
+			// Standard Error: 13_000
+			.saturating_add((8_528_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(RocksDbWeight::get().writes(3 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))
+	}
 	// Storage: Refungible TotalSupply (r:1 w:1)
 	// Storage: Refungible Balance (r:1 w:1)
 	// Storage: Refungible AccountBalance (r:1 w:1)
modifiedpallets/unique/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/unique/src/benchmarking.rs
+++ b/pallets/unique/src/benchmarking.rs
@@ -5,9 +5,8 @@
 use frame_system::RawOrigin;
 use frame_benchmarking::{benchmarks, account};
 use up_data_structs::*;
-use core::convert::TryInto;
 use sp_runtime::DispatchError;
-use pallet_common::benchmarking::{create_data, create_u16_data};
+use pallet_common::benchmarking::{create_data, create_var_data, create_u16_data};
 
 const SEED: u32 = 1;
 
@@ -16,13 +15,9 @@
 	mode: CollectionMode,
 ) -> Result<CollectionId, DispatchError> {
 	T::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());
-	let col_name = create_u16_data(MAX_COLLECTION_NAME_LENGTH)
-		.try_into()
-		.unwrap();
-	let col_desc = create_u16_data(MAX_COLLECTION_DESCRIPTION_LENGTH)
-		.try_into()
-		.unwrap();
-	let token_prefix = create_data(MAX_TOKEN_PREFIX_LENGTH).try_into().unwrap();
+	let col_name = create_u16_data::<MAX_COLLECTION_NAME_LENGTH>();
+	let col_desc = create_u16_data::<MAX_COLLECTION_DESCRIPTION_LENGTH>();
+	let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
 	<Pallet<T>>::create_collection(
 		RawOrigin::Signed(owner).into(),
 		col_name,
@@ -37,11 +32,10 @@
 }
 
 benchmarks! {
-
 	create_collection {
-		let col_name: Vec<u16> = create_u16_data(MAX_COLLECTION_NAME_LENGTH);
-		let col_desc: Vec<u16> = create_u16_data(MAX_COLLECTION_DESCRIPTION_LENGTH);
-		let token_prefix: Vec<u8> = create_data(MAX_TOKEN_PREFIX_LENGTH);
+		let col_name = create_u16_data::<MAX_COLLECTION_NAME_LENGTH>();
+		let col_desc = create_u16_data::<MAX_COLLECTION_DESCRIPTION_LENGTH>();
+		let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
 		let mode: CollectionMode = CollectionMode::NFT;
 		let caller: T::AccountId = account("caller", 0, SEED);
 		T::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
@@ -125,7 +119,7 @@
 
 		let caller: T::AccountId = account("caller", 0, SEED);
 		let collection = create_nft_collection::<T>(caller.clone())?;
-		let data = create_data(b as usize);
+		let data = create_var_data(b);
 	}: set_offchain_schema(RawOrigin::Signed(caller.clone()), collection, data)
 
 	set_const_on_chain_schema {
@@ -133,7 +127,7 @@
 
 		let caller: T::AccountId = account("caller", 0, SEED);
 		let collection = create_nft_collection::<T>(caller.clone())?;
-		let data = create_data(b as usize);
+		let data = create_var_data(b);
 	}: set_const_on_chain_schema(RawOrigin::Signed(caller.clone()), collection, data)
 
 	set_variable_on_chain_schema {
@@ -141,7 +135,7 @@
 
 		let caller: T::AccountId = account("caller", 0, SEED);
 		let collection = create_nft_collection::<T>(caller.clone())?;
-		let data = create_data(b as usize);
+		let data = create_var_data(b);
 	}: set_variable_on_chain_schema(RawOrigin::Signed(caller.clone()), collection, data)
 
 	set_schema_version {
modifiedpallets/unique/src/common.rsdiffbeforeafterboth
--- a/pallets/unique/src/common.rs
+++ b/pallets/unique/src/common.rs
@@ -5,6 +5,7 @@
 use pallet_fungible::{common::CommonWeights as FungibleWeights};
 use pallet_nonfungible::{common::CommonWeights as NonfungibleWeights};
 use pallet_refungible::{common::CommonWeights as RefungibleWeights};
+use up_data_structs::CreateItemExData;
 
 use crate::{Config, dispatch::dispatch_weight};
 
@@ -17,7 +18,7 @@
 }
 
 pub struct CommonWeights<T: Config>(PhantomData<T>);
-impl<T: Config> CommonWeightInfo for CommonWeights<T> {
+impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
 	fn create_item() -> up_data_structs::Weight {
 		dispatch_weight::<T>() + max_weight_of!(create_item())
 	}
@@ -26,6 +27,10 @@
 		dispatch_weight::<T>() + max_weight_of!(create_multiple_items(amount))
 	}
 
+	fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
+		dispatch_weight::<T>() + max_weight_of!(create_multiple_items_ex(data))
+	}
+
 	fn burn_item() -> Weight {
 		dispatch_weight::<T>() + max_weight_of!(burn_item())
 	}
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -40,7 +40,7 @@
 	OFFCHAIN_SCHEMA_LIMIT, MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH,
 	MAX_TOKEN_PREFIX_LENGTH, AccessMode, CreateItemData, CollectionLimits, CollectionId,
 	CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,
-	CreateCollectionData, CustomDataLimit,
+	CreateCollectionData, CustomDataLimit, CreateItemExData,
 };
 use pallet_common::{
 	account::CrossAccountId, CollectionHandle, Pallet as PalletCommon, Error as CommonError,
@@ -735,6 +735,14 @@
 			dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data))
 		}
 
+		#[weight = <CommonWeights<T>>::create_multiple_items_ex(&data)]
+		#[transactional]
+		pub fn create_multiple_items_ex(origin, collection_id: CollectionId, data: CreateItemExData<T::CrossAccountId>) -> DispatchResultWithPostInfo {
+			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
+
+			dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data))
+		}
+
 		// TODO! transaction weight
 
 		/// Set transfers_enabled value for particular collection
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -1,6 +1,11 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use core::convert::{TryFrom, TryInto};
+use core::{
+	convert::{TryFrom, TryInto},
+	fmt,
+};
+use frame_support::storage::bounded_btree_map::BoundedBTreeMap;
+use sp_std::collections::btree_map::BTreeMap;
 
 #[cfg(feature = "serde")]
 pub use serde::{Serialize, Deserialize};
@@ -76,9 +81,7 @@
 /// create_many call
 pub const MAX_ITEMS_PER_BATCH: u32 = 200;
 
-parameter_types! {
-	pub const CustomDataLimit: u32 = CUSTOM_DATA_LIMIT;
-}
+pub type CustomDataLimit = ConstU32<CUSTOM_DATA_LIMIT>;
 
 #[derive(
 	Encode,
@@ -417,15 +420,72 @@
 	}
 }
 
+fn bounded_debug<V, S>(v: &BoundedVec<V, S>, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
+where
+	V: fmt::Debug,
+{
+	use core::fmt::Debug;
+	(&v as &Vec<V>).fmt(f)
+}
+
+#[cfg(feature = "serde1")]
+#[allow(dead_code)]
+mod bounded_map_serde {
+	use core::convert::TryFrom;
+	use sp_std::collections::btree_map::BTreeMap;
+	use frame_support::{traits::Get, storage::bounded_btree_map::BoundedBTreeMap};
+	use serde::{
+		ser::{self, Serialize},
+		de::{self, Deserialize, Error},
+	};
+	pub fn serialize<D, K, V, S>(
+		value: &BoundedBTreeMap<K, V, S>,
+		serializer: D,
+	) -> Result<D::Ok, D::Error>
+	where
+		D: ser::Serializer,
+		K: Serialize + Ord,
+		V: Serialize,
+	{
+		(value as &BTreeMap<_, _>).serialize(serializer)
+	}
+
+	pub fn deserialize<'de, D, K, V, S>(
+		deserializer: D,
+	) -> Result<BoundedBTreeMap<K, V, S>, D::Error>
+	where
+		D: de::Deserializer<'de>,
+		K: de::Deserialize<'de> + Ord,
+		V: de::Deserialize<'de>,
+		S: Get<u32>,
+	{
+		let map = <BTreeMap<K, V>>::deserialize(deserializer)?;
+		let len = map.len();
+		TryFrom::try_from(map).map_err(|_| D::Error::invalid_length(len, &"lesser size"))
+	}
+}
+
+fn bounded_map_debug<K, V, S>(
+	v: &BoundedBTreeMap<K, V, S>,
+	f: &mut fmt::Formatter,
+) -> Result<(), fmt::Error>
+where
+	K: fmt::Debug + Ord,
+	V: fmt::Debug,
+{
+	use core::fmt::Debug;
+	(&v as &BTreeMap<K, V>).fmt(f)
+}
+
 #[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
 pub struct CreateNftData {
 	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
-	#[derivative(Debug = "ignore")]
+	#[derivative(Debug(format_with = "bounded_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
 	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
-	#[derivative(Debug = "ignore")]
+	#[derivative(Debug(format_with = "bounded_debug"))]
 	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 }
 
@@ -440,10 +500,10 @@
 #[derivative(Debug)]
 pub struct CreateReFungibleData {
 	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
-	#[derivative(Debug = "ignore")]
+	#[derivative(Debug(format_with = "bounded_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
 	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
-	#[derivative(Debug = "ignore")]
+	#[derivative(Debug(format_with = "bounded_debug"))]
 	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 	pub pieces: u128,
 }
@@ -470,6 +530,47 @@
 	ReFungible(CreateReFungibleData),
 }
 
+#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
+#[derivative(Debug)]
+pub struct CreateNftExData<CrossAccountId> {
+	#[derivative(Debug(format_with = "bounded_debug"))]
+	pub const_data: BoundedVec<u8, CustomDataLimit>,
+	#[derivative(Debug(format_with = "bounded_debug"))]
+	pub variable_data: BoundedVec<u8, CustomDataLimit>,
+	pub owner: CrossAccountId,
+}
+
+#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
+#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
+pub struct CreateRefungibleExData<CrossAccountId> {
+	#[derivative(Debug(format_with = "bounded_debug"))]
+	pub const_data: BoundedVec<u8, CustomDataLimit>,
+	#[derivative(Debug(format_with = "bounded_debug"))]
+	pub variable_data: BoundedVec<u8, CustomDataLimit>,
+	#[derivative(Debug(format_with = "bounded_map_debug"))]
+	pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
+}
+
+#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
+#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
+pub enum CreateItemExData<CrossAccountId> {
+	NFT(
+		#[derivative(Debug(format_with = "bounded_debug"))]
+		BoundedVec<CreateNftExData<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,
+	),
+	Fungible(
+		#[derivative(Debug(format_with = "bounded_map_debug"))]
+		BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
+	),
+	/// Many tokens, each may have only one owner
+	RefungibleMultipleItems(
+		#[derivative(Debug(format_with = "bounded_debug"))]
+		BoundedVec<CreateRefungibleExData<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,
+	),
+	/// Single token, which may have many owners
+	RefungibleMultipleOwners(CreateRefungibleExData<CrossAccountId>),
+}
+
 impl CreateItemData {
 	pub fn data_size(&self) -> usize {
 		match self {
addedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -0,0 +1,58 @@
+import {expect} from 'chai';
+import privateKey from './substrate/privateKey';
+import usingApi, {executeTransaction} from './substrate/substrate-api';
+import {createCollectionExpectSuccess} from './util/helpers';
+
+describe('createMultipleItemsEx', () => {
+  it('can initialize multiple NFT with different owners', async () => {
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const alice = privateKey('//Alice');
+    const bob = privateKey('//Bob');
+    const charlie = privateKey('//Charlie');
+    await usingApi(async (api) => {
+      const data = [
+        {
+          owner: {substrate: alice.address},
+          constData: '0x0000',
+          variableData: '0x1111',
+        }, {
+          owner: {substrate: bob.address},
+          constData: '0x2222',
+          variableData: '0x3333',
+        }, {
+          owner: {substrate: charlie.address},
+          constData: '0x4444',
+          variableData: '0x5555',
+        },
+      ];
+
+      await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
+        NFT: data,
+      }));
+      const tokens = await api.query.nonfungible.tokenData.entries(collection);
+      const json = tokens.map(([, token]) => token.toJSON());
+      expect(json).to.be.deep.equal(data);
+    });
+  });
+
+  it('fails when trying to set multiple owners when creating multiple refungibles', async () => {
+    const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+    const alice = privateKey('//Alice');
+    const bob = privateKey('//Bob');
+
+    await usingApi(async (api) => {
+      // Polkadot requires map, and yet requires keys to be JSON encoded
+      const users = new Map();
+      users.set(JSON.stringify({substrate: alice.address}), 1);
+      users.set(JSON.stringify({substrate: bob.address}), 1);
+
+      // TODO: better error message?
+      await expect(executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
+        RefungibleMultipleItems: [
+          {users},
+          {users},
+        ],
+      }))).to.be.rejectedWith(/^refungible\.NotRefungibleDataUsedToMintFungibleCollectionToken$/);
+    });
+  });
+});
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -5,7 +5,7 @@
 import type { Bytes, Compact, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types-codec';
 import type { AnyNumber, ITuple } from '@polkadot/types-codec/types';
 import type { AccountId32, Call, H160, H256, MultiAddress, Perbill } from '@polkadot/types/interfaces/runtime';
-import type { CumulusPrimitivesParachainInherentParachainInherentData, EthereumTransactionTransactionV2, OrmlVestingVestingSchedule, PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
+import type { CumulusPrimitivesParachainInherentParachainInherentData, EthereumTransactionTransactionV2, OrmlVestingVestingSchedule, PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
 
 declare module '@polkadot/api-base/types/submittable' {
   export interface AugmentedSubmittables<ApiType extends ApiTypes> {
@@ -710,6 +710,7 @@
        * * owner: Address, initial owner of the NFT.
        **/
       createMultipleItems: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, owner: PalletCommonAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, itemsData: Vec<UpDataStructsCreateItemData> | (UpDataStructsCreateItemData | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, PalletCommonAccountBasicCrossAccountIdRepr, Vec<UpDataStructsCreateItemData>]>;
+      createMultipleItemsEx: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, data: UpDataStructsCreateItemExData | { NFT: any } | { Fungible: any } | { RefungibleMultipleItems: any } | { RefungibleMultipleOwners: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsCreateItemExData]>;
       /**
        * **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.
        * 
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, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonAccountBasicCrossAccountIdRepr, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV1AbridgedHostConfiguration, PolkadotPrimitivesV1AbridgedHrmpChannel, PolkadotPrimitivesV1PersistedValidationData, PolkadotPrimitivesV1UpgradeRestriction, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpTrieStorageProof, SpVersionRuntimeVersion, UniqueRuntimeRuntime, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateNftData, UpDataStructsCreateReFungibleData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, 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 './unique';
+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, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonAccountBasicCrossAccountIdRepr, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV1AbridgedHostConfiguration, PolkadotPrimitivesV1AbridgedHrmpChannel, PolkadotPrimitivesV1PersistedValidationData, PolkadotPrimitivesV1UpgradeRestriction, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpTrieStorageProof, SpVersionRuntimeVersion, UniqueRuntimeRuntime, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, 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 './unique';
 import type { Data, StorageKey } from '@polkadot/types';
 import type { BitVec, Bool, Bytes, I128, I16, I256, I32, I64, I8, Json, Null, 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';
@@ -1159,8 +1159,11 @@
     UpDataStructsCreateCollectionData: UpDataStructsCreateCollectionData;
     UpDataStructsCreateFungibleData: UpDataStructsCreateFungibleData;
     UpDataStructsCreateItemData: UpDataStructsCreateItemData;
+    UpDataStructsCreateItemExData: UpDataStructsCreateItemExData;
     UpDataStructsCreateNftData: UpDataStructsCreateNftData;
+    UpDataStructsCreateNftExData: UpDataStructsCreateNftExData;
     UpDataStructsCreateReFungibleData: UpDataStructsCreateReFungibleData;
+    UpDataStructsCreateRefungibleExData: UpDataStructsCreateRefungibleExData;
     UpDataStructsMetaUpdatePermission: UpDataStructsMetaUpdatePermission;
     UpDataStructsSchemaVersion: UpDataStructsSchemaVersion;
     UpDataStructsSponsoringRateLimit: UpDataStructsSponsoringRateLimit;
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1300,6 +1300,10 @@
         owner: 'PalletCommonAccountBasicCrossAccountIdRepr',
         itemsData: 'Vec<UpDataStructsCreateItemData>',
       },
+      create_multiple_items_ex: {
+        collectionId: 'u32',
+        data: 'UpDataStructsCreateItemExData',
+      },
       set_transfers_enabled_flag: {
         collectionId: 'u32',
         value: 'bool',
@@ -1474,11 +1478,38 @@
     pieces: 'u128'
   },
   /**
-   * Lookup181: pallet_template_transaction_payment::Call<T>
+   * Lookup180: up_data_structs::CreateItemExData<pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
+  UpDataStructsCreateItemExData: {
+    _enum: {
+      NFT: 'Vec<UpDataStructsCreateNftExData>',
+      Fungible: 'BTreeMap<PalletCommonAccountBasicCrossAccountIdRepr, u128>',
+      RefungibleMultipleItems: 'Vec<UpDataStructsCreateRefungibleExData>',
+      RefungibleMultipleOwners: 'UpDataStructsCreateRefungibleExData'
+    }
+  },
+  /**
+   * Lookup182: up_data_structs::CreateNftExData<pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   **/
+  UpDataStructsCreateNftExData: {
+    constData: 'Bytes',
+    variableData: 'Bytes',
+    owner: 'PalletCommonAccountBasicCrossAccountIdRepr'
+  },
+  /**
+   * Lookup189: up_data_structs::CreateRefungibleExData<pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   **/
+  UpDataStructsCreateRefungibleExData: {
+    constData: 'Bytes',
+    variableData: 'Bytes',
+    users: 'BTreeMap<PalletCommonAccountBasicCrossAccountIdRepr, u128>'
+  },
+  /**
+   * Lookup192: pallet_template_transaction_payment::Call<T>
+   **/
   PalletTemplateTransactionPaymentCall: 'Null',
   /**
-   * Lookup182: pallet_evm::pallet::Call<T>
+   * Lookup193: pallet_evm::pallet::Call<T>
    **/
   PalletEvmCall: {
     _enum: {
@@ -1521,7 +1552,7 @@
     }
   },
   /**
-   * Lookup188: pallet_ethereum::pallet::Call<T>
+   * Lookup199: pallet_ethereum::pallet::Call<T>
    **/
   PalletEthereumCall: {
     _enum: {
@@ -1531,7 +1562,7 @@
     }
   },
   /**
-   * Lookup189: ethereum::transaction::TransactionV2
+   * Lookup200: ethereum::transaction::TransactionV2
    **/
   EthereumTransactionTransactionV2: {
     _enum: {
@@ -1541,7 +1572,7 @@
     }
   },
   /**
-   * Lookup190: ethereum::transaction::LegacyTransaction
+   * Lookup201: ethereum::transaction::LegacyTransaction
    **/
   EthereumTransactionLegacyTransaction: {
     nonce: 'U256',
@@ -1553,7 +1584,7 @@
     signature: 'EthereumTransactionTransactionSignature'
   },
   /**
-   * Lookup191: ethereum::transaction::TransactionAction
+   * Lookup202: ethereum::transaction::TransactionAction
    **/
   EthereumTransactionTransactionAction: {
     _enum: {
@@ -1562,7 +1593,7 @@
     }
   },
   /**
-   * Lookup192: ethereum::transaction::TransactionSignature
+   * Lookup203: ethereum::transaction::TransactionSignature
    **/
   EthereumTransactionTransactionSignature: {
     v: 'u64',
@@ -1570,7 +1601,7 @@
     s: 'H256'
   },
   /**
-   * Lookup194: ethereum::transaction::EIP2930Transaction
+   * Lookup205: ethereum::transaction::EIP2930Transaction
    **/
   EthereumTransactionEip2930Transaction: {
     chainId: 'u64',
@@ -1586,14 +1617,14 @@
     s: 'H256'
   },
   /**
-   * Lookup196: ethereum::transaction::AccessListItem
+   * Lookup207: ethereum::transaction::AccessListItem
    **/
   EthereumTransactionAccessListItem: {
     address: 'H160',
     slots: 'Vec<H256>'
   },
   /**
-   * Lookup197: ethereum::transaction::EIP1559Transaction
+   * Lookup208: ethereum::transaction::EIP1559Transaction
    **/
   EthereumTransactionEip1559Transaction: {
     chainId: 'u64',
@@ -1610,7 +1641,7 @@
     s: 'H256'
   },
   /**
-   * Lookup198: pallet_evm_migration::pallet::Call<T>
+   * Lookup209: pallet_evm_migration::pallet::Call<T>
    **/
   PalletEvmMigrationCall: {
     _enum: {
@@ -1628,7 +1659,7 @@
     }
   },
   /**
-   * Lookup201: pallet_sudo::pallet::Event<T>
+   * Lookup212: pallet_sudo::pallet::Event<T>
    **/
   PalletSudoEvent: {
     _enum: {
@@ -1644,7 +1675,7 @@
     }
   },
   /**
-   * Lookup203: sp_runtime::DispatchError
+   * Lookup214: sp_runtime::DispatchError
    **/
   SpRuntimeDispatchError: {
     _enum: {
@@ -1660,32 +1691,32 @@
     }
   },
   /**
-   * Lookup204: sp_runtime::ModuleError
+   * Lookup215: sp_runtime::ModuleError
    **/
   SpRuntimeModuleError: {
     index: 'u8',
     error: 'u8'
   },
   /**
-   * Lookup205: sp_runtime::TokenError
+   * Lookup216: sp_runtime::TokenError
    **/
   SpRuntimeTokenError: {
     _enum: ['NoFunds', 'WouldDie', 'BelowMinimum', 'CannotCreate', 'UnknownAsset', 'Frozen', 'Unsupported']
   },
   /**
-   * Lookup206: sp_runtime::ArithmeticError
+   * Lookup217: sp_runtime::ArithmeticError
    **/
   SpRuntimeArithmeticError: {
     _enum: ['Underflow', 'Overflow', 'DivisionByZero']
   },
   /**
-   * Lookup207: pallet_sudo::pallet::Error<T>
+   * Lookup218: pallet_sudo::pallet::Error<T>
    **/
   PalletSudoError: {
     _enum: ['RequireSudo']
   },
   /**
-   * Lookup208: frame_system::AccountInfo<Index, pallet_balances::AccountData<Balance>>
+   * Lookup219: frame_system::AccountInfo<Index, pallet_balances::AccountData<Balance>>
    **/
   FrameSystemAccountInfo: {
     nonce: 'u32',
@@ -1695,7 +1726,7 @@
     data: 'PalletBalancesAccountData'
   },
   /**
-   * Lookup209: frame_support::weights::PerDispatchClass<T>
+   * Lookup220: frame_support::weights::PerDispatchClass<T>
    **/
   FrameSupportWeightsPerDispatchClassU64: {
     normal: 'u64',
@@ -1703,13 +1734,13 @@
     mandatory: 'u64'
   },
   /**
-   * Lookup210: sp_runtime::generic::digest::Digest
+   * Lookup221: sp_runtime::generic::digest::Digest
    **/
   SpRuntimeDigest: {
     logs: 'Vec<SpRuntimeDigestDigestItem>'
   },
   /**
-   * Lookup212: sp_runtime::generic::digest::DigestItem
+   * Lookup223: sp_runtime::generic::digest::DigestItem
    **/
   SpRuntimeDigestDigestItem: {
     _enum: {
@@ -1725,7 +1756,7 @@
     }
   },
   /**
-   * Lookup214: frame_system::EventRecord<unique_runtime::Event, primitive_types::H256>
+   * Lookup225: frame_system::EventRecord<unique_runtime::Event, primitive_types::H256>
    **/
   FrameSystemEventRecord: {
     phase: 'FrameSystemPhase',
@@ -1733,7 +1764,7 @@
     topics: 'Vec<H256>'
   },
   /**
-   * Lookup216: frame_system::pallet::Event<T>
+   * Lookup227: frame_system::pallet::Event<T>
    **/
   FrameSystemEvent: {
     _enum: {
@@ -1761,7 +1792,7 @@
     }
   },
   /**
-   * Lookup217: frame_support::weights::DispatchInfo
+   * Lookup228: frame_support::weights::DispatchInfo
    **/
   FrameSupportWeightsDispatchInfo: {
     weight: 'u64',
@@ -1769,19 +1800,19 @@
     paysFee: 'FrameSupportWeightsPays'
   },
   /**
-   * Lookup218: frame_support::weights::DispatchClass
+   * Lookup229: frame_support::weights::DispatchClass
    **/
   FrameSupportWeightsDispatchClass: {
     _enum: ['Normal', 'Operational', 'Mandatory']
   },
   /**
-   * Lookup219: frame_support::weights::Pays
+   * Lookup230: frame_support::weights::Pays
    **/
   FrameSupportWeightsPays: {
     _enum: ['Yes', 'No']
   },
   /**
-   * Lookup220: orml_vesting::module::Event<T>
+   * Lookup231: orml_vesting::module::Event<T>
    **/
   OrmlVestingModuleEvent: {
     _enum: {
@@ -1800,7 +1831,7 @@
     }
   },
   /**
-   * Lookup221: cumulus_pallet_xcmp_queue::pallet::Event<T>
+   * Lookup232: cumulus_pallet_xcmp_queue::pallet::Event<T>
    **/
   CumulusPalletXcmpQueueEvent: {
     _enum: {
@@ -1815,7 +1846,7 @@
     }
   },
   /**
-   * Lookup222: pallet_xcm::pallet::Event<T>
+   * Lookup233: pallet_xcm::pallet::Event<T>
    **/
   PalletXcmEvent: {
     _enum: {
@@ -1838,7 +1869,7 @@
     }
   },
   /**
-   * Lookup223: xcm::v2::traits::Outcome
+   * Lookup234: xcm::v2::traits::Outcome
    **/
   XcmV2TraitsOutcome: {
     _enum: {
@@ -1848,7 +1879,7 @@
     }
   },
   /**
-   * Lookup225: cumulus_pallet_xcm::pallet::Event<T>
+   * Lookup236: cumulus_pallet_xcm::pallet::Event<T>
    **/
   CumulusPalletXcmEvent: {
     _enum: {
@@ -1858,7 +1889,7 @@
     }
   },
   /**
-   * Lookup226: cumulus_pallet_dmp_queue::pallet::Event<T>
+   * Lookup237: cumulus_pallet_dmp_queue::pallet::Event<T>
    **/
   CumulusPalletDmpQueueEvent: {
     _enum: {
@@ -1871,7 +1902,7 @@
     }
   },
   /**
-   * Lookup227: pallet_unique::RawEvent<sp_core::crypto::AccountId32, pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup238: pallet_unique::RawEvent<sp_core::crypto::AccountId32, pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   PalletUniqueRawEvent: {
     _enum: {
@@ -1893,7 +1924,7 @@
     }
   },
   /**
-   * Lookup228: pallet_common::pallet::Event<T>
+   * Lookup239: pallet_common::pallet::Event<T>
    **/
   PalletCommonEvent: {
     _enum: {
@@ -1906,7 +1937,7 @@
     }
   },
   /**
-   * Lookup229: pallet_evm::pallet::Event<T>
+   * Lookup240: pallet_evm::pallet::Event<T>
    **/
   PalletEvmEvent: {
     _enum: {
@@ -1920,7 +1951,7 @@
     }
   },
   /**
-   * Lookup230: ethereum::log::Log
+   * Lookup241: ethereum::log::Log
    **/
   EthereumLog: {
     address: 'H160',
@@ -1928,7 +1959,7 @@
     data: 'Bytes'
   },
   /**
-   * Lookup231: pallet_ethereum::pallet::Event
+   * Lookup242: pallet_ethereum::pallet::Event
    **/
   PalletEthereumEvent: {
     _enum: {
@@ -1936,7 +1967,7 @@
     }
   },
   /**
-   * Lookup232: evm_core::error::ExitReason
+   * Lookup243: evm_core::error::ExitReason
    **/
   EvmCoreErrorExitReason: {
     _enum: {
@@ -1947,13 +1978,13 @@
     }
   },
   /**
-   * Lookup233: evm_core::error::ExitSucceed
+   * Lookup244: evm_core::error::ExitSucceed
    **/
   EvmCoreErrorExitSucceed: {
     _enum: ['Stopped', 'Returned', 'Suicided']
   },
   /**
-   * Lookup234: evm_core::error::ExitError
+   * Lookup245: evm_core::error::ExitError
    **/
   EvmCoreErrorExitError: {
     _enum: {
@@ -1975,13 +2006,13 @@
     }
   },
   /**
-   * Lookup237: evm_core::error::ExitRevert
+   * Lookup248: evm_core::error::ExitRevert
    **/
   EvmCoreErrorExitRevert: {
     _enum: ['Reverted']
   },
   /**
-   * Lookup238: evm_core::error::ExitFatal
+   * Lookup249: evm_core::error::ExitFatal
    **/
   EvmCoreErrorExitFatal: {
     _enum: {
@@ -1992,7 +2023,7 @@
     }
   },
   /**
-   * Lookup239: frame_system::Phase
+   * Lookup250: frame_system::Phase
    **/
   FrameSystemPhase: {
     _enum: {
@@ -2002,14 +2033,14 @@
     }
   },
   /**
-   * Lookup241: frame_system::LastRuntimeUpgradeInfo
+   * Lookup252: frame_system::LastRuntimeUpgradeInfo
    **/
   FrameSystemLastRuntimeUpgradeInfo: {
     specVersion: 'Compact<u32>',
     specName: 'Text'
   },
   /**
-   * Lookup242: frame_system::limits::BlockWeights
+   * Lookup253: frame_system::limits::BlockWeights
    **/
   FrameSystemLimitsBlockWeights: {
     baseBlock: 'u64',
@@ -2017,7 +2048,7 @@
     perClass: 'FrameSupportWeightsPerDispatchClassWeightsPerClass'
   },
   /**
-   * Lookup243: frame_support::weights::PerDispatchClass<frame_system::limits::WeightsPerClass>
+   * Lookup254: frame_support::weights::PerDispatchClass<frame_system::limits::WeightsPerClass>
    **/
   FrameSupportWeightsPerDispatchClassWeightsPerClass: {
     normal: 'FrameSystemLimitsWeightsPerClass',
@@ -2025,7 +2056,7 @@
     mandatory: 'FrameSystemLimitsWeightsPerClass'
   },
   /**
-   * Lookup244: frame_system::limits::WeightsPerClass
+   * Lookup255: frame_system::limits::WeightsPerClass
    **/
   FrameSystemLimitsWeightsPerClass: {
     baseExtrinsic: 'u64',
@@ -2034,13 +2065,13 @@
     reserved: 'Option<u64>'
   },
   /**
-   * Lookup246: frame_system::limits::BlockLength
+   * Lookup257: frame_system::limits::BlockLength
    **/
   FrameSystemLimitsBlockLength: {
     max: 'FrameSupportWeightsPerDispatchClassU32'
   },
   /**
-   * Lookup247: frame_support::weights::PerDispatchClass<T>
+   * Lookup258: frame_support::weights::PerDispatchClass<T>
    **/
   FrameSupportWeightsPerDispatchClassU32: {
     normal: 'u32',
@@ -2048,14 +2079,14 @@
     mandatory: 'u32'
   },
   /**
-   * Lookup248: frame_support::weights::RuntimeDbWeight
+   * Lookup259: frame_support::weights::RuntimeDbWeight
    **/
   FrameSupportWeightsRuntimeDbWeight: {
     read: 'u64',
     write: 'u64'
   },
   /**
-   * Lookup249: sp_version::RuntimeVersion
+   * Lookup260: sp_version::RuntimeVersion
    **/
   SpVersionRuntimeVersion: {
     specName: 'Text',
@@ -2068,19 +2099,19 @@
     stateVersion: 'u8'
   },
   /**
-   * Lookup253: frame_system::pallet::Error<T>
+   * Lookup264: frame_system::pallet::Error<T>
    **/
   FrameSystemError: {
     _enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered']
   },
   /**
-   * Lookup255: orml_vesting::module::Error<T>
+   * Lookup266: orml_vesting::module::Error<T>
    **/
   OrmlVestingModuleError: {
     _enum: ['ZeroVestingPeriod', 'ZeroVestingPeriodCount', 'InsufficientBalanceToLock', 'TooManyVestingSchedules', 'AmountLow', 'MaxVestingSchedulesExceeded']
   },
   /**
-   * Lookup257: cumulus_pallet_xcmp_queue::InboundChannelDetails
+   * Lookup268: cumulus_pallet_xcmp_queue::InboundChannelDetails
    **/
   CumulusPalletXcmpQueueInboundChannelDetails: {
     sender: 'u32',
@@ -2088,19 +2119,19 @@
     messageMetadata: 'Vec<(u32,PolkadotParachainPrimitivesXcmpMessageFormat)>'
   },
   /**
-   * Lookup258: cumulus_pallet_xcmp_queue::InboundState
+   * Lookup269: cumulus_pallet_xcmp_queue::InboundState
    **/
   CumulusPalletXcmpQueueInboundState: {
     _enum: ['Ok', 'Suspended']
   },
   /**
-   * Lookup261: polkadot_parachain::primitives::XcmpMessageFormat
+   * Lookup272: polkadot_parachain::primitives::XcmpMessageFormat
    **/
   PolkadotParachainPrimitivesXcmpMessageFormat: {
     _enum: ['ConcatenatedVersionedXcm', 'ConcatenatedEncodedBlob', 'Signals']
   },
   /**
-   * Lookup264: cumulus_pallet_xcmp_queue::OutboundChannelDetails
+   * Lookup275: cumulus_pallet_xcmp_queue::OutboundChannelDetails
    **/
   CumulusPalletXcmpQueueOutboundChannelDetails: {
     recipient: 'u32',
@@ -2110,13 +2141,13 @@
     lastIndex: 'u16'
   },
   /**
-   * Lookup265: cumulus_pallet_xcmp_queue::OutboundState
+   * Lookup276: cumulus_pallet_xcmp_queue::OutboundState
    **/
   CumulusPalletXcmpQueueOutboundState: {
     _enum: ['Ok', 'Suspended']
   },
   /**
-   * Lookup267: cumulus_pallet_xcmp_queue::QueueConfigData
+   * Lookup278: cumulus_pallet_xcmp_queue::QueueConfigData
    **/
   CumulusPalletXcmpQueueQueueConfigData: {
     suspendThreshold: 'u32',
@@ -2127,29 +2158,29 @@
     xcmpMaxIndividualWeight: 'u64'
   },
   /**
-   * Lookup269: cumulus_pallet_xcmp_queue::pallet::Error<T>
+   * Lookup280: cumulus_pallet_xcmp_queue::pallet::Error<T>
    **/
   CumulusPalletXcmpQueueError: {
     _enum: ['FailedToSend', 'BadXcmOrigin', 'BadXcm', 'BadOverweightIndex', 'WeightOverLimit']
   },
   /**
-   * Lookup270: pallet_xcm::pallet::Error<T>
+   * Lookup281: pallet_xcm::pallet::Error<T>
    **/
   PalletXcmError: {
     _enum: ['Unreachable', 'SendFailure', 'Filtered', 'UnweighableMessage', 'DestinationNotInvertible', 'Empty', 'CannotReanchor', 'TooManyAssets', 'InvalidOrigin', 'BadVersion', 'BadLocation', 'NoSubscription', 'AlreadySubscribed']
   },
   /**
-   * Lookup271: cumulus_pallet_xcm::pallet::Error<T>
+   * Lookup282: cumulus_pallet_xcm::pallet::Error<T>
    **/
   CumulusPalletXcmError: 'Null',
   /**
-   * Lookup272: cumulus_pallet_dmp_queue::ConfigData
+   * Lookup283: cumulus_pallet_dmp_queue::ConfigData
    **/
   CumulusPalletDmpQueueConfigData: {
     maxIndividual: 'u64'
   },
   /**
-   * Lookup273: cumulus_pallet_dmp_queue::PageIndexData
+   * Lookup284: cumulus_pallet_dmp_queue::PageIndexData
    **/
   CumulusPalletDmpQueuePageIndexData: {
     beginUsed: 'u32',
@@ -2157,19 +2188,19 @@
     overweightCount: 'u64'
   },
   /**
-   * Lookup276: cumulus_pallet_dmp_queue::pallet::Error<T>
+   * Lookup287: cumulus_pallet_dmp_queue::pallet::Error<T>
    **/
   CumulusPalletDmpQueueError: {
     _enum: ['Unknown', 'OverLimit']
   },
   /**
-   * Lookup280: pallet_unique::Error<T>
+   * Lookup291: pallet_unique::Error<T>
    **/
   PalletUniqueError: {
     _enum: ['CollectionDecimalPointLimitExceeded', 'ConfirmUnsetSponsorFail', 'EmptyArgument']
   },
   /**
-   * Lookup281: up_data_structs::Collection<sp_core::crypto::AccountId32>
+   * Lookup292: up_data_structs::Collection<sp_core::crypto::AccountId32>
    **/
   UpDataStructsCollection: {
     owner: 'AccountId32',
@@ -2188,7 +2219,7 @@
     metaUpdatePermission: 'UpDataStructsMetaUpdatePermission'
   },
   /**
-   * Lookup282: up_data_structs::SponsorshipState<sp_core::crypto::AccountId32>
+   * Lookup293: up_data_structs::SponsorshipState<sp_core::crypto::AccountId32>
    **/
   UpDataStructsSponsorshipState: {
     _enum: {
@@ -2198,7 +2229,7 @@
     }
   },
   /**
-   * Lookup285: up_data_structs::CollectionStats
+   * Lookup296: up_data_structs::CollectionStats
    **/
   UpDataStructsCollectionStats: {
     created: 'u32',
@@ -2206,32 +2237,32 @@
     alive: 'u32'
   },
   /**
-   * Lookup286: pallet_common::pallet::Error<T>
+   * Lookup297: pallet_common::pallet::Error<T>
    **/
   PalletCommonError: {
     _enum: ['CollectionNotFound', 'MustBeTokenOwner', 'NoPermission', 'PublicMintingNotAllowed', 'AddressNotInAllowlist', 'CollectionNameLimitExceeded', 'CollectionDescriptionLimitExceeded', 'CollectionTokenPrefixLimitExceeded', 'TotalCollectionsLimitExceeded', 'TokenVariableDataLimitExceeded', 'CollectionAdminCountExceeded', 'CollectionLimitBoundsExceeded', 'OwnerPermissionsCantBeReverted', 'TransferNotAllowed', 'AccountTokenLimitExceeded', 'CollectionTokenLimitExceeded', 'MetadataFlagFrozen', 'TokenNotFound', 'TokenValueTooLow', 'ApprovedValueTooLow', 'CantApproveMoreThanOwned', 'AddressIsZero', 'UnsupportedOperation']
   },
   /**
-   * Lookup288: pallet_fungible::pallet::Error<T>
+   * Lookup299: pallet_fungible::pallet::Error<T>
    **/
   PalletFungibleError: {
     _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData']
   },
   /**
-   * Lookup289: pallet_refungible::ItemData
+   * Lookup300: pallet_refungible::ItemData
    **/
   PalletRefungibleItemData: {
     constData: 'Bytes',
     variableData: 'Bytes'
   },
   /**
-   * Lookup293: pallet_refungible::pallet::Error<T>
+   * Lookup304: pallet_refungible::pallet::Error<T>
    **/
   PalletRefungibleError: {
     _enum: ['NotRefungibleDataUsedToMintFungibleCollectionToken', 'WrongRefungiblePieces']
   },
   /**
-   * Lookup294: pallet_nonfungible::ItemData<pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup305: pallet_nonfungible::ItemData<pallet_common::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   PalletNonfungibleItemData: {
     constData: 'Bytes',
@@ -2239,19 +2270,19 @@
     owner: 'PalletCommonAccountBasicCrossAccountIdRepr'
   },
   /**
-   * Lookup295: pallet_nonfungible::pallet::Error<T>
+   * Lookup306: pallet_nonfungible::pallet::Error<T>
    **/
   PalletNonfungibleError: {
     _enum: ['NotNonfungibleDataUsedToMintFungibleCollectionToken', 'NonfungibleItemsHaveNoAmount']
   },
   /**
-   * Lookup297: pallet_evm::pallet::Error<T>
+   * Lookup308: pallet_evm::pallet::Error<T>
    **/
   PalletEvmError: {
     _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce']
   },
   /**
-   * Lookup300: fp_rpc::TransactionStatus
+   * Lookup311: fp_rpc::TransactionStatus
    **/
   FpRpcTransactionStatus: {
     transactionHash: 'H256',
@@ -2263,11 +2294,11 @@
     logsBloom: 'EthbloomBloom'
   },
   /**
-   * Lookup303: ethbloom::Bloom
+   * Lookup314: ethbloom::Bloom
    **/
   EthbloomBloom: '[u8;256]',
   /**
-   * Lookup305: ethereum::receipt::ReceiptV3
+   * Lookup316: ethereum::receipt::ReceiptV3
    **/
   EthereumReceiptReceiptV3: {
     _enum: {
@@ -2277,7 +2308,7 @@
     }
   },
   /**
-   * Lookup306: ethereum::receipt::EIP658ReceiptData
+   * Lookup317: ethereum::receipt::EIP658ReceiptData
    **/
   EthereumReceiptEip658ReceiptData: {
     statusCode: 'u8',
@@ -2286,7 +2317,7 @@
     logs: 'Vec<EthereumLog>'
   },
   /**
-   * Lookup307: ethereum::block::Block<ethereum::transaction::TransactionV2>
+   * Lookup318: ethereum::block::Block<ethereum::transaction::TransactionV2>
    **/
   EthereumBlock: {
     header: 'EthereumHeader',
@@ -2294,7 +2325,7 @@
     ommers: 'Vec<EthereumHeader>'
   },
   /**
-   * Lookup308: ethereum::header::Header
+   * Lookup319: ethereum::header::Header
    **/
   EthereumHeader: {
     parentHash: 'H256',
@@ -2314,41 +2345,41 @@
     nonce: 'EthereumTypesHashH64'
   },
   /**
-   * Lookup309: ethereum_types::hash::H64
+   * Lookup320: ethereum_types::hash::H64
    **/
   EthereumTypesHashH64: '[u8;8]',
   /**
-   * Lookup314: pallet_ethereum::pallet::Error<T>
+   * Lookup325: pallet_ethereum::pallet::Error<T>
    **/
   PalletEthereumError: {
     _enum: ['InvalidSignature', 'PreLogExists']
   },
   /**
-   * Lookup315: pallet_evm_coder_substrate::pallet::Error<T>
+   * Lookup326: pallet_evm_coder_substrate::pallet::Error<T>
    **/
   PalletEvmCoderSubstrateError: {
     _enum: ['OutOfGas', 'OutOfFund']
   },
   /**
-   * Lookup316: pallet_evm_contract_helpers::SponsoringModeT
+   * Lookup327: pallet_evm_contract_helpers::SponsoringModeT
    **/
   PalletEvmContractHelpersSponsoringModeT: {
     _enum: ['Disabled', 'Allowlisted', 'Generous']
   },
   /**
-   * Lookup318: pallet_evm_contract_helpers::pallet::Error<T>
+   * Lookup329: pallet_evm_contract_helpers::pallet::Error<T>
    **/
   PalletEvmContractHelpersError: {
     _enum: ['NoPermission']
   },
   /**
-   * Lookup319: pallet_evm_migration::pallet::Error<T>
+   * Lookup330: pallet_evm_migration::pallet::Error<T>
    **/
   PalletEvmMigrationError: {
     _enum: ['AccountNotEmpty', 'AccountIsNotMigrating']
   },
   /**
-   * Lookup321: sp_runtime::MultiSignature
+   * Lookup332: sp_runtime::MultiSignature
    **/
   SpRuntimeMultiSignature: {
     _enum: {
@@ -2358,39 +2389,39 @@
     }
   },
   /**
-   * Lookup322: sp_core::ed25519::Signature
+   * Lookup333: sp_core::ed25519::Signature
    **/
   SpCoreEd25519Signature: '[u8;64]',
   /**
-   * Lookup324: sp_core::sr25519::Signature
+   * Lookup335: sp_core::sr25519::Signature
    **/
   SpCoreSr25519Signature: '[u8;64]',
   /**
-   * Lookup325: sp_core::ecdsa::Signature
+   * Lookup336: sp_core::ecdsa::Signature
    **/
   SpCoreEcdsaSignature: '[u8;65]',
   /**
-   * Lookup328: frame_system::extensions::check_spec_version::CheckSpecVersion<T>
+   * Lookup339: frame_system::extensions::check_spec_version::CheckSpecVersion<T>
    **/
   FrameSystemExtensionsCheckSpecVersion: 'Null',
   /**
-   * Lookup329: frame_system::extensions::check_genesis::CheckGenesis<T>
+   * Lookup340: frame_system::extensions::check_genesis::CheckGenesis<T>
    **/
   FrameSystemExtensionsCheckGenesis: 'Null',
   /**
-   * Lookup332: frame_system::extensions::check_nonce::CheckNonce<T>
+   * Lookup343: frame_system::extensions::check_nonce::CheckNonce<T>
    **/
   FrameSystemExtensionsCheckNonce: 'Compact<u32>',
   /**
-   * Lookup333: frame_system::extensions::check_weight::CheckWeight<T>
+   * Lookup344: frame_system::extensions::check_weight::CheckWeight<T>
    **/
   FrameSystemExtensionsCheckWeight: 'Null',
   /**
-   * Lookup334: pallet_template_transaction_payment::ChargeTransactionPayment<unique_runtime::Runtime>
+   * Lookup345: pallet_template_transaction_payment::ChargeTransactionPayment<unique_runtime::Runtime>
    **/
   PalletTemplateTransactionPaymentChargeTransactionPayment: 'Compact<u128>',
   /**
-   * Lookup335: unique_runtime::Runtime
+   * Lookup346: unique_runtime::Runtime
    **/
   UniqueRuntimeRuntime: 'Null'
 };
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1421,6 +1421,11 @@
       readonly owner: PalletCommonAccountBasicCrossAccountIdRepr;
       readonly itemsData: Vec<UpDataStructsCreateItemData>;
     } & Struct;
+    readonly isCreateMultipleItemsEx: boolean;
+    readonly asCreateMultipleItemsEx: {
+      readonly collectionId: u32;
+      readonly data: UpDataStructsCreateItemExData;
+    } & Struct;
     readonly isSetTransfersEnabledFlag: boolean;
     readonly asSetTransfersEnabledFlag: {
       readonly collectionId: u32;
@@ -1497,7 +1502,7 @@
       readonly collectionId: u32;
       readonly newLimit: UpDataStructsCollectionLimits;
     } & Struct;
-    readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetVariableOnChainSchema' | 'SetCollectionLimits';
+    readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetVariableOnChainSchema' | 'SetCollectionLimits';
   }
 
   /** @name UpDataStructsCollectionMode (155) */
@@ -1606,10 +1611,37 @@
     readonly pieces: u128;
   }
 
-  /** @name PalletTemplateTransactionPaymentCall (181) */
+  /** @name UpDataStructsCreateItemExData (180) */
+  export interface UpDataStructsCreateItemExData extends Enum {
+    readonly isNft: boolean;
+    readonly asNft: Vec<UpDataStructsCreateNftExData>;
+    readonly isFungible: boolean;
+    readonly asFungible: BTreeMap<PalletCommonAccountBasicCrossAccountIdRepr, u128>;
+    readonly isRefungibleMultipleItems: boolean;
+    readonly asRefungibleMultipleItems: Vec<UpDataStructsCreateRefungibleExData>;
+    readonly isRefungibleMultipleOwners: boolean;
+    readonly asRefungibleMultipleOwners: UpDataStructsCreateRefungibleExData;
+    readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';
+  }
+
+  /** @name UpDataStructsCreateNftExData (182) */
+  export interface UpDataStructsCreateNftExData extends Struct {
+    readonly constData: Bytes;
+    readonly variableData: Bytes;
+    readonly owner: PalletCommonAccountBasicCrossAccountIdRepr;
+  }
+
+  /** @name UpDataStructsCreateRefungibleExData (189) */
+  export interface UpDataStructsCreateRefungibleExData extends Struct {
+    readonly constData: Bytes;
+    readonly variableData: Bytes;
+    readonly users: BTreeMap<PalletCommonAccountBasicCrossAccountIdRepr, u128>;
+  }
+
+  /** @name PalletTemplateTransactionPaymentCall (192) */
   export type PalletTemplateTransactionPaymentCall = Null;
 
-  /** @name PalletEvmCall (182) */
+  /** @name PalletEvmCall (193) */
   export interface PalletEvmCall extends Enum {
     readonly isWithdraw: boolean;
     readonly asWithdraw: {
@@ -1654,7 +1686,7 @@
     readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2';
   }
 
-  /** @name PalletEthereumCall (188) */
+  /** @name PalletEthereumCall (199) */
   export interface PalletEthereumCall extends Enum {
     readonly isTransact: boolean;
     readonly asTransact: {
@@ -1663,7 +1695,7 @@
     readonly type: 'Transact';
   }
 
-  /** @name EthereumTransactionTransactionV2 (189) */
+  /** @name EthereumTransactionTransactionV2 (200) */
   export interface EthereumTransactionTransactionV2 extends Enum {
     readonly isLegacy: boolean;
     readonly asLegacy: EthereumTransactionLegacyTransaction;
@@ -1674,7 +1706,7 @@
     readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';
   }
 
-  /** @name EthereumTransactionLegacyTransaction (190) */
+  /** @name EthereumTransactionLegacyTransaction (201) */
   export interface EthereumTransactionLegacyTransaction extends Struct {
     readonly nonce: U256;
     readonly gasPrice: U256;
@@ -1685,7 +1717,7 @@
     readonly signature: EthereumTransactionTransactionSignature;
   }
 
-  /** @name EthereumTransactionTransactionAction (191) */
+  /** @name EthereumTransactionTransactionAction (202) */
   export interface EthereumTransactionTransactionAction extends Enum {
     readonly isCall: boolean;
     readonly asCall: H160;
@@ -1693,14 +1725,14 @@
     readonly type: 'Call' | 'Create';
   }
 
-  /** @name EthereumTransactionTransactionSignature (192) */
+  /** @name EthereumTransactionTransactionSignature (203) */
   export interface EthereumTransactionTransactionSignature extends Struct {
     readonly v: u64;
     readonly r: H256;
     readonly s: H256;
   }
 
-  /** @name EthereumTransactionEip2930Transaction (194) */
+  /** @name EthereumTransactionEip2930Transaction (205) */
   export interface EthereumTransactionEip2930Transaction extends Struct {
     readonly chainId: u64;
     readonly nonce: U256;
@@ -1715,13 +1747,13 @@
     readonly s: H256;
   }
 
-  /** @name EthereumTransactionAccessListItem (196) */
+  /** @name EthereumTransactionAccessListItem (207) */
   export interface EthereumTransactionAccessListItem extends Struct {
     readonly address: H160;
     readonly slots: Vec<H256>;
   }
 
-  /** @name EthereumTransactionEip1559Transaction (197) */
+  /** @name EthereumTransactionEip1559Transaction (208) */
   export interface EthereumTransactionEip1559Transaction extends Struct {
     readonly chainId: u64;
     readonly nonce: U256;
@@ -1737,7 +1769,7 @@
     readonly s: H256;
   }
 
-  /** @name PalletEvmMigrationCall (198) */
+  /** @name PalletEvmMigrationCall (209) */
   export interface PalletEvmMigrationCall extends Enum {
     readonly isBegin: boolean;
     readonly asBegin: {
@@ -1756,7 +1788,7 @@
     readonly type: 'Begin' | 'SetData' | 'Finish';
   }
 
-  /** @name PalletSudoEvent (201) */
+  /** @name PalletSudoEvent (212) */
   export interface PalletSudoEvent extends Enum {
     readonly isSudid: boolean;
     readonly asSudid: {
@@ -1773,7 +1805,7 @@
     readonly type: 'Sudid' | 'KeyChanged' | 'SudoAsDone';
   }
 
-  /** @name SpRuntimeDispatchError (203) */
+  /** @name SpRuntimeDispatchError (214) */
   export interface SpRuntimeDispatchError extends Enum {
     readonly isOther: boolean;
     readonly isCannotLookup: boolean;
@@ -1790,13 +1822,13 @@
     readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic';
   }
 
-  /** @name SpRuntimeModuleError (204) */
+  /** @name SpRuntimeModuleError (215) */
   export interface SpRuntimeModuleError extends Struct {
     readonly index: u8;
     readonly error: u8;
   }
 
-  /** @name SpRuntimeTokenError (205) */
+  /** @name SpRuntimeTokenError (216) */
   export interface SpRuntimeTokenError extends Enum {
     readonly isNoFunds: boolean;
     readonly isWouldDie: boolean;
@@ -1808,7 +1840,7 @@
     readonly type: 'NoFunds' | 'WouldDie' | 'BelowMinimum' | 'CannotCreate' | 'UnknownAsset' | 'Frozen' | 'Unsupported';
   }
 
-  /** @name SpRuntimeArithmeticError (206) */
+  /** @name SpRuntimeArithmeticError (217) */
   export interface SpRuntimeArithmeticError extends Enum {
     readonly isUnderflow: boolean;
     readonly isOverflow: boolean;
@@ -1816,13 +1848,13 @@
     readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero';
   }
 
-  /** @name PalletSudoError (207) */
+  /** @name PalletSudoError (218) */
   export interface PalletSudoError extends Enum {
     readonly isRequireSudo: boolean;
     readonly type: 'RequireSudo';
   }
 
-  /** @name FrameSystemAccountInfo (208) */
+  /** @name FrameSystemAccountInfo (219) */
   export interface FrameSystemAccountInfo extends Struct {
     readonly nonce: u32;
     readonly consumers: u32;
@@ -1831,19 +1863,19 @@
     readonly data: PalletBalancesAccountData;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassU64 (209) */
+  /** @name FrameSupportWeightsPerDispatchClassU64 (220) */
   export interface FrameSupportWeightsPerDispatchClassU64 extends Struct {
     readonly normal: u64;
     readonly operational: u64;
     readonly mandatory: u64;
   }
 
-  /** @name SpRuntimeDigest (210) */
+  /** @name SpRuntimeDigest (221) */
   export interface SpRuntimeDigest extends Struct {
     readonly logs: Vec<SpRuntimeDigestDigestItem>;
   }
 
-  /** @name SpRuntimeDigestDigestItem (212) */
+  /** @name SpRuntimeDigestDigestItem (223) */
   export interface SpRuntimeDigestDigestItem extends Enum {
     readonly isOther: boolean;
     readonly asOther: Bytes;
@@ -1857,14 +1889,14 @@
     readonly type: 'Other' | 'Consensus' | 'Seal' | 'PreRuntime' | 'RuntimeEnvironmentUpdated';
   }
 
-  /** @name FrameSystemEventRecord (214) */
+  /** @name FrameSystemEventRecord (225) */
   export interface FrameSystemEventRecord extends Struct {
     readonly phase: FrameSystemPhase;
     readonly event: Event;
     readonly topics: Vec<H256>;
   }
 
-  /** @name FrameSystemEvent (216) */
+  /** @name FrameSystemEvent (227) */
   export interface FrameSystemEvent extends Enum {
     readonly isExtrinsicSuccess: boolean;
     readonly asExtrinsicSuccess: {
@@ -1892,14 +1924,14 @@
     readonly type: 'ExtrinsicSuccess' | 'ExtrinsicFailed' | 'CodeUpdated' | 'NewAccount' | 'KilledAccount' | 'Remarked';
   }
 
-  /** @name FrameSupportWeightsDispatchInfo (217) */
+  /** @name FrameSupportWeightsDispatchInfo (228) */
   export interface FrameSupportWeightsDispatchInfo extends Struct {
     readonly weight: u64;
     readonly class: FrameSupportWeightsDispatchClass;
     readonly paysFee: FrameSupportWeightsPays;
   }
 
-  /** @name FrameSupportWeightsDispatchClass (218) */
+  /** @name FrameSupportWeightsDispatchClass (229) */
   export interface FrameSupportWeightsDispatchClass extends Enum {
     readonly isNormal: boolean;
     readonly isOperational: boolean;
@@ -1907,14 +1939,14 @@
     readonly type: 'Normal' | 'Operational' | 'Mandatory';
   }
 
-  /** @name FrameSupportWeightsPays (219) */
+  /** @name FrameSupportWeightsPays (230) */
   export interface FrameSupportWeightsPays extends Enum {
     readonly isYes: boolean;
     readonly isNo: boolean;
     readonly type: 'Yes' | 'No';
   }
 
-  /** @name OrmlVestingModuleEvent (220) */
+  /** @name OrmlVestingModuleEvent (231) */
   export interface OrmlVestingModuleEvent extends Enum {
     readonly isVestingScheduleAdded: boolean;
     readonly asVestingScheduleAdded: {
@@ -1934,7 +1966,7 @@
     readonly type: 'VestingScheduleAdded' | 'Claimed' | 'VestingSchedulesUpdated';
   }
 
-  /** @name CumulusPalletXcmpQueueEvent (221) */
+  /** @name CumulusPalletXcmpQueueEvent (232) */
   export interface CumulusPalletXcmpQueueEvent extends Enum {
     readonly isSuccess: boolean;
     readonly asSuccess: Option<H256>;
@@ -1955,7 +1987,7 @@
     readonly type: 'Success' | 'Fail' | 'BadVersion' | 'BadFormat' | 'UpwardMessageSent' | 'XcmpMessageSent' | 'OverweightEnqueued' | 'OverweightServiced';
   }
 
-  /** @name PalletXcmEvent (222) */
+  /** @name PalletXcmEvent (233) */
   export interface PalletXcmEvent extends Enum {
     readonly isAttempted: boolean;
     readonly asAttempted: XcmV2TraitsOutcome;
@@ -1992,7 +2024,7 @@
     readonly type: 'Attempted' | 'Sent' | 'UnexpectedResponse' | 'ResponseReady' | 'Notified' | 'NotifyOverweight' | 'NotifyDispatchError' | 'NotifyDecodeFailed' | 'InvalidResponder' | 'InvalidResponderVersion' | 'ResponseTaken' | 'AssetsTrapped' | 'VersionChangeNotified' | 'SupportedVersionChanged' | 'NotifyTargetSendFail' | 'NotifyTargetMigrationFail';
   }
 
-  /** @name XcmV2TraitsOutcome (223) */
+  /** @name XcmV2TraitsOutcome (234) */
   export interface XcmV2TraitsOutcome extends Enum {
     readonly isComplete: boolean;
     readonly asComplete: u64;
@@ -2003,7 +2035,7 @@
     readonly type: 'Complete' | 'Incomplete' | 'Error';
   }
 
-  /** @name CumulusPalletXcmEvent (225) */
+  /** @name CumulusPalletXcmEvent (236) */
   export interface CumulusPalletXcmEvent extends Enum {
     readonly isInvalidFormat: boolean;
     readonly asInvalidFormat: U8aFixed;
@@ -2014,7 +2046,7 @@
     readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward';
   }
 
-  /** @name CumulusPalletDmpQueueEvent (226) */
+  /** @name CumulusPalletDmpQueueEvent (237) */
   export interface CumulusPalletDmpQueueEvent extends Enum {
     readonly isInvalidFormat: boolean;
     readonly asInvalidFormat: U8aFixed;
@@ -2031,7 +2063,7 @@
     readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward' | 'WeightExhausted' | 'OverweightEnqueued' | 'OverweightServiced';
   }
 
-  /** @name PalletUniqueRawEvent (227) */
+  /** @name PalletUniqueRawEvent (238) */
   export interface PalletUniqueRawEvent extends Enum {
     readonly isCollectionSponsorRemoved: boolean;
     readonly asCollectionSponsorRemoved: u32;
@@ -2066,7 +2098,7 @@
     readonly type: 'CollectionSponsorRemoved' | 'CollectionAdminAdded' | 'CollectionOwnedChanged' | 'CollectionSponsorSet' | 'ConstOnChainSchemaSet' | 'SponsorshipConfirmed' | 'CollectionAdminRemoved' | 'AllowListAddressRemoved' | 'AllowListAddressAdded' | 'CollectionLimitSet' | 'MintPermissionSet' | 'OffchainSchemaSet' | 'PublicAccessModeSet' | 'SchemaVersionSet' | 'VariableOnChainSchemaSet';
   }
 
-  /** @name PalletCommonEvent (228) */
+  /** @name PalletCommonEvent (239) */
   export interface PalletCommonEvent extends Enum {
     readonly isCollectionCreated: boolean;
     readonly asCollectionCreated: ITuple<[u32, u8, AccountId32]>;
@@ -2083,7 +2115,7 @@
     readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved';
   }
 
-  /** @name PalletEvmEvent (229) */
+  /** @name PalletEvmEvent (240) */
   export interface PalletEvmEvent extends Enum {
     readonly isLog: boolean;
     readonly asLog: EthereumLog;
@@ -2102,21 +2134,21 @@
     readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
   }
 
-  /** @name EthereumLog (230) */
+  /** @name EthereumLog (241) */
   export interface EthereumLog extends Struct {
     readonly address: H160;
     readonly topics: Vec<H256>;
     readonly data: Bytes;
   }
 
-  /** @name PalletEthereumEvent (231) */
+  /** @name PalletEthereumEvent (242) */
   export interface PalletEthereumEvent extends Enum {
     readonly isExecuted: boolean;
     readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
     readonly type: 'Executed';
   }
 
-  /** @name EvmCoreErrorExitReason (232) */
+  /** @name EvmCoreErrorExitReason (243) */
   export interface EvmCoreErrorExitReason extends Enum {
     readonly isSucceed: boolean;
     readonly asSucceed: EvmCoreErrorExitSucceed;
@@ -2129,7 +2161,7 @@
     readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';
   }
 
-  /** @name EvmCoreErrorExitSucceed (233) */
+  /** @name EvmCoreErrorExitSucceed (244) */
   export interface EvmCoreErrorExitSucceed extends Enum {
     readonly isStopped: boolean;
     readonly isReturned: boolean;
@@ -2137,7 +2169,7 @@
     readonly type: 'Stopped' | 'Returned' | 'Suicided';
   }
 
-  /** @name EvmCoreErrorExitError (234) */
+  /** @name EvmCoreErrorExitError (245) */
   export interface EvmCoreErrorExitError extends Enum {
     readonly isStackUnderflow: boolean;
     readonly isStackOverflow: boolean;
@@ -2158,13 +2190,13 @@
     readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'InvalidCode' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other';
   }
 
-  /** @name EvmCoreErrorExitRevert (237) */
+  /** @name EvmCoreErrorExitRevert (248) */
   export interface EvmCoreErrorExitRevert extends Enum {
     readonly isReverted: boolean;
     readonly type: 'Reverted';
   }
 
-  /** @name EvmCoreErrorExitFatal (238) */
+  /** @name EvmCoreErrorExitFatal (249) */
   export interface EvmCoreErrorExitFatal extends Enum {
     readonly isNotSupported: boolean;
     readonly isUnhandledInterrupt: boolean;
@@ -2175,7 +2207,7 @@
     readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';
   }
 
-  /** @name FrameSystemPhase (239) */
+  /** @name FrameSystemPhase (250) */
   export interface FrameSystemPhase extends Enum {
     readonly isApplyExtrinsic: boolean;
     readonly asApplyExtrinsic: u32;
@@ -2184,27 +2216,27 @@
     readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';
   }
 
-  /** @name FrameSystemLastRuntimeUpgradeInfo (241) */
+  /** @name FrameSystemLastRuntimeUpgradeInfo (252) */
   export interface FrameSystemLastRuntimeUpgradeInfo extends Struct {
     readonly specVersion: Compact<u32>;
     readonly specName: Text;
   }
 
-  /** @name FrameSystemLimitsBlockWeights (242) */
+  /** @name FrameSystemLimitsBlockWeights (253) */
   export interface FrameSystemLimitsBlockWeights extends Struct {
     readonly baseBlock: u64;
     readonly maxBlock: u64;
     readonly perClass: FrameSupportWeightsPerDispatchClassWeightsPerClass;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassWeightsPerClass (243) */
+  /** @name FrameSupportWeightsPerDispatchClassWeightsPerClass (254) */
   export interface FrameSupportWeightsPerDispatchClassWeightsPerClass extends Struct {
     readonly normal: FrameSystemLimitsWeightsPerClass;
     readonly operational: FrameSystemLimitsWeightsPerClass;
     readonly mandatory: FrameSystemLimitsWeightsPerClass;
   }
 
-  /** @name FrameSystemLimitsWeightsPerClass (244) */
+  /** @name FrameSystemLimitsWeightsPerClass (255) */
   export interface FrameSystemLimitsWeightsPerClass extends Struct {
     readonly baseExtrinsic: u64;
     readonly maxExtrinsic: Option<u64>;
@@ -2212,25 +2244,25 @@
     readonly reserved: Option<u64>;
   }
 
-  /** @name FrameSystemLimitsBlockLength (246) */
+  /** @name FrameSystemLimitsBlockLength (257) */
   export interface FrameSystemLimitsBlockLength extends Struct {
     readonly max: FrameSupportWeightsPerDispatchClassU32;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassU32 (247) */
+  /** @name FrameSupportWeightsPerDispatchClassU32 (258) */
   export interface FrameSupportWeightsPerDispatchClassU32 extends Struct {
     readonly normal: u32;
     readonly operational: u32;
     readonly mandatory: u32;
   }
 
-  /** @name FrameSupportWeightsRuntimeDbWeight (248) */
+  /** @name FrameSupportWeightsRuntimeDbWeight (259) */
   export interface FrameSupportWeightsRuntimeDbWeight extends Struct {
     readonly read: u64;
     readonly write: u64;
   }
 
-  /** @name SpVersionRuntimeVersion (249) */
+  /** @name SpVersionRuntimeVersion (260) */
   export interface SpVersionRuntimeVersion extends Struct {
     readonly specName: Text;
     readonly implName: Text;
@@ -2242,7 +2274,7 @@
     readonly stateVersion: u8;
   }
 
-  /** @name FrameSystemError (253) */
+  /** @name FrameSystemError (264) */
   export interface FrameSystemError extends Enum {
     readonly isInvalidSpecName: boolean;
     readonly isSpecVersionNeedsToIncrease: boolean;
@@ -2253,7 +2285,7 @@
     readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';
   }
 
-  /** @name OrmlVestingModuleError (255) */
+  /** @name OrmlVestingModuleError (266) */
   export interface OrmlVestingModuleError extends Enum {
     readonly isZeroVestingPeriod: boolean;
     readonly isZeroVestingPeriodCount: boolean;
@@ -2264,21 +2296,21 @@
     readonly type: 'ZeroVestingPeriod' | 'ZeroVestingPeriodCount' | 'InsufficientBalanceToLock' | 'TooManyVestingSchedules' | 'AmountLow' | 'MaxVestingSchedulesExceeded';
   }
 
-  /** @name CumulusPalletXcmpQueueInboundChannelDetails (257) */
+  /** @name CumulusPalletXcmpQueueInboundChannelDetails (268) */
   export interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct {
     readonly sender: u32;
     readonly state: CumulusPalletXcmpQueueInboundState;
     readonly messageMetadata: Vec<ITuple<[u32, PolkadotParachainPrimitivesXcmpMessageFormat]>>;
   }
 
-  /** @name CumulusPalletXcmpQueueInboundState (258) */
+  /** @name CumulusPalletXcmpQueueInboundState (269) */
   export interface CumulusPalletXcmpQueueInboundState extends Enum {
     readonly isOk: boolean;
     readonly isSuspended: boolean;
     readonly type: 'Ok' | 'Suspended';
   }
 
-  /** @name PolkadotParachainPrimitivesXcmpMessageFormat (261) */
+  /** @name PolkadotParachainPrimitivesXcmpMessageFormat (272) */
   export interface PolkadotParachainPrimitivesXcmpMessageFormat extends Enum {
     readonly isConcatenatedVersionedXcm: boolean;
     readonly isConcatenatedEncodedBlob: boolean;
@@ -2286,7 +2318,7 @@
     readonly type: 'ConcatenatedVersionedXcm' | 'ConcatenatedEncodedBlob' | 'Signals';
   }
 
-  /** @name CumulusPalletXcmpQueueOutboundChannelDetails (264) */
+  /** @name CumulusPalletXcmpQueueOutboundChannelDetails (275) */
   export interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct {
     readonly recipient: u32;
     readonly state: CumulusPalletXcmpQueueOutboundState;
@@ -2295,14 +2327,14 @@
     readonly lastIndex: u16;
   }
 
-  /** @name CumulusPalletXcmpQueueOutboundState (265) */
+  /** @name CumulusPalletXcmpQueueOutboundState (276) */
   export interface CumulusPalletXcmpQueueOutboundState extends Enum {
     readonly isOk: boolean;
     readonly isSuspended: boolean;
     readonly type: 'Ok' | 'Suspended';
   }
 
-  /** @name CumulusPalletXcmpQueueQueueConfigData (267) */
+  /** @name CumulusPalletXcmpQueueQueueConfigData (278) */
   export interface CumulusPalletXcmpQueueQueueConfigData extends Struct {
     readonly suspendThreshold: u32;
     readonly dropThreshold: u32;
@@ -2312,7 +2344,7 @@
     readonly xcmpMaxIndividualWeight: u64;
   }
 
-  /** @name CumulusPalletXcmpQueueError (269) */
+  /** @name CumulusPalletXcmpQueueError (280) */
   export interface CumulusPalletXcmpQueueError extends Enum {
     readonly isFailedToSend: boolean;
     readonly isBadXcmOrigin: boolean;
@@ -2322,7 +2354,7 @@
     readonly type: 'FailedToSend' | 'BadXcmOrigin' | 'BadXcm' | 'BadOverweightIndex' | 'WeightOverLimit';
   }
 
-  /** @name PalletXcmError (270) */
+  /** @name PalletXcmError (281) */
   export interface PalletXcmError extends Enum {
     readonly isUnreachable: boolean;
     readonly isSendFailure: boolean;
@@ -2340,29 +2372,29 @@
     readonly type: 'Unreachable' | 'SendFailure' | 'Filtered' | 'UnweighableMessage' | 'DestinationNotInvertible' | 'Empty' | 'CannotReanchor' | 'TooManyAssets' | 'InvalidOrigin' | 'BadVersion' | 'BadLocation' | 'NoSubscription' | 'AlreadySubscribed';
   }
 
-  /** @name CumulusPalletXcmError (271) */
+  /** @name CumulusPalletXcmError (282) */
   export type CumulusPalletXcmError = Null;
 
-  /** @name CumulusPalletDmpQueueConfigData (272) */
+  /** @name CumulusPalletDmpQueueConfigData (283) */
   export interface CumulusPalletDmpQueueConfigData extends Struct {
     readonly maxIndividual: u64;
   }
 
-  /** @name CumulusPalletDmpQueuePageIndexData (273) */
+  /** @name CumulusPalletDmpQueuePageIndexData (284) */
   export interface CumulusPalletDmpQueuePageIndexData extends Struct {
     readonly beginUsed: u32;
     readonly endUsed: u32;
     readonly overweightCount: u64;
   }
 
-  /** @name CumulusPalletDmpQueueError (276) */
+  /** @name CumulusPalletDmpQueueError (287) */
   export interface CumulusPalletDmpQueueError extends Enum {
     readonly isUnknown: boolean;
     readonly isOverLimit: boolean;
     readonly type: 'Unknown' | 'OverLimit';
   }
 
-  /** @name PalletUniqueError (280) */
+  /** @name PalletUniqueError (291) */
   export interface PalletUniqueError extends Enum {
     readonly isCollectionDecimalPointLimitExceeded: boolean;
     readonly isConfirmUnsetSponsorFail: boolean;
@@ -2370,7 +2402,7 @@
     readonly type: 'CollectionDecimalPointLimitExceeded' | 'ConfirmUnsetSponsorFail' | 'EmptyArgument';
   }
 
-  /** @name UpDataStructsCollection (281) */
+  /** @name UpDataStructsCollection (292) */
   export interface UpDataStructsCollection extends Struct {
     readonly owner: AccountId32;
     readonly mode: UpDataStructsCollectionMode;
@@ -2388,7 +2420,7 @@
     readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
   }
 
-  /** @name UpDataStructsSponsorshipState (282) */
+  /** @name UpDataStructsSponsorshipState (293) */
   export interface UpDataStructsSponsorshipState extends Enum {
     readonly isDisabled: boolean;
     readonly isUnconfirmed: boolean;
@@ -2398,14 +2430,14 @@
     readonly type: 'Disabled' | 'Unconfirmed' | 'Confirmed';
   }
 
-  /** @name UpDataStructsCollectionStats (285) */
+  /** @name UpDataStructsCollectionStats (296) */
   export interface UpDataStructsCollectionStats extends Struct {
     readonly created: u32;
     readonly destroyed: u32;
     readonly alive: u32;
   }
 
-  /** @name PalletCommonError (286) */
+  /** @name PalletCommonError (297) */
   export interface PalletCommonError extends Enum {
     readonly isCollectionNotFound: boolean;
     readonly isMustBeTokenOwner: boolean;
@@ -2433,7 +2465,7 @@
     readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'TokenVariableDataLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation';
   }
 
-  /** @name PalletFungibleError (288) */
+  /** @name PalletFungibleError (299) */
   export interface PalletFungibleError extends Enum {
     readonly isNotFungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isFungibleItemsHaveNoId: boolean;
@@ -2441,34 +2473,34 @@
     readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData';
   }
 
-  /** @name PalletRefungibleItemData (289) */
+  /** @name PalletRefungibleItemData (300) */
   export interface PalletRefungibleItemData extends Struct {
     readonly constData: Bytes;
     readonly variableData: Bytes;
   }
 
-  /** @name PalletRefungibleError (293) */
+  /** @name PalletRefungibleError (304) */
   export interface PalletRefungibleError extends Enum {
     readonly isNotRefungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isWrongRefungiblePieces: boolean;
     readonly type: 'NotRefungibleDataUsedToMintFungibleCollectionToken' | 'WrongRefungiblePieces';
   }
 
-  /** @name PalletNonfungibleItemData (294) */
+  /** @name PalletNonfungibleItemData (305) */
   export interface PalletNonfungibleItemData extends Struct {
     readonly constData: Bytes;
     readonly variableData: Bytes;
     readonly owner: PalletCommonAccountBasicCrossAccountIdRepr;
   }
 
-  /** @name PalletNonfungibleError (295) */
+  /** @name PalletNonfungibleError (306) */
   export interface PalletNonfungibleError extends Enum {
     readonly isNotNonfungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isNonfungibleItemsHaveNoAmount: boolean;
     readonly type: 'NotNonfungibleDataUsedToMintFungibleCollectionToken' | 'NonfungibleItemsHaveNoAmount';
   }
 
-  /** @name PalletEvmError (297) */
+  /** @name PalletEvmError (308) */
   export interface PalletEvmError extends Enum {
     readonly isBalanceLow: boolean;
     readonly isFeeOverflow: boolean;
@@ -2479,7 +2511,7 @@
     readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
   }
 
-  /** @name FpRpcTransactionStatus (300) */
+  /** @name FpRpcTransactionStatus (311) */
   export interface FpRpcTransactionStatus extends Struct {
     readonly transactionHash: H256;
     readonly transactionIndex: u32;
@@ -2490,10 +2522,10 @@
     readonly logsBloom: EthbloomBloom;
   }
 
-  /** @name EthbloomBloom (303) */
+  /** @name EthbloomBloom (314) */
   export interface EthbloomBloom extends U8aFixed {}
 
-  /** @name EthereumReceiptReceiptV3 (305) */
+  /** @name EthereumReceiptReceiptV3 (316) */
   export interface EthereumReceiptReceiptV3 extends Enum {
     readonly isLegacy: boolean;
     readonly asLegacy: EthereumReceiptEip658ReceiptData;
@@ -2504,7 +2536,7 @@
     readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';
   }
 
-  /** @name EthereumReceiptEip658ReceiptData (306) */
+  /** @name EthereumReceiptEip658ReceiptData (317) */
   export interface EthereumReceiptEip658ReceiptData extends Struct {
     readonly statusCode: u8;
     readonly usedGas: U256;
@@ -2512,14 +2544,14 @@
     readonly logs: Vec<EthereumLog>;
   }
 
-  /** @name EthereumBlock (307) */
+  /** @name EthereumBlock (318) */
   export interface EthereumBlock extends Struct {
     readonly header: EthereumHeader;
     readonly transactions: Vec<EthereumTransactionTransactionV2>;
     readonly ommers: Vec<EthereumHeader>;
   }
 
-  /** @name EthereumHeader (308) */
+  /** @name EthereumHeader (319) */
   export interface EthereumHeader extends Struct {
     readonly parentHash: H256;
     readonly ommersHash: H256;
@@ -2538,24 +2570,24 @@
     readonly nonce: EthereumTypesHashH64;
   }
 
-  /** @name EthereumTypesHashH64 (309) */
+  /** @name EthereumTypesHashH64 (320) */
   export interface EthereumTypesHashH64 extends U8aFixed {}
 
-  /** @name PalletEthereumError (314) */
+  /** @name PalletEthereumError (325) */
   export interface PalletEthereumError extends Enum {
     readonly isInvalidSignature: boolean;
     readonly isPreLogExists: boolean;
     readonly type: 'InvalidSignature' | 'PreLogExists';
   }
 
-  /** @name PalletEvmCoderSubstrateError (315) */
+  /** @name PalletEvmCoderSubstrateError (326) */
   export interface PalletEvmCoderSubstrateError extends Enum {
     readonly isOutOfGas: boolean;
     readonly isOutOfFund: boolean;
     readonly type: 'OutOfGas' | 'OutOfFund';
   }
 
-  /** @name PalletEvmContractHelpersSponsoringModeT (316) */
+  /** @name PalletEvmContractHelpersSponsoringModeT (327) */
   export interface PalletEvmContractHelpersSponsoringModeT extends Enum {
     readonly isDisabled: boolean;
     readonly isAllowlisted: boolean;
@@ -2563,20 +2595,20 @@
     readonly type: 'Disabled' | 'Allowlisted' | 'Generous';
   }
 
-  /** @name PalletEvmContractHelpersError (318) */
+  /** @name PalletEvmContractHelpersError (329) */
   export interface PalletEvmContractHelpersError extends Enum {
     readonly isNoPermission: boolean;
     readonly type: 'NoPermission';
   }
 
-  /** @name PalletEvmMigrationError (319) */
+  /** @name PalletEvmMigrationError (330) */
   export interface PalletEvmMigrationError extends Enum {
     readonly isAccountNotEmpty: boolean;
     readonly isAccountIsNotMigrating: boolean;
     readonly type: 'AccountNotEmpty' | 'AccountIsNotMigrating';
   }
 
-  /** @name SpRuntimeMultiSignature (321) */
+  /** @name SpRuntimeMultiSignature (332) */
   export interface SpRuntimeMultiSignature extends Enum {
     readonly isEd25519: boolean;
     readonly asEd25519: SpCoreEd25519Signature;
@@ -2587,31 +2619,31 @@
     readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa';
   }
 
-  /** @name SpCoreEd25519Signature (322) */
+  /** @name SpCoreEd25519Signature (333) */
   export interface SpCoreEd25519Signature extends U8aFixed {}
 
-  /** @name SpCoreSr25519Signature (324) */
+  /** @name SpCoreSr25519Signature (335) */
   export interface SpCoreSr25519Signature extends U8aFixed {}
 
-  /** @name SpCoreEcdsaSignature (325) */
+  /** @name SpCoreEcdsaSignature (336) */
   export interface SpCoreEcdsaSignature extends U8aFixed {}
 
-  /** @name FrameSystemExtensionsCheckSpecVersion (328) */
+  /** @name FrameSystemExtensionsCheckSpecVersion (339) */
   export type FrameSystemExtensionsCheckSpecVersion = Null;
 
-  /** @name FrameSystemExtensionsCheckGenesis (329) */
+  /** @name FrameSystemExtensionsCheckGenesis (340) */
   export type FrameSystemExtensionsCheckGenesis = Null;
 
-  /** @name FrameSystemExtensionsCheckNonce (332) */
+  /** @name FrameSystemExtensionsCheckNonce (343) */
   export interface FrameSystemExtensionsCheckNonce extends Compact<u32> {}
 
-  /** @name FrameSystemExtensionsCheckWeight (333) */
+  /** @name FrameSystemExtensionsCheckWeight (344) */
   export type FrameSystemExtensionsCheckWeight = Null;
 
-  /** @name PalletTemplateTransactionPaymentChargeTransactionPayment (334) */
+  /** @name PalletTemplateTransactionPaymentChargeTransactionPayment (345) */
   export interface PalletTemplateTransactionPaymentChargeTransactionPayment extends Compact<u128> {}
 
-  /** @name UniqueRuntimeRuntime (335) */
+  /** @name UniqueRuntimeRuntime (346) */
   export type UniqueRuntimeRuntime = Null;
 
 } // declare module
modifiedtests/src/interfaces/unique/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/types.ts
+++ b/tests/src/interfaces/unique/types.ts
@@ -1316,6 +1316,11 @@
     readonly owner: PalletCommonAccountBasicCrossAccountIdRepr;
     readonly itemsData: Vec<UpDataStructsCreateItemData>;
   } & Struct;
+  readonly isCreateMultipleItemsEx: boolean;
+  readonly asCreateMultipleItemsEx: {
+    readonly collectionId: u32;
+    readonly data: UpDataStructsCreateItemExData;
+  } & Struct;
   readonly isSetTransfersEnabledFlag: boolean;
   readonly asSetTransfersEnabledFlag: {
     readonly collectionId: u32;
@@ -1392,7 +1397,7 @@
     readonly collectionId: u32;
     readonly newLimit: UpDataStructsCollectionLimits;
   } & Struct;
-  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetVariableOnChainSchema' | 'SetCollectionLimits';
+  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetVariableOnChainSchema' | 'SetCollectionLimits';
 }
 
 /** @name PalletUniqueError */
@@ -1806,12 +1811,32 @@
   readonly type: 'Nft' | 'Fungible' | 'ReFungible';
 }
 
+/** @name UpDataStructsCreateItemExData */
+export interface UpDataStructsCreateItemExData extends Enum {
+  readonly isNft: boolean;
+  readonly asNft: Vec<UpDataStructsCreateNftExData>;
+  readonly isFungible: boolean;
+  readonly asFungible: BTreeMap<PalletCommonAccountBasicCrossAccountIdRepr,u128>;
+  readonly isRefungibleMultipleItems: boolean;
+  readonly asRefungibleMultipleItems: Vec<UpDataStructsCreateRefungibleExData>;
+  readonly isRefungibleMultipleOwners: boolean;
+  readonly asRefungibleMultipleOwners: UpDataStructsCreateRefungibleExData;
+  readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';
+}
+
 /** @name UpDataStructsCreateNftData */
 export interface UpDataStructsCreateNftData extends Struct {
   readonly constData: Bytes;
   readonly variableData: Bytes;
 }
 
+/** @name UpDataStructsCreateNftExData */
+export interface UpDataStructsCreateNftExData extends Struct {
+  readonly constData: Bytes;
+  readonly variableData: Bytes;
+  readonly owner: PalletCommonAccountBasicCrossAccountIdRepr;
+}
+
 /** @name UpDataStructsCreateReFungibleData */
 export interface UpDataStructsCreateReFungibleData extends Struct {
   readonly constData: Bytes;
@@ -1819,6 +1844,13 @@
   readonly pieces: u128;
 }
 
+/** @name UpDataStructsCreateRefungibleExData */
+export interface UpDataStructsCreateRefungibleExData extends Struct {
+  readonly constData: Bytes;
+  readonly variableData: Bytes;
+  readonly users: BTreeMap<PalletCommonAccountBasicCrossAccountIdRepr, u128>;
+}
+
 /** @name UpDataStructsMetaUpdatePermission */
 export interface UpDataStructsMetaUpdatePermission extends Enum {
   readonly isItemOwner: boolean;