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

difftreelog

feat add ApproveForAll to Eth and Sub

Grigoriy Simonov2022-12-06parent: #e7f81f3.patch.diff
in: master

39 files changed

modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -246,6 +246,16 @@
 		token_id: TokenId,
 		at: Option<BlockHash>,
 	) -> Result<Option<String>>;
+
+	/// Get whether an operator is approved by a given owner.
+	#[method(name = "unique_isApprovedForAll")]
+	fn is_approved_for_all(
+		&self,
+		collection: CollectionId,
+		owner: CrossAccountId,
+		operator: CrossAccountId,
+		at: Option<BlockHash>,
+	) -> Result<bool>;
 }
 
 mod app_promotion_unique_rpc {
@@ -569,6 +579,7 @@
 	pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);
 	pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<String> => |o| o.map(|number| number.to_string()) , unique_api);
 	pass_method!(token_owners(collection: CollectionId, token: TokenId) -> Vec<CrossAccountId>, unique_api);
+	pass_method!(is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> bool, unique_api);
 }
 
 impl<C, Block, BlockNumber, CrossAccountId, AccountId>
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -472,6 +472,18 @@
 			u128,
 		),
 
+		/// Amount pieces of token owned by `sender` was approved for `spender`.
+		ApprovedForAll(
+			/// Id of collection to which item is belong.
+			CollectionId,
+			/// Owner of a wallet.
+			T::CrossAccountId,
+			/// Id for which operator status was granted or rewoked.
+			T::CrossAccountId,
+			/// Is operator status was granted or rewoked.
+			bool,
+		),
+
 		/// The colletion property has been added or edited.
 		CollectionPropertySet(
 			/// Id of collection to which property has been set.
@@ -1521,6 +1533,9 @@
 
 	/// The price of retrieving token owner
 	fn token_owner() -> Weight;
+
+	/// The price of setting approval for all
+	fn set_approval_for_all() -> Weight;
 }
 
 /// Weight info extension trait for refungible pallet.
@@ -1828,6 +1843,20 @@
 
 	/// Get extension for RFT collection.
 	fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>>;
+
+	/// An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// * `owner` - Token owner
+	/// * `operator` - Operator
+	/// * `approve` - Is operator enabled or disabled
+	fn set_approval_for_all(
+		&self,
+		owner: T::CrossAccountId,
+		operator: T::CrossAccountId,
+		approve: bool,
+	) -> DispatchResultWithPostInfo;
+
+	/// Tells whether an operator is approved by a given owner.
+	fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool;
 }
 
 /// Extension for RFT collection.
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -107,6 +107,10 @@
 	fn token_owner() -> Weight {
 		Weight::zero()
 	}
+
+	fn set_approval_for_all() -> Weight {
+		Weight::zero()
+	}
 }
 
 /// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete
@@ -424,4 +428,17 @@
 		}
 		<TotalSupply<T>>::try_get(self.id).ok()
 	}
+
+	fn set_approval_for_all(
+		&self,
+		_owner: T::CrossAccountId,
+		_operator: T::CrossAccountId,
+		_approve: bool,
+	) -> DispatchResultWithPostInfo {
+		fail!(<Error<T>>::SettingApprovalForAllNotAllowed)
+	}
+
+	fn is_approved_for_all(&self, _owner: T::CrossAccountId, _operator: T::CrossAccountId) -> bool {
+		false
+	}
 }
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -127,6 +127,8 @@
 		FungibleDisallowsNesting,
 		/// Setting item properties is not allowed.
 		SettingPropertiesNotAllowed,
+		/// Setting approval for all is not allowed.
+		SettingApprovalForAllNotAllowed,
 	}
 
 	#[pallet::config]
modifiedpallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -222,4 +222,18 @@
 		let item = create_max_item(&collection, &owner, owner.clone())?;
 
 	}: {collection.token_owner(item)}
+
+	set_approval_for_all {
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			operator: cross_from_sub(owner); owner: cross_sub;
+		};
+	}: {<Pallet<T>>::set_approval_for_all(&collection, &owner, &operator, true)}
+
+	is_approved_for_all {
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			operator: cross_from_sub(owner); owner: cross_sub;
+		};
+	}: {<Pallet<T>>::is_approved_for_all(&collection, &owner, &operator)}
 }
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -122,6 +122,10 @@
 	fn token_owner() -> Weight {
 		<SelfWeightOf<T>>::token_owner()
 	}
+
+	fn set_approval_for_all() -> Weight {
+		<SelfWeightOf<T>>::set_approval_for_all()
+	}
 }
 
 fn map_create_data<T: Config>(
@@ -512,4 +516,20 @@
 			None
 		}
 	}
+
+	fn set_approval_for_all(
+		&self,
+		owner: T::CrossAccountId,
+		operator: T::CrossAccountId,
+		approve: bool,
+	) -> DispatchResultWithPostInfo {
+		with_weight(
+			<Pallet<T>>::set_approval_for_all(self, &owner, &operator, approve),
+			<CommonWeights<T>>::set_approval_for_all(),
+		)
+	}
+
+	fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {
+		<Pallet<T>>::is_approved_for_all(self, &owner, &operator)
+	}
 }
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -469,15 +469,23 @@
 		Ok(())
 	}
 
-	/// @dev Not implemented
+	/// @notice Sets or unsets the approval of a given operator.
+	///  An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// @param operator Operator
+	/// @param approved Is operator enabled or disabled
+	#[weight(<SelfWeightOf<T>>::set_approval_for_all())]
 	fn set_approval_for_all(
 		&mut self,
-		_caller: caller,
-		_operator: address,
-		_approved: bool,
+		caller: caller,
+		operator: address,
+		approved: bool,
 	) -> Result<void> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
+		let caller = T::CrossAccountId::from_eth(caller);
+		let operator = T::CrossAccountId::from_eth(operator);
+
+		<Pallet<T>>::set_approval_for_all(self, &caller, &operator, approved)
+			.map_err(dispatch_to_evm::<T>)?;
+		Ok(())
 	}
 
 	/// @dev Not implemented
@@ -486,10 +494,13 @@
 		Err("not implemented".into())
 	}
 
-	/// @dev Not implemented
-	fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
+	/// @notice Tells whether an operator is approved by a given owner.
+	#[weight(<SelfWeightOf<T>>::is_approved_for_all())]
+	fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {
+		let owner = T::CrossAccountId::from_eth(owner);
+		let operator = T::CrossAccountId::from_eth(operator);
+
+		Ok(<Pallet<T>>::is_approved_for_all(self, &owner, &operator))
 	}
 
 	/// @notice Returns collection helper contract address
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -272,6 +272,18 @@
 		QueryKind = OptionQuery,
 	>;
 
+	/// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+	#[pallet::storage]
+	pub type WalletOperator<T: Config> = StorageNMap<
+		Key = (
+			Key<Twox64Concat, CollectionId>,
+			Key<Blake2_128Concat, T::CrossAccountId>,
+			Key<Blake2_128Concat, T::CrossAccountId>,
+		),
+		Value = bool,
+		QueryKind = OptionQuery,
+	>;
+
 	/// Upgrade from the old schema to properties.
 	#[pallet::hooks]
 	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
@@ -438,6 +450,7 @@
 		<TokensBurnt<T>>::remove(id);
 		let _ = <Allowance<T>>::clear_prefix((id,), u32::MAX, None);
 		let _ = <AccountBalance<T>>::clear_prefix((id,), u32::MAX, None);
+		let _ = <WalletOperator<T>>::clear_prefix((id,), u32::MAX, None);
 		Ok(())
 	}
 
@@ -1193,6 +1206,9 @@
 		if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {
 			return Ok(());
 		}
+		if <WalletOperator<T>>::get((collection.id, from, spender)) == Some(true) {
+			return Ok(());
+		}
 		ensure!(
 			collection.ignores_allowance(spender),
 			<CommonError<T>>::ApprovedValueTooLow
@@ -1326,4 +1342,52 @@
 	) -> DispatchResult {
 		Self::create_multiple_items(collection, sender, vec![data], nesting_budget)
 	}
+
+	/// Sets or unsets the approval of a given operator.
+	///
+	/// An operator is allowed to transfer all token pieces of the sender on their behalf.
+	/// - `owner`: Token owner
+	/// - `operator`: Operator
+	/// - `approve`: Is operator enabled or disabled
+	pub fn set_approval_for_all(
+		collection: &NonfungibleHandle<T>,
+		owner: &T::CrossAccountId,
+		operator: &T::CrossAccountId,
+		approve: bool,
+	) -> DispatchResult {
+		if collection.permissions.access() == AccessMode::AllowList {
+			collection.check_allowlist(owner)?;
+			collection.check_allowlist(operator)?;
+		}
+
+		<PalletCommon<T>>::ensure_correct_receiver(operator)?;
+
+		// =========
+
+		<WalletOperator<T>>::insert((collection.id, owner, operator), approve);
+		<PalletEvm<T>>::deposit_log(
+			ERC721Events::ApprovalForAll {
+				owner: *owner.as_eth(),
+				operator: *operator.as_eth(),
+				approved: approve,
+			}
+			.to_log(collection_id_to_address(collection.id)),
+		);
+		<PalletCommon<T>>::deposit_event(CommonEvent::ApprovedForAll(
+			collection.id,
+			owner.clone(),
+			operator.clone(),
+			approve,
+		));
+		Ok(())
+	}
+
+	/// Tells whether an operator is approved by a given owner.
+	pub fn is_approved_for_all(
+		collection: &NonfungibleHandle<T>,
+		owner: &T::CrossAccountId,
+		operator: &T::CrossAccountId,
+	) -> bool {
+		<WalletOperator<T>>::get((collection.id, owner, operator)).unwrap_or(false)
+	}
 }
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -1020,7 +1020,10 @@
 		dummy = 0;
 	}
 
-	/// @dev Not implemented
+	/// @notice Sets or unsets the approval of a given operator.
+	///  An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// @param operator Operator
+	/// @param approved Is operator enabled or disabled
 	/// @dev EVM selector for this function is: 0xa22cb465,
 	///  or in textual repr: setApprovalForAll(address,bool)
 	function setApprovalForAll(address operator, bool approved) public {
@@ -1040,15 +1043,15 @@
 		return 0x0000000000000000000000000000000000000000;
 	}
 
-	/// @dev Not implemented
+	/// @notice Tells whether an operator is approved by a given owner.
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
-	function isApprovedForAll(address owner, address operator) public view returns (address) {
+	function isApprovedForAll(address owner, address operator) public view returns (bool) {
 		require(false, stub_error);
 		owner;
 		operator;
 		dummy;
-		return 0x0000000000000000000000000000000000000000;
+		return false;
 	}
 
 	/// @notice Returns collection helper contract address
modifiedpallets/nonfungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -26,6 +26,7 @@
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
 #![allow(unused_imports)]
+#![allow(missing_docs)]
 #![allow(clippy::unnecessary_cast)]
 
 use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
@@ -47,6 +48,8 @@
 	fn set_token_properties(b: u32, ) -> Weight;
 	fn delete_token_properties(b: u32, ) -> Weight;
 	fn token_owner() -> Weight;
+	fn set_approval_for_all() -> Weight;
+	fn is_approved_for_all() -> Weight;
 }
 
 /// Weights for pallet_nonfungible using the Substrate node and recommended hardware.
@@ -195,6 +198,16 @@
 		Weight::from_ref_time(4_366_000)
 			.saturating_add(T::DbWeight::get().reads(1 as u64))
 	}
+	// Storage: Nonfungible WalletOperator (r:0 w:1)
+	fn set_approval_for_all() -> Weight {
+		Weight::from_ref_time(16_231_000 as u64)
+			.saturating_add(T::DbWeight::get().writes(1 as u64))
+	}
+	// Storage: Nonfungible WalletOperator (r:1 w:0)
+	fn is_approved_for_all() -> Weight {
+		Weight::from_ref_time(6_161_000 as u64)
+			.saturating_add(T::DbWeight::get().reads(1 as u64))
+	}
 }
 
 // For backwards compatibility and tests
@@ -342,4 +355,14 @@
 		Weight::from_ref_time(4_366_000)
 			.saturating_add(RocksDbWeight::get().reads(1 as u64))
 	}
+	// Storage: Nonfungible WalletOperator (r:0 w:1)
+	fn set_approval_for_all() -> Weight {
+		Weight::from_ref_time(16_231_000 as u64)
+			.saturating_add(RocksDbWeight::get().writes(1 as u64))
+	}
+	// Storage: Nonfungible WalletOperator (r:1 w:0)
+	fn is_approved_for_all() -> Weight {
+		Weight::from_ref_time(6_161_000 as u64)
+			.saturating_add(RocksDbWeight::get().reads(1 as u64))
+	}
 }
modifiedpallets/refungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -290,4 +290,18 @@
 		};
 		let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
 	}: {<Pallet<T>>::token_owner(collection.id, item)}
+
+	set_approval_for_all {
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			operator: cross_from_sub(owner); owner: cross_sub;
+		};
+	}: {<Pallet<T>>::set_approval_for_all(&collection, &owner, &operator, true)}
+
+	is_approved_for_all {
+		bench_init!{
+			owner: sub; collection: collection(owner);
+			operator: cross_from_sub(owner); owner: cross_sub;
+		};
+	}: {<Pallet<T>>::is_approved_for_all(&collection, &owner, &operator)}
 }
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -152,6 +152,10 @@
 	fn token_owner() -> Weight {
 		<SelfWeightOf<T>>::token_owner()
 	}
+
+	fn set_approval_for_all() -> Weight {
+		<SelfWeightOf<T>>::set_approval_for_all()
+	}
 }
 
 fn map_create_data<T: Config>(
@@ -516,6 +520,22 @@
 	fn total_pieces(&self, token: TokenId) -> Option<u128> {
 		<Pallet<T>>::total_pieces(self.id, token)
 	}
+
+	fn set_approval_for_all(
+		&self,
+		owner: T::CrossAccountId,
+		operator: T::CrossAccountId,
+		approve: bool,
+	) -> DispatchResultWithPostInfo {
+		with_weight(
+			<Pallet<T>>::set_approval_for_all(self, &owner, &operator, approve),
+			<CommonWeights<T>>::set_approval_for_all(),
+		)
+	}
+
+	fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {
+		<Pallet<T>>::is_approved_for_all(self, &owner, &operator)
+	}
 }
 
 impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -461,15 +461,23 @@
 		Err("not implemented".into())
 	}
 
-	/// @dev Not implemented
+	/// @notice Sets or unsets the approval of a given operator.
+	///  An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// @param operator Operator
+	/// @param approved Is operator enabled or disabled
+	#[weight(<SelfWeightOf<T>>::set_approval_for_all())]
 	fn set_approval_for_all(
 		&mut self,
-		_caller: caller,
-		_operator: address,
-		_approved: bool,
+		caller: caller,
+		operator: address,
+		approved: bool,
 	) -> Result<void> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
+		let caller = T::CrossAccountId::from_eth(caller);
+		let operator = T::CrossAccountId::from_eth(operator);
+
+		<Pallet<T>>::set_approval_for_all(self, &caller, &operator, approved)
+			.map_err(dispatch_to_evm::<T>)?;
+		Ok(())
 	}
 
 	/// @dev Not implemented
@@ -478,10 +486,13 @@
 		Err("not implemented".into())
 	}
 
-	/// @dev Not implemented
-	fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
+	/// @notice Tells whether an operator is approved by a given owner.
+	#[weight(<SelfWeightOf<T>>::is_approved_for_all())]
+	fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {
+		let owner = T::CrossAccountId::from_eth(owner);
+		let operator = T::CrossAccountId::from_eth(operator);
+
+		Ok(<Pallet<T>>::is_approved_for_all(self, &owner, &operator))
 	}
 
 	/// @notice Returns collection helper contract address
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -273,6 +273,18 @@
 		QueryKind = ValueQuery,
 	>;
 
+	/// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+	#[pallet::storage]
+	pub type WalletOperator<T: Config> = StorageNMap<
+		Key = (
+			Key<Twox64Concat, CollectionId>,
+			Key<Blake2_128Concat, T::CrossAccountId>,
+			Key<Blake2_128Concat, T::CrossAccountId>,
+		),
+		Value = bool,
+		QueryKind = OptionQuery,
+	>;
+
 	#[pallet::hooks]
 	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
 		fn on_runtime_upgrade() -> Weight {
@@ -1161,6 +1173,12 @@
 		}
 		let allowance =
 			<Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
+
+		// Allowance if any would be reduced if spender is also wallet operator
+		if <WalletOperator<T>>::get((collection.id, from, spender)) == Some(true) {
+			return Ok(allowance);
+		}
+
 		if allowance.is_none() {
 			ensure!(
 				collection.ignores_allowance(spender),
@@ -1387,4 +1405,52 @@
 			Some(res)
 		}
 	}
+
+	/// Sets or unsets the approval of a given operator.
+	///
+	/// An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// - `owner`: Token owner
+	/// - `operator`: Operator
+	/// - `approve`: Is operator enabled or disabled
+	pub fn set_approval_for_all(
+		collection: &RefungibleHandle<T>,
+		owner: &T::CrossAccountId,
+		operator: &T::CrossAccountId,
+		approve: bool,
+	) -> DispatchResult {
+		if collection.permissions.access() == AccessMode::AllowList {
+			collection.check_allowlist(owner)?;
+			collection.check_allowlist(operator)?;
+		}
+
+		<PalletCommon<T>>::ensure_correct_receiver(operator)?;
+
+		// =========
+
+		<WalletOperator<T>>::insert((collection.id, owner, operator), approve);
+		<PalletEvm<T>>::deposit_log(
+			ERC721Events::ApprovalForAll {
+				owner: *owner.as_eth(),
+				operator: *operator.as_eth(),
+				approved: approve,
+			}
+			.to_log(collection_id_to_address(collection.id)),
+		);
+		<PalletCommon<T>>::deposit_event(CommonEvent::ApprovedForAll(
+			collection.id,
+			owner.clone(),
+			operator.clone(),
+			approve,
+		));
+		Ok(())
+	}
+
+	/// Tells whether an operator is approved by a given owner.
+	pub fn is_approved_for_all(
+		collection: &RefungibleHandle<T>,
+		owner: &T::CrossAccountId,
+		operator: &T::CrossAccountId,
+	) -> bool {
+		<WalletOperator<T>>::get((collection.id, owner, operator)).unwrap_or(false)
+	}
 }
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -1017,7 +1017,10 @@
 		dummy = 0;
 	}
 
-	/// @dev Not implemented
+	/// @notice Sets or unsets the approval of a given operator.
+	///  An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// @param operator Operator
+	/// @param approved Is operator enabled or disabled
 	/// @dev EVM selector for this function is: 0xa22cb465,
 	///  or in textual repr: setApprovalForAll(address,bool)
 	function setApprovalForAll(address operator, bool approved) public {
@@ -1037,15 +1040,15 @@
 		return 0x0000000000000000000000000000000000000000;
 	}
 
-	/// @dev Not implemented
+	/// @notice Tells whether an operator is approved by a given owner.
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
-	function isApprovedForAll(address owner, address operator) public view returns (address) {
+	function isApprovedForAll(address owner, address operator) public view returns (bool) {
 		require(false, stub_error);
 		owner;
 		operator;
 		dummy;
-		return 0x0000000000000000000000000000000000000000;
+		return false;
 	}
 
 	/// @notice Returns collection helper contract address
modifiedpallets/refungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/refungible/src/weights.rs
+++ b/pallets/refungible/src/weights.rs
@@ -3,7 +3,7 @@
 //! Autogenerated weights for pallet_refungible
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2022-11-25, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
 
 // Executed Command:
@@ -26,6 +26,7 @@
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
 #![allow(unused_imports)]
+#![allow(missing_docs)]
 #![allow(clippy::unnecessary_cast)]
 
 use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
@@ -54,6 +55,8 @@
 	fn delete_token_properties(b: u32, ) -> Weight;
 	fn repartition_item() -> Weight;
 	fn token_owner() -> Weight;
+	fn set_approval_for_all() -> Weight;
+	fn is_approved_for_all() -> Weight;
 }
 
 /// Weights for pallet_refungible using the Substrate node and recommended hardware.
@@ -259,6 +262,16 @@
 		Weight::from_ref_time(9_431_000)
 			.saturating_add(T::DbWeight::get().reads(2 as u64))
 	}
+	// Storage: Refungible WalletOperator (r:0 w:1)
+	fn set_approval_for_all() -> Weight {
+		Weight::from_ref_time(16_150_000 as u64)
+			.saturating_add(T::DbWeight::get().writes(1 as u64))
+	}
+	// Storage: Refungible WalletOperator (r:1 w:0)
+	fn is_approved_for_all() -> Weight {
+		Weight::from_ref_time(5_901_000 as u64)
+			.saturating_add(T::DbWeight::get().reads(1 as u64))
+	}
 }
 
 // For backwards compatibility and tests
@@ -463,4 +476,14 @@
 		Weight::from_ref_time(9_431_000)
 			.saturating_add(RocksDbWeight::get().reads(2 as u64))
 	}
+	// Storage: Refungible WalletOperator (r:0 w:1)
+	fn set_approval_for_all() -> Weight {
+		Weight::from_ref_time(16_150_000 as u64)
+			.saturating_add(RocksDbWeight::get().writes(1 as u64))
+	}
+	// Storage: Refungible WalletOperator (r:1 w:0)
+	fn is_approved_for_all() -> Weight {
+		Weight::from_ref_time(5_901_000 as u64)
+			.saturating_add(RocksDbWeight::get().reads(1 as u64))
+	}
 }
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -1126,6 +1126,28 @@
 				}
 			})
 		}
+
+		/// Sets or unsets the approval of a given operator.
+		///
+		/// An operator is allowed to transfer all tokens of the sender on their behalf.
+		///
+		/// # Arguments
+		///
+		/// * `owner`: Token owner
+		/// * `operator`: Operator
+		/// * `approve`: Is operator enabled or disabled
+		#[weight = T::CommonWeightInfo::set_approval_for_all()]
+		pub fn set_approval_for_all(
+			origin,
+			collection_id: CollectionId,
+			operator: T::CrossAccountId,
+			approve: bool,
+		) -> DispatchResultWithPostInfo {
+			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
+			dispatch_tx::<T, _>(collection_id, |d| {
+				d.set_approval_for_all(sender, operator, approve)
+			})
+		}
 	}
 }
 
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -132,5 +132,8 @@
 		fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;
 
 		fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;
+
+		/// Get whether an operator is approved by a given owner.
+		fn is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> Result<bool>;
 	}
 }
modifiedruntime/common/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -187,6 +187,10 @@
                 fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
                     dispatch_unique_runtime!(collection.total_pieces(token_id))
                 }
+
+		        fn is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> Result<bool, DispatchError> {
+                    dispatch_unique_runtime!(collection.is_approved_for_all(owner, operator))
+                }
             }
 
             impl app_promotion_rpc::AppPromotionApi<Block, BlockNumber, CrossAccountId, AccountId> for Runtime {
modifiedruntime/common/weights.rsdiffbeforeafterboth
--- a/runtime/common/weights.rs
+++ b/runtime/common/weights.rs
@@ -120,6 +120,10 @@
 	fn token_owner() -> Weight {
 		max_weight_of!(token_owner())
 	}
+
+	fn set_approval_for_all() -> Weight {
+		max_weight_of!(set_approval_for_all())
+	}
 }
 
 #[cfg(feature = "refungible")]
modifiedtests/src/approve.test.tsdiffbeforeafterboth
--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -603,3 +603,40 @@
     await expect(approveTx()).to.be.rejected;
   });
 });
+
+describe('Normal user can approve other users to be wallet operator:', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = await privateKey({filename: __filename});
+      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);
+    });
+  });
+
+  itSub('[nft] Enable and disable approval', async ({helper}) => {
+    const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+    await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+    const checkBeforeApprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+    expect(await checkBeforeApprovalTx()).to.be.false;
+    await helper.nft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, true);
+    const checkAfterApprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+    expect(await checkAfterApprovalTx()).to.be.true;
+    await helper.nft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, false);
+    const checkAfterDisapprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+    expect(await checkAfterDisapprovalTx()).to.be.false;
+  });
+
+  itSub.ifWithPallets('[rft] Enable and disable approval', [Pallets.ReFungible], async ({helper}) => {
+    const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+    const checkBeforeApprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+    expect(await checkBeforeApprovalTx()).to.be.false;
+    await helper.rft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, true);
+    const checkAfterApprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+    expect(await checkAfterApprovalTx()).to.be.true;
+    await helper.rft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, false);
+    const checkAfterDisapprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+    expect(await checkAfterDisapprovalTx()).to.be.false;
+  });
+});
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -384,7 +384,7 @@
       { "internalType": "address", "name": "operator", "type": "address" }
     ],
     "name": "isApprovedForAll",
-    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
     "stateMutability": "view",
     "type": "function"
   },
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -366,7 +366,7 @@
       { "internalType": "address", "name": "operator", "type": "address" }
     ],
     "name": "isApprovedForAll",
-    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
     "stateMutability": "view",
     "type": "function"
   },
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -671,7 +671,10 @@
 	///  or in textual repr: approve(address,uint256)
 	function approve(address approved, uint256 tokenId) external;
 
-	/// @dev Not implemented
+	/// @notice Sets or unsets the approval of a given operator.
+	///  An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// @param operator Operator
+	/// @param approved Is operator enabled or disabled
 	/// @dev EVM selector for this function is: 0xa22cb465,
 	///  or in textual repr: setApprovalForAll(address,bool)
 	function setApprovalForAll(address operator, bool approved) external;
@@ -681,10 +684,10 @@
 	///  or in textual repr: getApproved(uint256)
 	function getApproved(uint256 tokenId) external view returns (address);
 
-	/// @dev Not implemented
+	/// @notice Tells whether an operator is approved by a given owner.
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
-	function isApprovedForAll(address owner, address operator) external view returns (address);
+	function isApprovedForAll(address owner, address operator) external view returns (bool);
 
 	/// @notice Returns collection helper contract address
 	/// @dev EVM selector for this function is: 0x1896cce6,
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -668,7 +668,10 @@
 	///  or in textual repr: approve(address,uint256)
 	function approve(address approved, uint256 tokenId) external;
 
-	/// @dev Not implemented
+	/// @notice Sets or unsets the approval of a given operator.
+	///  An operator is allowed to transfer all tokens of the sender on their behalf.
+	/// @param operator Operator
+	/// @param approved Is operator enabled or disabled
 	/// @dev EVM selector for this function is: 0xa22cb465,
 	///  or in textual repr: setApprovalForAll(address,bool)
 	function setApprovalForAll(address operator, bool approved) external;
@@ -678,10 +681,10 @@
 	///  or in textual repr: getApproved(uint256)
 	function getApproved(uint256 tokenId) external view returns (address);
 
-	/// @dev Not implemented
+	/// @notice Tells whether an operator is approved by a given owner.
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
-	function isApprovedForAll(address owner, address operator) external view returns (address);
+	function isApprovedForAll(address owner, address operator) external view returns (bool);
 
 	/// @notice Returns collection helper contract address
 	/// @dev EVM selector for this function is: 0x1896cce6,
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -249,6 +249,114 @@
     }
   });
 
+  itEth('Can perform setApprovalForAll()', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = helper.eth.createAccount();
+
+    const collection = await helper.nft.mintCollection(minter, {});
+
+    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+    const approvedBefore = await contract.methods.isApprovedForAll(owner, operator).call();
+    expect(approvedBefore).to.be.equal(false);
+
+    {
+      const result = await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+
+      expect(result.events.ApprovalForAll).to.be.like({
+        address: collectionAddress,
+        event: 'ApprovalForAll',
+        returnValues: {
+          owner,
+          operator,
+          approved: true,
+        },
+      });
+
+      const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+      expect(approvedAfter).to.be.equal(true);
+    }
+
+    {
+      const result = await contract.methods.setApprovalForAll(operator, false).send({from: owner});
+
+      expect(result.events.ApprovalForAll).to.be.like({
+        address: collectionAddress,
+        event: 'ApprovalForAll',
+        returnValues: {
+          owner,
+          operator,
+          approved: false,
+        },
+      });
+
+      const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+      expect(approvedAfter).to.be.equal(false);
+    }
+  });
+
+  itEth('Can perform burn with ApprovalForAll', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'nft');
+
+    {
+      await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: operator});
+      const events = result.events.Transfer;
+
+      expect(events).to.be.like({
+        address,
+        event: 'Transfer',
+        returnValues: {
+          from: owner,
+          to: '0x0000000000000000000000000000000000000000',
+          tokenId: token.tokenId.toString(),
+        },
+      });
+    }
+  });
+  
+  itEth('Can perform transfer with ApprovalForAll', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = await helper.eth.createAccountWithBalance(donor);
+    const receiver = charlie;
+
+    const token = await collection.mintToken(minter, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'nft');
+
+    {
+      await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+      const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: operator});
+      const event = result.events.Transfer;
+      expect(event).to.be.like({
+        address: helper.ethAddress.fromCollectionId(collection.collectionId),
+        event: 'Transfer',
+        returnValues: {
+          from: owner,
+          to: helper.address.substrateToEth(receiver.address),
+          tokenId: token.tokenId.toString(),
+        },
+      });
+    }
+
+    expect(await token.getOwner()).to.be.like({Substrate: receiver.address});
+  });
+
   itEth('Can perform burnFromCross()', async ({helper}) => {
     const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
     const ownerSub = bob;
@@ -822,3 +930,53 @@
     expect(symbol).to.equal('CHANGE');
   });
 });
+
+describe('Negative tests', () => {
+  let donor: IKeyringPair;
+  let minter: IKeyringPair;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (helper, privateKey) => {
+      donor = await privateKey({filename: __filename});
+      [minter, alice, bob] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
+    });
+  });
+
+  itEth('[negative] Cant perform burn without approval', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = bob;
+    const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, {Substrate: owner.address});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'nft');
+
+    {
+      const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
+      await expect(contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender})).to.be.rejected;
+    }
+  });
+
+  itEth('[negative] Cant perform transfer without approval', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+    const owner = bob;
+    const receiver = alice;
+
+    const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, {Substrate: owner.address});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'nft');
+
+    {
+      const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
+      const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+      await expect(contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender})).to.be.rejected;
+    }
+  });
+});
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -169,6 +169,136 @@
     }
   });
 
+  itEth('Can perform setApprovalForAll()', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = helper.eth.createAccount();
+
+    const collection = await helper.rft.mintCollection(minter, {});
+
+    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
+    const approvedBefore = await contract.methods.isApprovedForAll(owner, operator).call();
+    expect(approvedBefore).to.be.equal(false);
+
+    {
+      const result = await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+
+      expect(result.events.ApprovalForAll).to.be.like({
+        address: collectionAddress,
+        event: 'ApprovalForAll',
+        returnValues: {
+          owner,
+          operator,
+          approved: true,
+        },
+      });
+
+      const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+      expect(approvedAfter).to.be.equal(true);
+    }
+
+    {
+      const result = await contract.methods.setApprovalForAll(operator, false).send({from: owner});
+
+      expect(result.events.ApprovalForAll).to.be.like({
+        address: collectionAddress,
+        event: 'ApprovalForAll',
+        returnValues: {
+          owner,
+          operator,
+          approved: false,
+        },
+      });
+
+      const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+      expect(approvedAfter).to.be.equal(false);
+    }
+  });
+
+  itEth('Can perform burn with ApprovalForAll', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'rft');
+
+    {
+      await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: operator});
+      const events = result.events.Transfer;
+
+      expect(events).to.be.like({
+        address,
+        event: 'Transfer',
+        returnValues: {
+          from: owner,
+          to: '0x0000000000000000000000000000000000000000',
+          tokenId: token.tokenId.toString(),
+        },
+      });
+    }
+  });
+
+  itEth('Can perform burn with approve and approvalForAll', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'rft');
+
+    const rftToken = helper.ethNativeContract.rftTokenById(token.collectionId, token.tokenId, owner);
+
+    {
+      await rftToken.methods.approve(operator, 15n).send({from: owner});
+      await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+      await rftToken.methods.burnFrom(owner, 10n).send({from: operator});
+      const allowance = await rftToken.methods.allowance(owner, operator).call();
+      expect(allowance).to.be.equal('5');
+    }
+  });
+  
+  itEth('Can perform transfer with ApprovalForAll', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const operator = await helper.eth.createAccountWithBalance(donor);
+    const receiver = charlie;
+
+    const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'rft');
+
+    {
+      await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+      const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: operator});
+      const event = result.events.Transfer;
+      expect(event).to.be.like({
+        address: helper.ethAddress.fromCollectionId(collection.collectionId),
+        event: 'Transfer',
+        returnValues: {
+          from: owner,
+          to: helper.address.substrateToEth(receiver.address),
+          tokenId: token.tokenId.toString(),
+        },
+      });
+    }
+
+    expect(await token.getTop10Owners()).to.be.like([{Substrate: receiver.address}]);
+  });
+
   itEth('Can perform burn()', async ({helper}) => {
     const caller = await helper.eth.createAccountWithBalance(donor);
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Burny', '6', '6');
@@ -594,3 +724,52 @@
     expect(symbol).to.equal('12');
   });
 });
+
+describe('Negative tests', () => {
+  let donor: IKeyringPair;
+  let minter: IKeyringPair;
+  let alice: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (helper, privateKey) => {
+      donor = await privateKey({filename: __filename});
+      [minter, alice] = await helper.arrange.createAccounts([100n, 100n], donor);
+    });
+  });
+
+  itEth('[negative] Cant perform burn without approval', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor, 100n);
+    const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'rft');
+
+    {
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      await expect(contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender})).to.be.rejected;
+    }
+  });
+
+  itEth('[negative] Cant perform transfer without approval', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+    const owner = await helper.eth.createAccountWithBalance(donor, 100n);
+    const receiver = alice;
+
+    const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+    const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'rft');
+
+    {
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+      await expect(contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender})).to.be.rejected;
+    }
+  });
+});
modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -386,6 +386,10 @@
        **/
       NotFungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;
       /**
+       * Setting approval for all is not allowed.
+       **/
+      SettingApprovalForAllNotAllowed: AugmentedError<ApiType>;
+      /**
        * Setting item properties is not allowed.
        **/
       SettingPropertiesNotAllowed: AugmentedError<ApiType>;
modifiedtests/src/interfaces/augment-api-events.tsdiffbeforeafterboth
before · tests/src/interfaces/augment-api-events.ts
1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */34// import type lookup before we augment - in some environments5// this is required to allow for ambient/previous definitions6import '@polkadot/api-base/types/events';78import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types';9import type { Bytes, Null, Option, Result, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';10import type { ITuple } from '@polkadot/types-codec/types';11import type { AccountId32, H160, H256, Weight } from '@polkadot/types/interfaces/runtime';12import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, PalletForeignAssetsAssetIds, PalletForeignAssetsModuleAssetMetadata, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetMultiAssets, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';1314export type __AugmentedEvent<ApiType extends ApiTypes> = AugmentedEvent<ApiType>;1516declare module '@polkadot/api-base/types/events' {17  interface AugmentedEvents<ApiType extends ApiTypes> {18    appPromotion: {19      /**20       * The admin was set21       * 22       * # Arguments23       * * AccountId: account address of the admin24       **/25      SetAdmin: AugmentedEvent<ApiType, [AccountId32]>;26      /**27       * Staking was performed28       * 29       * # Arguments30       * * AccountId: account of the staker31       * * Balance : staking amount32       **/33      Stake: AugmentedEvent<ApiType, [AccountId32, u128]>;34      /**35       * Staking recalculation was performed36       * 37       * # Arguments38       * * AccountId: account of the staker.39       * * Balance : recalculation base40       * * Balance : total income41       **/42      StakingRecalculation: AugmentedEvent<ApiType, [AccountId32, u128, u128]>;43      /**44       * Unstaking was performed45       * 46       * # Arguments47       * * AccountId: account of the staker48       * * Balance : unstaking amount49       **/50      Unstake: AugmentedEvent<ApiType, [AccountId32, u128]>;51      /**52       * Generic event53       **/54      [key: string]: AugmentedEvent<ApiType>;55    };56    balances: {57      /**58       * A balance was set by root.59       **/60      BalanceSet: AugmentedEvent<ApiType, [who: AccountId32, free: u128, reserved: u128], { who: AccountId32, free: u128, reserved: u128 }>;61      /**62       * Some amount was deposited (e.g. for transaction fees).63       **/64      Deposit: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;65      /**66       * An account was removed whose balance was non-zero but below ExistentialDeposit,67       * resulting in an outright loss.68       **/69      DustLost: AugmentedEvent<ApiType, [account: AccountId32, amount: u128], { account: AccountId32, amount: u128 }>;70      /**71       * An account was created with some free balance.72       **/73      Endowed: AugmentedEvent<ApiType, [account: AccountId32, freeBalance: u128], { account: AccountId32, freeBalance: u128 }>;74      /**75       * Some balance was reserved (moved from free to reserved).76       **/77      Reserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;78      /**79       * Some balance was moved from the reserve of the first account to the second account.80       * Final argument indicates the destination balance type.81       **/82      ReserveRepatriated: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus], { from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus }>;83      /**84       * Some amount was removed from the account (e.g. for misbehavior).85       **/86      Slashed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;87      /**88       * Transfer succeeded.89       **/90      Transfer: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128], { from: AccountId32, to: AccountId32, amount: u128 }>;91      /**92       * Some balance was unreserved (moved from reserved to free).93       **/94      Unreserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;95      /**96       * Some amount was withdrawn from the account (e.g. for transaction fees).97       **/98      Withdraw: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;99      /**100       * Generic event101       **/102      [key: string]: AugmentedEvent<ApiType>;103    };104    common: {105      /**106       * Amount pieces of token owned by `sender` was approved for `spender`.107       **/108      Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;109      /**110       * New collection was created111       **/112      CollectionCreated: AugmentedEvent<ApiType, [u32, u8, AccountId32]>;113      /**114       * New collection was destroyed115       **/116      CollectionDestroyed: AugmentedEvent<ApiType, [u32]>;117      /**118       * The property has been deleted.119       **/120      CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;121      /**122       * The colletion property has been added or edited.123       **/124      CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;125      /**126       * New item was created.127       **/128      ItemCreated: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;129      /**130       * Collection item was burned.131       **/132      ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;133      /**134       * The token property permission of a collection has been set.135       **/136      PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;137      /**138       * The token property has been deleted.139       **/140      TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;141      /**142       * The token property has been added or edited.143       **/144      TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;145      /**146       * Item was transferred147       **/148      Transfer: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;149      /**150       * Generic event151       **/152      [key: string]: AugmentedEvent<ApiType>;153    };154    cumulusXcm: {155      /**156       * Downward message executed with the given outcome.157       * \[ id, outcome \]158       **/159      ExecutedDownward: AugmentedEvent<ApiType, [U8aFixed, XcmV2TraitsOutcome]>;160      /**161       * Downward message is invalid XCM.162       * \[ id \]163       **/164      InvalidFormat: AugmentedEvent<ApiType, [U8aFixed]>;165      /**166       * Downward message is unsupported version of XCM.167       * \[ id \]168       **/169      UnsupportedVersion: AugmentedEvent<ApiType, [U8aFixed]>;170      /**171       * Generic event172       **/173      [key: string]: AugmentedEvent<ApiType>;174    };175    dmpQueue: {176      /**177       * Downward message executed with the given outcome.178       **/179      ExecutedDownward: AugmentedEvent<ApiType, [messageId: U8aFixed, outcome: XcmV2TraitsOutcome], { messageId: U8aFixed, outcome: XcmV2TraitsOutcome }>;180      /**181       * Downward message is invalid XCM.182       **/183      InvalidFormat: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;184      /**185       * Downward message is overweight and was placed in the overweight queue.186       **/187      OverweightEnqueued: AugmentedEvent<ApiType, [messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight], { messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight }>;188      /**189       * Downward message from the overweight queue was executed.190       **/191      OverweightServiced: AugmentedEvent<ApiType, [overweightIndex: u64, weightUsed: Weight], { overweightIndex: u64, weightUsed: Weight }>;192      /**193       * Downward message is unsupported version of XCM.194       **/195      UnsupportedVersion: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;196      /**197       * The weight limit for handling downward messages was reached.198       **/199      WeightExhausted: AugmentedEvent<ApiType, [messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight], { messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight }>;200      /**201       * Generic event202       **/203      [key: string]: AugmentedEvent<ApiType>;204    };205    ethereum: {206      /**207       * An ethereum transaction was successfully executed.208       **/209      Executed: AugmentedEvent<ApiType, [from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason], { from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason }>;210      /**211       * Generic event212       **/213      [key: string]: AugmentedEvent<ApiType>;214    };215    evm: {216      /**217       * A contract has been created at given address.218       **/219      Created: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;220      /**221       * A contract was attempted to be created, but the execution failed.222       **/223      CreatedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;224      /**225       * A contract has been executed successfully with states applied.226       **/227      Executed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;228      /**229       * A contract has been executed with errors. States are reverted with only gas fees applied.230       **/231      ExecutedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;232      /**233       * Ethereum events from contracts.234       **/235      Log: AugmentedEvent<ApiType, [log: EthereumLog], { log: EthereumLog }>;236      /**237       * Generic event238       **/239      [key: string]: AugmentedEvent<ApiType>;240    };241    evmContractHelpers: {242      /**243       * Collection sponsor was removed.244       **/245      ContractSponsorRemoved: AugmentedEvent<ApiType, [H160]>;246      /**247       * Contract sponsor was set.248       **/249      ContractSponsorSet: AugmentedEvent<ApiType, [H160, AccountId32]>;250      /**251       * New sponsor was confirm.252       **/253      ContractSponsorshipConfirmed: AugmentedEvent<ApiType, [H160, AccountId32]>;254      /**255       * Generic event256       **/257      [key: string]: AugmentedEvent<ApiType>;258    };259    evmMigration: {260      /**261       * This event is used in benchmarking and can be used for tests262       **/263      TestEvent: AugmentedEvent<ApiType, []>;264      /**265       * Generic event266       **/267      [key: string]: AugmentedEvent<ApiType>;268    };269    foreignAssets: {270      /**271       * The asset registered.272       **/273      AssetRegistered: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;274      /**275       * The asset updated.276       **/277      AssetUpdated: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;278      /**279       * The foreign asset registered.280       **/281      ForeignAssetRegistered: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;282      /**283       * The foreign asset updated.284       **/285      ForeignAssetUpdated: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;286      /**287       * Generic event288       **/289      [key: string]: AugmentedEvent<ApiType>;290    };291    maintenance: {292      MaintenanceDisabled: AugmentedEvent<ApiType, []>;293      MaintenanceEnabled: AugmentedEvent<ApiType, []>;294      /**295       * Generic event296       **/297      [key: string]: AugmentedEvent<ApiType>;298    };299    parachainSystem: {300      /**301       * Downward messages were processed using the given weight.302       **/303      DownwardMessagesProcessed: AugmentedEvent<ApiType, [weightUsed: Weight, dmqHead: H256], { weightUsed: Weight, dmqHead: H256 }>;304      /**305       * Some downward messages have been received and will be processed.306       **/307      DownwardMessagesReceived: AugmentedEvent<ApiType, [count: u32], { count: u32 }>;308      /**309       * An upgrade has been authorized.310       **/311      UpgradeAuthorized: AugmentedEvent<ApiType, [codeHash: H256], { codeHash: H256 }>;312      /**313       * The validation function was applied as of the contained relay chain block number.314       **/315      ValidationFunctionApplied: AugmentedEvent<ApiType, [relayChainBlockNum: u32], { relayChainBlockNum: u32 }>;316      /**317       * The relay-chain aborted the upgrade process.318       **/319      ValidationFunctionDiscarded: AugmentedEvent<ApiType, []>;320      /**321       * The validation function has been scheduled to apply.322       **/323      ValidationFunctionStored: AugmentedEvent<ApiType, []>;324      /**325       * Generic event326       **/327      [key: string]: AugmentedEvent<ApiType>;328    };329    polkadotXcm: {330      /**331       * Some assets have been placed in an asset trap.332       * 333       * \[ hash, origin, assets \]334       **/335      AssetsTrapped: AugmentedEvent<ApiType, [H256, XcmV1MultiLocation, XcmVersionedMultiAssets]>;336      /**337       * Execution of an XCM message was attempted.338       * 339       * \[ outcome \]340       **/341      Attempted: AugmentedEvent<ApiType, [XcmV2TraitsOutcome]>;342      /**343       * Expected query response has been received but the origin location of the response does344       * not match that expected. The query remains registered for a later, valid, response to345       * be received and acted upon.346       * 347       * \[ origin location, id, expected location \]348       **/349      InvalidResponder: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, Option<XcmV1MultiLocation>]>;350      /**351       * Expected query response has been received but the expected origin location placed in352       * storage by this runtime previously cannot be decoded. The query remains registered.353       * 354       * This is unexpected (since a location placed in storage in a previously executing355       * runtime should be readable prior to query timeout) and dangerous since the possibly356       * valid response will be dropped. Manual governance intervention is probably going to be357       * needed.358       * 359       * \[ origin location, id \]360       **/361      InvalidResponderVersion: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;362      /**363       * Query response has been received and query is removed. The registered notification has364       * been dispatched and executed successfully.365       * 366       * \[ id, pallet index, call index \]367       **/368      Notified: AugmentedEvent<ApiType, [u64, u8, u8]>;369      /**370       * Query response has been received and query is removed. The dispatch was unable to be371       * decoded into a `Call`; this might be due to dispatch function having a signature which372       * is not `(origin, QueryId, Response)`.373       * 374       * \[ id, pallet index, call index \]375       **/376      NotifyDecodeFailed: AugmentedEvent<ApiType, [u64, u8, u8]>;377      /**378       * Query response has been received and query is removed. There was a general error with379       * dispatching the notification call.380       * 381       * \[ id, pallet index, call index \]382       **/383      NotifyDispatchError: AugmentedEvent<ApiType, [u64, u8, u8]>;384      /**385       * Query response has been received and query is removed. The registered notification could386       * not be dispatched because the dispatch weight is greater than the maximum weight387       * originally budgeted by this runtime for the query result.388       * 389       * \[ id, pallet index, call index, actual weight, max budgeted weight \]390       **/391      NotifyOverweight: AugmentedEvent<ApiType, [u64, u8, u8, Weight, Weight]>;392      /**393       * A given location which had a version change subscription was dropped owing to an error394       * migrating the location to our new XCM format.395       * 396       * \[ location, query ID \]397       **/398      NotifyTargetMigrationFail: AugmentedEvent<ApiType, [XcmVersionedMultiLocation, u64]>;399      /**400       * A given location which had a version change subscription was dropped owing to an error401       * sending the notification to it.402       * 403       * \[ location, query ID, error \]404       **/405      NotifyTargetSendFail: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, XcmV2TraitsError]>;406      /**407       * Query response has been received and is ready for taking with `take_response`. There is408       * no registered notification call.409       * 410       * \[ id, response \]411       **/412      ResponseReady: AugmentedEvent<ApiType, [u64, XcmV2Response]>;413      /**414       * Received query response has been read and removed.415       * 416       * \[ id \]417       **/418      ResponseTaken: AugmentedEvent<ApiType, [u64]>;419      /**420       * A XCM message was sent.421       * 422       * \[ origin, destination, message \]423       **/424      Sent: AugmentedEvent<ApiType, [XcmV1MultiLocation, XcmV1MultiLocation, XcmV2Xcm]>;425      /**426       * The supported version of a location has been changed. This might be through an427       * automatic notification or a manual intervention.428       * 429       * \[ location, XCM version \]430       **/431      SupportedVersionChanged: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;432      /**433       * Query response received which does not match a registered query. This may be because a434       * matching query was never registered, it may be because it is a duplicate response, or435       * because the query timed out.436       * 437       * \[ origin location, id \]438       **/439      UnexpectedResponse: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;440      /**441       * An XCM version change notification message has been attempted to be sent.442       * 443       * \[ destination, result \]444       **/445      VersionChangeNotified: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;446      /**447       * Generic event448       **/449      [key: string]: AugmentedEvent<ApiType>;450    };451    rmrkCore: {452      CollectionCreated: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;453      CollectionDestroyed: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;454      CollectionLocked: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;455      IssuerChanged: AugmentedEvent<ApiType, [oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32], { oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32 }>;456      NFTAccepted: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32 }>;457      NFTBurned: AugmentedEvent<ApiType, [owner: AccountId32, nftId: u32], { owner: AccountId32, nftId: u32 }>;458      NftMinted: AugmentedEvent<ApiType, [owner: AccountId32, collectionId: u32, nftId: u32], { owner: AccountId32, collectionId: u32, nftId: u32 }>;459      NFTRejected: AugmentedEvent<ApiType, [sender: AccountId32, collectionId: u32, nftId: u32], { sender: AccountId32, collectionId: u32, nftId: u32 }>;460      NFTSent: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool }>;461      PrioritySet: AugmentedEvent<ApiType, [collectionId: u32, nftId: u32], { collectionId: u32, nftId: u32 }>;462      PropertySet: AugmentedEvent<ApiType, [collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes], { collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes }>;463      ResourceAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;464      ResourceAdded: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;465      ResourceRemoval: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;466      ResourceRemovalAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;467      /**468       * Generic event469       **/470      [key: string]: AugmentedEvent<ApiType>;471    };472    rmrkEquip: {473      BaseCreated: AugmentedEvent<ApiType, [issuer: AccountId32, baseId: u32], { issuer: AccountId32, baseId: u32 }>;474      EquippablesUpdated: AugmentedEvent<ApiType, [baseId: u32, slotId: u32], { baseId: u32, slotId: u32 }>;475      /**476       * Generic event477       **/478      [key: string]: AugmentedEvent<ApiType>;479    };480    scheduler: {481      /**482       * The call for the provided hash was not found so the task has been aborted.483       **/484      CallUnavailable: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;485      /**486       * Canceled some task.487       **/488      Canceled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;489      /**490       * Dispatched some task.491       **/492      Dispatched: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError> }>;493      /**494       * The given task can never be executed since it is overweight.495       **/496      PermanentlyOverweight: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;497      /**498       * Scheduled task's priority has changed499       **/500      PriorityChanged: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, priority: u8], { task: ITuple<[u32, u32]>, priority: u8 }>;501      /**502       * Scheduled some task.503       **/504      Scheduled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;505      /**506       * Generic event507       **/508      [key: string]: AugmentedEvent<ApiType>;509    };510    structure: {511      /**512       * Executed call on behalf of the token.513       **/514      Executed: AugmentedEvent<ApiType, [Result<Null, SpRuntimeDispatchError>]>;515      /**516       * Generic event517       **/518      [key: string]: AugmentedEvent<ApiType>;519    };520    sudo: {521      /**522       * The \[sudoer\] just switched identity; the old key is supplied if one existed.523       **/524      KeyChanged: AugmentedEvent<ApiType, [oldSudoer: Option<AccountId32>], { oldSudoer: Option<AccountId32> }>;525      /**526       * A sudo just took place. \[result\]527       **/528      Sudid: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;529      /**530       * A sudo just took place. \[result\]531       **/532      SudoAsDone: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;533      /**534       * Generic event535       **/536      [key: string]: AugmentedEvent<ApiType>;537    };538    system: {539      /**540       * `:code` was updated.541       **/542      CodeUpdated: AugmentedEvent<ApiType, []>;543      /**544       * An extrinsic failed.545       **/546      ExtrinsicFailed: AugmentedEvent<ApiType, [dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo }>;547      /**548       * An extrinsic completed successfully.549       **/550      ExtrinsicSuccess: AugmentedEvent<ApiType, [dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchInfo: FrameSupportDispatchDispatchInfo }>;551      /**552       * An account was reaped.553       **/554      KilledAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;555      /**556       * A new account was created.557       **/558      NewAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;559      /**560       * On on-chain remark happened.561       **/562      Remarked: AugmentedEvent<ApiType, [sender: AccountId32, hash_: H256], { sender: AccountId32, hash_: H256 }>;563      /**564       * Generic event565       **/566      [key: string]: AugmentedEvent<ApiType>;567    };568    testUtils: {569      BatchCompleted: AugmentedEvent<ApiType, []>;570      ShouldRollback: AugmentedEvent<ApiType, []>;571      ValueIsSet: AugmentedEvent<ApiType, []>;572      /**573       * Generic event574       **/575      [key: string]: AugmentedEvent<ApiType>;576    };577    tokens: {578      /**579       * A balance was set by root.580       **/581      BalanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128 }>;582      /**583       * Deposited some balance into an account584       **/585      Deposited: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;586      /**587       * An account was removed whose balance was non-zero but below588       * ExistentialDeposit, resulting in an outright loss.589       **/590      DustLost: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;591      /**592       * An account was created with some free balance.593       **/594      Endowed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;595      /**596       * Some locked funds were unlocked597       **/598      LockRemoved: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32 }>;599      /**600       * Some funds are locked601       **/602      LockSet: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;603      /**604       * Some balance was reserved (moved from free to reserved).605       **/606      Reserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;607      /**608       * Some reserved balance was repatriated (moved from reserved to609       * another account).610       **/611      ReserveRepatriated: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus }>;612      /**613       * Some balances were slashed (e.g. due to mis-behavior)614       **/615      Slashed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128 }>;616      /**617       * The total issuance of an currency has been set618       **/619      TotalIssuanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, amount: u128], { currencyId: PalletForeignAssetsAssetIds, amount: u128 }>;620      /**621       * Transfer succeeded.622       **/623      Transfer: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128 }>;624      /**625       * Some balance was unreserved (moved from reserved to free).626       **/627      Unreserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;628      /**629       * Some balances were withdrawn (e.g. pay for transaction fee)630       **/631      Withdrawn: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;632      /**633       * Generic event634       **/635      [key: string]: AugmentedEvent<ApiType>;636    };637    transactionPayment: {638      /**639       * A transaction fee `actual_fee`, of which `tip` was added to the minimum inclusion fee,640       * has been paid by `who`.641       **/642      TransactionFeePaid: AugmentedEvent<ApiType, [who: AccountId32, actualFee: u128, tip: u128], { who: AccountId32, actualFee: u128, tip: u128 }>;643      /**644       * Generic event645       **/646      [key: string]: AugmentedEvent<ApiType>;647    };648    treasury: {649      /**650       * Some funds have been allocated.651       **/652      Awarded: AugmentedEvent<ApiType, [proposalIndex: u32, award: u128, account: AccountId32], { proposalIndex: u32, award: u128, account: AccountId32 }>;653      /**654       * Some of our funds have been burnt.655       **/656      Burnt: AugmentedEvent<ApiType, [burntFunds: u128], { burntFunds: u128 }>;657      /**658       * Some funds have been deposited.659       **/660      Deposit: AugmentedEvent<ApiType, [value: u128], { value: u128 }>;661      /**662       * New proposal.663       **/664      Proposed: AugmentedEvent<ApiType, [proposalIndex: u32], { proposalIndex: u32 }>;665      /**666       * A proposal was rejected; funds were slashed.667       **/668      Rejected: AugmentedEvent<ApiType, [proposalIndex: u32, slashed: u128], { proposalIndex: u32, slashed: u128 }>;669      /**670       * Spending has finished; this is the amount that rolls over until next spend.671       **/672      Rollover: AugmentedEvent<ApiType, [rolloverBalance: u128], { rolloverBalance: u128 }>;673      /**674       * A new spend proposal has been approved.675       **/676      SpendApproved: AugmentedEvent<ApiType, [proposalIndex: u32, amount: u128, beneficiary: AccountId32], { proposalIndex: u32, amount: u128, beneficiary: AccountId32 }>;677      /**678       * We have ended a spend period and will now allocate funds.679       **/680      Spending: AugmentedEvent<ApiType, [budgetRemaining: u128], { budgetRemaining: u128 }>;681      /**682       * Generic event683       **/684      [key: string]: AugmentedEvent<ApiType>;685    };686    unique: {687      /**688       * Address was added to the allow list689       * 690       * # Arguments691       * * collection_id: ID of the affected collection.692       * * user: Address of the added account.693       **/694      AllowListAddressAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;695      /**696       * Address was removed from the allow list697       * 698       * # Arguments699       * * collection_id: ID of the affected collection.700       * * user: Address of the removed account.701       **/702      AllowListAddressRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;703      /**704       * Collection admin was added705       * 706       * # Arguments707       * * collection_id: ID of the affected collection.708       * * admin: Admin address.709       **/710      CollectionAdminAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;711      /**712       * Collection admin was removed713       * 714       * # Arguments715       * * collection_id: ID of the affected collection.716       * * admin: Removed admin address.717       **/718      CollectionAdminRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;719      /**720       * Collection limits were set721       * 722       * # Arguments723       * * collection_id: ID of the affected collection.724       **/725      CollectionLimitSet: AugmentedEvent<ApiType, [u32]>;726      /**727       * Collection owned was changed728       * 729       * # Arguments730       * * collection_id: ID of the affected collection.731       * * owner: New owner address.732       **/733      CollectionOwnedChanged: AugmentedEvent<ApiType, [u32, AccountId32]>;734      /**735       * Collection permissions were set736       * 737       * # Arguments738       * * collection_id: ID of the affected collection.739       **/740      CollectionPermissionSet: AugmentedEvent<ApiType, [u32]>;741      /**742       * Collection sponsor was removed743       * 744       * # Arguments745       * * collection_id: ID of the affected collection.746       **/747      CollectionSponsorRemoved: AugmentedEvent<ApiType, [u32]>;748      /**749       * Collection sponsor was set750       * 751       * # Arguments752       * * collection_id: ID of the affected collection.753       * * owner: New sponsor address.754       **/755      CollectionSponsorSet: AugmentedEvent<ApiType, [u32, AccountId32]>;756      /**757       * New sponsor was confirm758       * 759       * # Arguments760       * * collection_id: ID of the affected collection.761       * * sponsor: New sponsor address.762       **/763      SponsorshipConfirmed: AugmentedEvent<ApiType, [u32, AccountId32]>;764      /**765       * Generic event766       **/767      [key: string]: AugmentedEvent<ApiType>;768    };769    vesting: {770      /**771       * Claimed vesting.772       **/773      Claimed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;774      /**775       * Added new vesting schedule.776       **/777      VestingScheduleAdded: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule], { from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule }>;778      /**779       * Updated vesting schedules.780       **/781      VestingSchedulesUpdated: AugmentedEvent<ApiType, [who: AccountId32], { who: AccountId32 }>;782      /**783       * Generic event784       **/785      [key: string]: AugmentedEvent<ApiType>;786    };787    xcmpQueue: {788      /**789       * Bad XCM format used.790       **/791      BadFormat: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;792      /**793       * Bad XCM version used.794       **/795      BadVersion: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;796      /**797       * Some XCM failed.798       **/799      Fail: AugmentedEvent<ApiType, [messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight], { messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight }>;800      /**801       * An XCM exceeded the individual message weight budget.802       **/803      OverweightEnqueued: AugmentedEvent<ApiType, [sender: u32, sentAt: u32, index: u64, required: Weight], { sender: u32, sentAt: u32, index: u64, required: Weight }>;804      /**805       * An XCM from the overweight queue was executed with the given actual weight used.806       **/807      OverweightServiced: AugmentedEvent<ApiType, [index: u64, used: Weight], { index: u64, used: Weight }>;808      /**809       * Some XCM was executed ok.810       **/811      Success: AugmentedEvent<ApiType, [messageHash: Option<H256>, weight: Weight], { messageHash: Option<H256>, weight: Weight }>;812      /**813       * An upward message was sent to the relay chain.814       **/815      UpwardMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;816      /**817       * An HRMP message was sent to a sibling parachain.818       **/819      XcmpMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;820      /**821       * Generic event822       **/823      [key: string]: AugmentedEvent<ApiType>;824    };825    xTokens: {826      /**827       * Transferred `MultiAsset` with fee.828       **/829      TransferredMultiAssets: AugmentedEvent<ApiType, [sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation], { sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation }>;830      /**831       * Generic event832       **/833      [key: string]: AugmentedEvent<ApiType>;834    };835  } // AugmentedEvents836} // declare module
after · tests/src/interfaces/augment-api-events.ts
1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */34// import type lookup before we augment - in some environments5// this is required to allow for ambient/previous definitions6import '@polkadot/api-base/types/events';78import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types';9import type { Bytes, Null, Option, Result, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';10import type { ITuple } from '@polkadot/types-codec/types';11import type { AccountId32, H160, H256, Weight } from '@polkadot/types/interfaces/runtime';12import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, PalletForeignAssetsAssetIds, PalletForeignAssetsModuleAssetMetadata, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetMultiAssets, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';1314export type __AugmentedEvent<ApiType extends ApiTypes> = AugmentedEvent<ApiType>;1516declare module '@polkadot/api-base/types/events' {17  interface AugmentedEvents<ApiType extends ApiTypes> {18    appPromotion: {19      /**20       * The admin was set21       * 22       * # Arguments23       * * AccountId: account address of the admin24       **/25      SetAdmin: AugmentedEvent<ApiType, [AccountId32]>;26      /**27       * Staking was performed28       * 29       * # Arguments30       * * AccountId: account of the staker31       * * Balance : staking amount32       **/33      Stake: AugmentedEvent<ApiType, [AccountId32, u128]>;34      /**35       * Staking recalculation was performed36       * 37       * # Arguments38       * * AccountId: account of the staker.39       * * Balance : recalculation base40       * * Balance : total income41       **/42      StakingRecalculation: AugmentedEvent<ApiType, [AccountId32, u128, u128]>;43      /**44       * Unstaking was performed45       * 46       * # Arguments47       * * AccountId: account of the staker48       * * Balance : unstaking amount49       **/50      Unstake: AugmentedEvent<ApiType, [AccountId32, u128]>;51      /**52       * Generic event53       **/54      [key: string]: AugmentedEvent<ApiType>;55    };56    balances: {57      /**58       * A balance was set by root.59       **/60      BalanceSet: AugmentedEvent<ApiType, [who: AccountId32, free: u128, reserved: u128], { who: AccountId32, free: u128, reserved: u128 }>;61      /**62       * Some amount was deposited (e.g. for transaction fees).63       **/64      Deposit: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;65      /**66       * An account was removed whose balance was non-zero but below ExistentialDeposit,67       * resulting in an outright loss.68       **/69      DustLost: AugmentedEvent<ApiType, [account: AccountId32, amount: u128], { account: AccountId32, amount: u128 }>;70      /**71       * An account was created with some free balance.72       **/73      Endowed: AugmentedEvent<ApiType, [account: AccountId32, freeBalance: u128], { account: AccountId32, freeBalance: u128 }>;74      /**75       * Some balance was reserved (moved from free to reserved).76       **/77      Reserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;78      /**79       * Some balance was moved from the reserve of the first account to the second account.80       * Final argument indicates the destination balance type.81       **/82      ReserveRepatriated: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus], { from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus }>;83      /**84       * Some amount was removed from the account (e.g. for misbehavior).85       **/86      Slashed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;87      /**88       * Transfer succeeded.89       **/90      Transfer: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128], { from: AccountId32, to: AccountId32, amount: u128 }>;91      /**92       * Some balance was unreserved (moved from reserved to free).93       **/94      Unreserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;95      /**96       * Some amount was withdrawn from the account (e.g. for transaction fees).97       **/98      Withdraw: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;99      /**100       * Generic event101       **/102      [key: string]: AugmentedEvent<ApiType>;103    };104    common: {105      /**106       * Amount pieces of token owned by `sender` was approved for `spender`.107       **/108      Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;109      /**110       * Amount pieces of token owned by `sender` was approved for `spender`.111       **/112      ApprovedForAll: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;113      /**114       * New collection was created115       **/116      CollectionCreated: AugmentedEvent<ApiType, [u32, u8, AccountId32]>;117      /**118       * New collection was destroyed119       **/120      CollectionDestroyed: AugmentedEvent<ApiType, [u32]>;121      /**122       * The property has been deleted.123       **/124      CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;125      /**126       * The colletion property has been added or edited.127       **/128      CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;129      /**130       * New item was created.131       **/132      ItemCreated: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;133      /**134       * Collection item was burned.135       **/136      ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;137      /**138       * The token property permission of a collection has been set.139       **/140      PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;141      /**142       * The token property has been deleted.143       **/144      TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;145      /**146       * The token property has been added or edited.147       **/148      TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;149      /**150       * Item was transferred151       **/152      Transfer: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;153      /**154       * Generic event155       **/156      [key: string]: AugmentedEvent<ApiType>;157    };158    cumulusXcm: {159      /**160       * Downward message executed with the given outcome.161       * \[ id, outcome \]162       **/163      ExecutedDownward: AugmentedEvent<ApiType, [U8aFixed, XcmV2TraitsOutcome]>;164      /**165       * Downward message is invalid XCM.166       * \[ id \]167       **/168      InvalidFormat: AugmentedEvent<ApiType, [U8aFixed]>;169      /**170       * Downward message is unsupported version of XCM.171       * \[ id \]172       **/173      UnsupportedVersion: AugmentedEvent<ApiType, [U8aFixed]>;174      /**175       * Generic event176       **/177      [key: string]: AugmentedEvent<ApiType>;178    };179    dmpQueue: {180      /**181       * Downward message executed with the given outcome.182       **/183      ExecutedDownward: AugmentedEvent<ApiType, [messageId: U8aFixed, outcome: XcmV2TraitsOutcome], { messageId: U8aFixed, outcome: XcmV2TraitsOutcome }>;184      /**185       * Downward message is invalid XCM.186       **/187      InvalidFormat: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;188      /**189       * Downward message is overweight and was placed in the overweight queue.190       **/191      OverweightEnqueued: AugmentedEvent<ApiType, [messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight], { messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight }>;192      /**193       * Downward message from the overweight queue was executed.194       **/195      OverweightServiced: AugmentedEvent<ApiType, [overweightIndex: u64, weightUsed: Weight], { overweightIndex: u64, weightUsed: Weight }>;196      /**197       * Downward message is unsupported version of XCM.198       **/199      UnsupportedVersion: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;200      /**201       * The weight limit for handling downward messages was reached.202       **/203      WeightExhausted: AugmentedEvent<ApiType, [messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight], { messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight }>;204      /**205       * Generic event206       **/207      [key: string]: AugmentedEvent<ApiType>;208    };209    ethereum: {210      /**211       * An ethereum transaction was successfully executed.212       **/213      Executed: AugmentedEvent<ApiType, [from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason], { from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason }>;214      /**215       * Generic event216       **/217      [key: string]: AugmentedEvent<ApiType>;218    };219    evm: {220      /**221       * A contract has been created at given address.222       **/223      Created: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;224      /**225       * A contract was attempted to be created, but the execution failed.226       **/227      CreatedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;228      /**229       * A contract has been executed successfully with states applied.230       **/231      Executed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;232      /**233       * A contract has been executed with errors. States are reverted with only gas fees applied.234       **/235      ExecutedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;236      /**237       * Ethereum events from contracts.238       **/239      Log: AugmentedEvent<ApiType, [log: EthereumLog], { log: EthereumLog }>;240      /**241       * Generic event242       **/243      [key: string]: AugmentedEvent<ApiType>;244    };245    evmContractHelpers: {246      /**247       * Collection sponsor was removed.248       **/249      ContractSponsorRemoved: AugmentedEvent<ApiType, [H160]>;250      /**251       * Contract sponsor was set.252       **/253      ContractSponsorSet: AugmentedEvent<ApiType, [H160, AccountId32]>;254      /**255       * New sponsor was confirm.256       **/257      ContractSponsorshipConfirmed: AugmentedEvent<ApiType, [H160, AccountId32]>;258      /**259       * Generic event260       **/261      [key: string]: AugmentedEvent<ApiType>;262    };263    evmMigration: {264      /**265       * This event is used in benchmarking and can be used for tests266       **/267      TestEvent: AugmentedEvent<ApiType, []>;268      /**269       * Generic event270       **/271      [key: string]: AugmentedEvent<ApiType>;272    };273    foreignAssets: {274      /**275       * The asset registered.276       **/277      AssetRegistered: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;278      /**279       * The asset updated.280       **/281      AssetUpdated: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;282      /**283       * The foreign asset registered.284       **/285      ForeignAssetRegistered: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;286      /**287       * The foreign asset updated.288       **/289      ForeignAssetUpdated: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;290      /**291       * Generic event292       **/293      [key: string]: AugmentedEvent<ApiType>;294    };295    maintenance: {296      MaintenanceDisabled: AugmentedEvent<ApiType, []>;297      MaintenanceEnabled: AugmentedEvent<ApiType, []>;298      /**299       * Generic event300       **/301      [key: string]: AugmentedEvent<ApiType>;302    };303    parachainSystem: {304      /**305       * Downward messages were processed using the given weight.306       **/307      DownwardMessagesProcessed: AugmentedEvent<ApiType, [weightUsed: Weight, dmqHead: H256], { weightUsed: Weight, dmqHead: H256 }>;308      /**309       * Some downward messages have been received and will be processed.310       **/311      DownwardMessagesReceived: AugmentedEvent<ApiType, [count: u32], { count: u32 }>;312      /**313       * An upgrade has been authorized.314       **/315      UpgradeAuthorized: AugmentedEvent<ApiType, [codeHash: H256], { codeHash: H256 }>;316      /**317       * The validation function was applied as of the contained relay chain block number.318       **/319      ValidationFunctionApplied: AugmentedEvent<ApiType, [relayChainBlockNum: u32], { relayChainBlockNum: u32 }>;320      /**321       * The relay-chain aborted the upgrade process.322       **/323      ValidationFunctionDiscarded: AugmentedEvent<ApiType, []>;324      /**325       * The validation function has been scheduled to apply.326       **/327      ValidationFunctionStored: AugmentedEvent<ApiType, []>;328      /**329       * Generic event330       **/331      [key: string]: AugmentedEvent<ApiType>;332    };333    polkadotXcm: {334      /**335       * Some assets have been placed in an asset trap.336       * 337       * \[ hash, origin, assets \]338       **/339      AssetsTrapped: AugmentedEvent<ApiType, [H256, XcmV1MultiLocation, XcmVersionedMultiAssets]>;340      /**341       * Execution of an XCM message was attempted.342       * 343       * \[ outcome \]344       **/345      Attempted: AugmentedEvent<ApiType, [XcmV2TraitsOutcome]>;346      /**347       * Expected query response has been received but the origin location of the response does348       * not match that expected. The query remains registered for a later, valid, response to349       * be received and acted upon.350       * 351       * \[ origin location, id, expected location \]352       **/353      InvalidResponder: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, Option<XcmV1MultiLocation>]>;354      /**355       * Expected query response has been received but the expected origin location placed in356       * storage by this runtime previously cannot be decoded. The query remains registered.357       * 358       * This is unexpected (since a location placed in storage in a previously executing359       * runtime should be readable prior to query timeout) and dangerous since the possibly360       * valid response will be dropped. Manual governance intervention is probably going to be361       * needed.362       * 363       * \[ origin location, id \]364       **/365      InvalidResponderVersion: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;366      /**367       * Query response has been received and query is removed. The registered notification has368       * been dispatched and executed successfully.369       * 370       * \[ id, pallet index, call index \]371       **/372      Notified: AugmentedEvent<ApiType, [u64, u8, u8]>;373      /**374       * Query response has been received and query is removed. The dispatch was unable to be375       * decoded into a `Call`; this might be due to dispatch function having a signature which376       * is not `(origin, QueryId, Response)`.377       * 378       * \[ id, pallet index, call index \]379       **/380      NotifyDecodeFailed: AugmentedEvent<ApiType, [u64, u8, u8]>;381      /**382       * Query response has been received and query is removed. There was a general error with383       * dispatching the notification call.384       * 385       * \[ id, pallet index, call index \]386       **/387      NotifyDispatchError: AugmentedEvent<ApiType, [u64, u8, u8]>;388      /**389       * Query response has been received and query is removed. The registered notification could390       * not be dispatched because the dispatch weight is greater than the maximum weight391       * originally budgeted by this runtime for the query result.392       * 393       * \[ id, pallet index, call index, actual weight, max budgeted weight \]394       **/395      NotifyOverweight: AugmentedEvent<ApiType, [u64, u8, u8, Weight, Weight]>;396      /**397       * A given location which had a version change subscription was dropped owing to an error398       * migrating the location to our new XCM format.399       * 400       * \[ location, query ID \]401       **/402      NotifyTargetMigrationFail: AugmentedEvent<ApiType, [XcmVersionedMultiLocation, u64]>;403      /**404       * A given location which had a version change subscription was dropped owing to an error405       * sending the notification to it.406       * 407       * \[ location, query ID, error \]408       **/409      NotifyTargetSendFail: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, XcmV2TraitsError]>;410      /**411       * Query response has been received and is ready for taking with `take_response`. There is412       * no registered notification call.413       * 414       * \[ id, response \]415       **/416      ResponseReady: AugmentedEvent<ApiType, [u64, XcmV2Response]>;417      /**418       * Received query response has been read and removed.419       * 420       * \[ id \]421       **/422      ResponseTaken: AugmentedEvent<ApiType, [u64]>;423      /**424       * A XCM message was sent.425       * 426       * \[ origin, destination, message \]427       **/428      Sent: AugmentedEvent<ApiType, [XcmV1MultiLocation, XcmV1MultiLocation, XcmV2Xcm]>;429      /**430       * The supported version of a location has been changed. This might be through an431       * automatic notification or a manual intervention.432       * 433       * \[ location, XCM version \]434       **/435      SupportedVersionChanged: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;436      /**437       * Query response received which does not match a registered query. This may be because a438       * matching query was never registered, it may be because it is a duplicate response, or439       * because the query timed out.440       * 441       * \[ origin location, id \]442       **/443      UnexpectedResponse: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;444      /**445       * An XCM version change notification message has been attempted to be sent.446       * 447       * \[ destination, result \]448       **/449      VersionChangeNotified: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;450      /**451       * Generic event452       **/453      [key: string]: AugmentedEvent<ApiType>;454    };455    rmrkCore: {456      CollectionCreated: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;457      CollectionDestroyed: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;458      CollectionLocked: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;459      IssuerChanged: AugmentedEvent<ApiType, [oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32], { oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32 }>;460      NFTAccepted: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32 }>;461      NFTBurned: AugmentedEvent<ApiType, [owner: AccountId32, nftId: u32], { owner: AccountId32, nftId: u32 }>;462      NftMinted: AugmentedEvent<ApiType, [owner: AccountId32, collectionId: u32, nftId: u32], { owner: AccountId32, collectionId: u32, nftId: u32 }>;463      NFTRejected: AugmentedEvent<ApiType, [sender: AccountId32, collectionId: u32, nftId: u32], { sender: AccountId32, collectionId: u32, nftId: u32 }>;464      NFTSent: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool }>;465      PrioritySet: AugmentedEvent<ApiType, [collectionId: u32, nftId: u32], { collectionId: u32, nftId: u32 }>;466      PropertySet: AugmentedEvent<ApiType, [collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes], { collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes }>;467      ResourceAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;468      ResourceAdded: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;469      ResourceRemoval: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;470      ResourceRemovalAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;471      /**472       * Generic event473       **/474      [key: string]: AugmentedEvent<ApiType>;475    };476    rmrkEquip: {477      BaseCreated: AugmentedEvent<ApiType, [issuer: AccountId32, baseId: u32], { issuer: AccountId32, baseId: u32 }>;478      EquippablesUpdated: AugmentedEvent<ApiType, [baseId: u32, slotId: u32], { baseId: u32, slotId: u32 }>;479      /**480       * Generic event481       **/482      [key: string]: AugmentedEvent<ApiType>;483    };484    scheduler: {485      /**486       * The call for the provided hash was not found so the task has been aborted.487       **/488      CallUnavailable: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;489      /**490       * Canceled some task.491       **/492      Canceled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;493      /**494       * Dispatched some task.495       **/496      Dispatched: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError> }>;497      /**498       * The given task can never be executed since it is overweight.499       **/500      PermanentlyOverweight: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;501      /**502       * Scheduled task's priority has changed503       **/504      PriorityChanged: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, priority: u8], { task: ITuple<[u32, u32]>, priority: u8 }>;505      /**506       * Scheduled some task.507       **/508      Scheduled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;509      /**510       * Generic event511       **/512      [key: string]: AugmentedEvent<ApiType>;513    };514    structure: {515      /**516       * Executed call on behalf of the token.517       **/518      Executed: AugmentedEvent<ApiType, [Result<Null, SpRuntimeDispatchError>]>;519      /**520       * Generic event521       **/522      [key: string]: AugmentedEvent<ApiType>;523    };524    sudo: {525      /**526       * The \[sudoer\] just switched identity; the old key is supplied if one existed.527       **/528      KeyChanged: AugmentedEvent<ApiType, [oldSudoer: Option<AccountId32>], { oldSudoer: Option<AccountId32> }>;529      /**530       * A sudo just took place. \[result\]531       **/532      Sudid: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;533      /**534       * A sudo just took place. \[result\]535       **/536      SudoAsDone: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;537      /**538       * Generic event539       **/540      [key: string]: AugmentedEvent<ApiType>;541    };542    system: {543      /**544       * `:code` was updated.545       **/546      CodeUpdated: AugmentedEvent<ApiType, []>;547      /**548       * An extrinsic failed.549       **/550      ExtrinsicFailed: AugmentedEvent<ApiType, [dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo }>;551      /**552       * An extrinsic completed successfully.553       **/554      ExtrinsicSuccess: AugmentedEvent<ApiType, [dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchInfo: FrameSupportDispatchDispatchInfo }>;555      /**556       * An account was reaped.557       **/558      KilledAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;559      /**560       * A new account was created.561       **/562      NewAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;563      /**564       * On on-chain remark happened.565       **/566      Remarked: AugmentedEvent<ApiType, [sender: AccountId32, hash_: H256], { sender: AccountId32, hash_: H256 }>;567      /**568       * Generic event569       **/570      [key: string]: AugmentedEvent<ApiType>;571    };572    testUtils: {573      BatchCompleted: AugmentedEvent<ApiType, []>;574      ShouldRollback: AugmentedEvent<ApiType, []>;575      ValueIsSet: AugmentedEvent<ApiType, []>;576      /**577       * Generic event578       **/579      [key: string]: AugmentedEvent<ApiType>;580    };581    tokens: {582      /**583       * A balance was set by root.584       **/585      BalanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128 }>;586      /**587       * Deposited some balance into an account588       **/589      Deposited: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;590      /**591       * An account was removed whose balance was non-zero but below592       * ExistentialDeposit, resulting in an outright loss.593       **/594      DustLost: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;595      /**596       * An account was created with some free balance.597       **/598      Endowed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;599      /**600       * Some locked funds were unlocked601       **/602      LockRemoved: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32 }>;603      /**604       * Some funds are locked605       **/606      LockSet: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;607      /**608       * Some balance was reserved (moved from free to reserved).609       **/610      Reserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;611      /**612       * Some reserved balance was repatriated (moved from reserved to613       * another account).614       **/615      ReserveRepatriated: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus }>;616      /**617       * Some balances were slashed (e.g. due to mis-behavior)618       **/619      Slashed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128 }>;620      /**621       * The total issuance of an currency has been set622       **/623      TotalIssuanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, amount: u128], { currencyId: PalletForeignAssetsAssetIds, amount: u128 }>;624      /**625       * Transfer succeeded.626       **/627      Transfer: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128 }>;628      /**629       * Some balance was unreserved (moved from reserved to free).630       **/631      Unreserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;632      /**633       * Some balances were withdrawn (e.g. pay for transaction fee)634       **/635      Withdrawn: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;636      /**637       * Generic event638       **/639      [key: string]: AugmentedEvent<ApiType>;640    };641    transactionPayment: {642      /**643       * A transaction fee `actual_fee`, of which `tip` was added to the minimum inclusion fee,644       * has been paid by `who`.645       **/646      TransactionFeePaid: AugmentedEvent<ApiType, [who: AccountId32, actualFee: u128, tip: u128], { who: AccountId32, actualFee: u128, tip: u128 }>;647      /**648       * Generic event649       **/650      [key: string]: AugmentedEvent<ApiType>;651    };652    treasury: {653      /**654       * Some funds have been allocated.655       **/656      Awarded: AugmentedEvent<ApiType, [proposalIndex: u32, award: u128, account: AccountId32], { proposalIndex: u32, award: u128, account: AccountId32 }>;657      /**658       * Some of our funds have been burnt.659       **/660      Burnt: AugmentedEvent<ApiType, [burntFunds: u128], { burntFunds: u128 }>;661      /**662       * Some funds have been deposited.663       **/664      Deposit: AugmentedEvent<ApiType, [value: u128], { value: u128 }>;665      /**666       * New proposal.667       **/668      Proposed: AugmentedEvent<ApiType, [proposalIndex: u32], { proposalIndex: u32 }>;669      /**670       * A proposal was rejected; funds were slashed.671       **/672      Rejected: AugmentedEvent<ApiType, [proposalIndex: u32, slashed: u128], { proposalIndex: u32, slashed: u128 }>;673      /**674       * Spending has finished; this is the amount that rolls over until next spend.675       **/676      Rollover: AugmentedEvent<ApiType, [rolloverBalance: u128], { rolloverBalance: u128 }>;677      /**678       * A new spend proposal has been approved.679       **/680      SpendApproved: AugmentedEvent<ApiType, [proposalIndex: u32, amount: u128, beneficiary: AccountId32], { proposalIndex: u32, amount: u128, beneficiary: AccountId32 }>;681      /**682       * We have ended a spend period and will now allocate funds.683       **/684      Spending: AugmentedEvent<ApiType, [budgetRemaining: u128], { budgetRemaining: u128 }>;685      /**686       * Generic event687       **/688      [key: string]: AugmentedEvent<ApiType>;689    };690    unique: {691      /**692       * Address was added to the allow list693       * 694       * # Arguments695       * * collection_id: ID of the affected collection.696       * * user: Address of the added account.697       **/698      AllowListAddressAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;699      /**700       * Address was removed from the allow list701       * 702       * # Arguments703       * * collection_id: ID of the affected collection.704       * * user: Address of the removed account.705       **/706      AllowListAddressRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;707      /**708       * Collection admin was added709       * 710       * # Arguments711       * * collection_id: ID of the affected collection.712       * * admin: Admin address.713       **/714      CollectionAdminAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;715      /**716       * Collection admin was removed717       * 718       * # Arguments719       * * collection_id: ID of the affected collection.720       * * admin: Removed admin address.721       **/722      CollectionAdminRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;723      /**724       * Collection limits were set725       * 726       * # Arguments727       * * collection_id: ID of the affected collection.728       **/729      CollectionLimitSet: AugmentedEvent<ApiType, [u32]>;730      /**731       * Collection owned was changed732       * 733       * # Arguments734       * * collection_id: ID of the affected collection.735       * * owner: New owner address.736       **/737      CollectionOwnedChanged: AugmentedEvent<ApiType, [u32, AccountId32]>;738      /**739       * Collection permissions were set740       * 741       * # Arguments742       * * collection_id: ID of the affected collection.743       **/744      CollectionPermissionSet: AugmentedEvent<ApiType, [u32]>;745      /**746       * Collection sponsor was removed747       * 748       * # Arguments749       * * collection_id: ID of the affected collection.750       **/751      CollectionSponsorRemoved: AugmentedEvent<ApiType, [u32]>;752      /**753       * Collection sponsor was set754       * 755       * # Arguments756       * * collection_id: ID of the affected collection.757       * * owner: New sponsor address.758       **/759      CollectionSponsorSet: AugmentedEvent<ApiType, [u32, AccountId32]>;760      /**761       * New sponsor was confirm762       * 763       * # Arguments764       * * collection_id: ID of the affected collection.765       * * sponsor: New sponsor address.766       **/767      SponsorshipConfirmed: AugmentedEvent<ApiType, [u32, AccountId32]>;768      /**769       * Generic event770       **/771      [key: string]: AugmentedEvent<ApiType>;772    };773    vesting: {774      /**775       * Claimed vesting.776       **/777      Claimed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;778      /**779       * Added new vesting schedule.780       **/781      VestingScheduleAdded: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule], { from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule }>;782      /**783       * Updated vesting schedules.784       **/785      VestingSchedulesUpdated: AugmentedEvent<ApiType, [who: AccountId32], { who: AccountId32 }>;786      /**787       * Generic event788       **/789      [key: string]: AugmentedEvent<ApiType>;790    };791    xcmpQueue: {792      /**793       * Bad XCM format used.794       **/795      BadFormat: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;796      /**797       * Bad XCM version used.798       **/799      BadVersion: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;800      /**801       * Some XCM failed.802       **/803      Fail: AugmentedEvent<ApiType, [messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight], { messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight }>;804      /**805       * An XCM exceeded the individual message weight budget.806       **/807      OverweightEnqueued: AugmentedEvent<ApiType, [sender: u32, sentAt: u32, index: u64, required: Weight], { sender: u32, sentAt: u32, index: u64, required: Weight }>;808      /**809       * An XCM from the overweight queue was executed with the given actual weight used.810       **/811      OverweightServiced: AugmentedEvent<ApiType, [index: u64, used: Weight], { index: u64, used: Weight }>;812      /**813       * Some XCM was executed ok.814       **/815      Success: AugmentedEvent<ApiType, [messageHash: Option<H256>, weight: Weight], { messageHash: Option<H256>, weight: Weight }>;816      /**817       * An upward message was sent to the relay chain.818       **/819      UpwardMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;820      /**821       * An HRMP message was sent to a sibling parachain.822       **/823      XcmpMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;824      /**825       * Generic event826       **/827      [key: string]: AugmentedEvent<ApiType>;828    };829    xTokens: {830      /**831       * Transferred `MultiAsset` with fee.832       **/833      TransferredMultiAssets: AugmentedEvent<ApiType, [sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation], { sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation }>;834      /**835       * Generic event836       **/837      [key: string]: AugmentedEvent<ApiType>;838    };839  } // AugmentedEvents840} // declare module
modifiedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -442,6 +442,10 @@
        **/
       tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
+       * Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+       **/
+      walletOperator: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<Option<bool>>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]>;
+      /**
        * Generic query
        **/
       [key: string]: QueryableStorageEntry<ApiType>;
@@ -645,6 +649,10 @@
        **/
       totalSupply: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<u128>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
+       * Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+       **/
+      walletOperator: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<Option<bool>>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]>;
+      /**
        * Generic query
        **/
       [key: string]: QueryableStorageEntry<ApiType>;
modifiedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -720,6 +720,10 @@
        **/
       effectiveCollectionLimits: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsCollectionLimits>>>;
       /**
+       * Tells whether an operator is approved by a given owner.
+       **/
+      isApprovedForAll: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, owner: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, operator: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<bool>>>;
+      /**
        * Get the last token ID created in a collection
        **/
       lastTokenId: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u32>>;
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -1545,6 +1545,18 @@
        **/
       repartition: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;
       /**
+       * Sets or unsets the approval of a given operator.
+       * 
+       * An operator is allowed to transfer all tokens of the sender on their behalf.
+       * 
+       * # Arguments
+       * 
+       * * `owner`: Token owner
+       * * `operator`: Operator
+       * * `approve`: Is operator enabled or disabled
+       **/
+      setApprovalForAll: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, operator: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, approve: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;
+      /**
        * Set specific limits of a collection. Empty, or None fields mean chain default.
        * 
        * # Permissions
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -1286,6 +1286,8 @@
   readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
   readonly isApproved: boolean;
   readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
+  readonly isApprovedForAll: boolean;
+  readonly asApprovedForAll: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;
   readonly isCollectionPropertySet: boolean;
   readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;
   readonly isCollectionPropertyDeleted: boolean;
@@ -1296,7 +1298,7 @@
   readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;
   readonly isPropertyPermissionSet: boolean;
   readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;
-  readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
+  readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'ApprovedForAll' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
 }
 
 /** @name PalletConfigurationCall */
@@ -1603,7 +1605,8 @@
   readonly isFungibleItemsDontHaveData: boolean;
   readonly isFungibleDisallowsNesting: boolean;
   readonly isSettingPropertiesNotAllowed: boolean;
-  readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
+  readonly isSettingApprovalForAllNotAllowed: boolean;
+  readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed' | 'SettingApprovalForAllNotAllowed';
 }
 
 /** @name PalletInflationCall */
@@ -2309,7 +2312,13 @@
     readonly tokenId: u32;
     readonly amount: u128;
   } & Struct;
-  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';
+  readonly isSetApprovalForAll: boolean;
+  readonly asSetApprovalForAll: {
+    readonly collectionId: u32;
+    readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;
+    readonly approve: bool;
+  } & Struct;
+  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetApprovalForAll';
 }
 
 /** @name PalletUniqueError */
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1046,6 +1046,7 @@
       ItemDestroyed: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,u128)',
       Transfer: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',
       Approved: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',
+      ApprovedForAll: '(u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,bool)',
       CollectionPropertySet: '(u32,Bytes)',
       CollectionPropertyDeleted: '(u32,Bytes)',
       TokenPropertySet: '(u32,u32,Bytes)',
@@ -1054,7 +1055,7 @@
     }
   },
   /**
-   * Lookup99: pallet_structure::pallet::Event<T>
+   * Lookup100: pallet_structure::pallet::Event<T>
    **/
   PalletStructureEvent: {
     _enum: {
@@ -1062,7 +1063,7 @@
     }
   },
   /**
-   * Lookup100: pallet_rmrk_core::pallet::Event<T>
+   * Lookup101: pallet_rmrk_core::pallet::Event<T>
    **/
   PalletRmrkCoreEvent: {
     _enum: {
@@ -1139,7 +1140,7 @@
     }
   },
   /**
-   * Lookup101: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
+   * Lookup102: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
    **/
   RmrkTraitsNftAccountIdOrCollectionNftTuple: {
     _enum: {
@@ -2302,7 +2303,12 @@
       repartition: {
         collectionId: 'u32',
         tokenId: 'u32',
-        amount: 'u128'
+        amount: 'u128',
+      },
+      set_approval_for_all: {
+        collectionId: 'u32',
+        operator: 'PalletEvmAccountBasicCrossAccountIdRepr',
+        approve: 'bool'
       }
     }
   },
@@ -3445,7 +3451,7 @@
    * Lookup430: pallet_fungible::pallet::Error<T>
    **/
   PalletFungibleError: {
-    _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed']
+    _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed', 'SettingApprovalForAllNotAllowed']
   },
   /**
    * Lookup431: pallet_refungible::ItemData
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1182,6 +1182,8 @@
     readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
     readonly isApproved: boolean;
     readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
+    readonly isApprovedForAll: boolean;
+    readonly asApprovedForAll: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;
     readonly isCollectionPropertySet: boolean;
     readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;
     readonly isCollectionPropertyDeleted: boolean;
@@ -1192,17 +1194,17 @@
     readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;
     readonly isPropertyPermissionSet: boolean;
     readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;
-    readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
+    readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'ApprovedForAll' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
   }
 
-  /** @name PalletStructureEvent (99) */
+  /** @name PalletStructureEvent (100) */
   interface PalletStructureEvent extends Enum {
     readonly isExecuted: boolean;
     readonly asExecuted: Result<Null, SpRuntimeDispatchError>;
     readonly type: 'Executed';
   }
 
-  /** @name PalletRmrkCoreEvent (100) */
+  /** @name PalletRmrkCoreEvent (101) */
   interface PalletRmrkCoreEvent extends Enum {
     readonly isCollectionCreated: boolean;
     readonly asCollectionCreated: {
@@ -1292,7 +1294,7 @@
     readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';
   }
 
-  /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (101) */
+  /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (102) */
   interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {
     readonly isAccountId: boolean;
     readonly asAccountId: AccountId32;
@@ -2539,7 +2541,13 @@
       readonly tokenId: u32;
       readonly amount: u128;
     } & Struct;
-    readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';
+    readonly isSetApprovalForAll: boolean;
+    readonly asSetApprovalForAll: {
+      readonly collectionId: u32;
+      readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;
+      readonly approve: bool;
+    } & Struct;
+    readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetApprovalForAll';
   }
 
   /** @name UpDataStructsCollectionMode (240) */
@@ -3655,7 +3663,8 @@
     readonly isFungibleItemsDontHaveData: boolean;
     readonly isFungibleDisallowsNesting: boolean;
     readonly isSettingPropertiesNotAllowed: boolean;
-    readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
+    readonly isSettingApprovalForAllNotAllowed: boolean;
+    readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed' | 'SettingApprovalForAllNotAllowed';
   }
 
   /** @name PalletRefungibleItemData (431) */
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/definitions.ts
+++ b/tests/src/interfaces/unique/definitions.ts
@@ -175,5 +175,10 @@
       [collectionParam, tokenParam], 
       'Option<u128>',
     ),
+    isApprovedForAll: fun(
+      'Tells whether an operator is approved by a given owner.', 
+      [collectionParam, crossAccountParam('owner'), crossAccountParam('operator')], 
+      'Option<bool>',
+    ),
   },
 };
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -1413,6 +1413,32 @@
   getTokenObject(_collectionId: number, _tokenId: number): any {
     return null;
   }
+
+  /**
+   * Tells whether an operator is approved by a given owner.
+   * @param collectionId ID of collection
+   * @param owner owner address
+	 * @param operator operator addrees
+   * @returns true if operator is enabled
+   */
+  async isApprovedForAll(collectionId: number, owner: ICrossAccountId, operator: ICrossAccountId): Promise<boolean> {
+    return (await this.helper.callRpc('api.rpc.unique.isApprovedForAll', [collectionId, owner, operator])).toJSON();
+  }
+
+  /** Sets or unsets the approval of a given operator.
+	 *  An operator is allowed to transfer all tokens of the sender on their behalf.
+	 *  @param operator Operator
+	 *  @param approved Is operator enabled or disabled
+   *  @returns ```true``` if extrinsic success, otherwise ```false```
+   */
+  async setApprovalForAll(signer: TSigner, collectionId: number, operator: ICrossAccountId, approved: boolean): Promise<boolean> {
+    const result = await this.helper.executeExtrinsic(
+      signer,
+      'api.tx.unique.setApprovalForAll', [collectionId, operator, approved],
+      true,
+    );
+    return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'ApprovedForAll');
+  }
 }