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

difftreelog

Merge pull request #427 from UniqueNetwork/doc/architectural-changes

Yaroslav Bolyukin2022-07-22parents: #281e817 #2bb23d8.patch.diff
in: master

19 files changed

modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -42,6 +42,7 @@
 #[rpc(server)]
 #[async_trait]
 pub trait UniqueApi<BlockHash, CrossAccountId, AccountId> {
+	/// Get tokens owned by account.
 	#[method(name = "unique_accountTokens")]
 	fn account_tokens(
 		&self,
@@ -49,12 +50,16 @@
 		account: CrossAccountId,
 		at: Option<BlockHash>,
 	) -> Result<Vec<TokenId>>;
+
+	/// Get tokens contained within a collection.
 	#[method(name = "unique_collectionTokens")]
 	fn collection_tokens(
 		&self,
 		collection: CollectionId,
 		at: Option<BlockHash>,
 	) -> Result<Vec<TokenId>>;
+
+	/// Check if the token exists.
 	#[method(name = "unique_tokenExists")]
 	fn token_exists(
 		&self,
@@ -63,6 +68,7 @@
 		at: Option<BlockHash>,
 	) -> Result<bool>;
 
+	/// Get the token owner.
 	#[method(name = "unique_tokenOwner")]
 	fn token_owner(
 		&self,
@@ -80,6 +86,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Vec<CrossAccountId>>;
 
+	/// Get the topmost token owner in the hierarchy of a possibly nested token.
 	#[method(name = "unique_topmostTokenOwner")]
 	fn topmost_token_owner(
 		&self,
@@ -87,6 +94,8 @@
 		token: TokenId,
 		at: Option<BlockHash>,
 	) -> Result<Option<CrossAccountId>>;
+
+	/// Get tokens nested directly into the token.
 	#[method(name = "unique_tokenChildren")]
 	fn token_children(
 		&self,
@@ -95,6 +104,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Vec<TokenChild>>;
 
+	/// Get collection properties, optionally limited to the provided keys.
 	#[method(name = "unique_collectionProperties")]
 	fn collection_properties(
 		&self,
@@ -103,6 +113,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Vec<Property>>;
 
+	/// Get token properties, optionally limited to the provided keys.
 	#[method(name = "unique_tokenProperties")]
 	fn token_properties(
 		&self,
@@ -112,6 +123,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Vec<Property>>;
 
+	/// Get property permissions, optionally limited to the provided keys.
 	#[method(name = "unique_propertyPermissions")]
 	fn property_permissions(
 		&self,
@@ -120,6 +132,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Vec<PropertyKeyPermission>>;
 
+	/// Get token data, including properties, optionally limited to the provided keys, and total pieces for an RFT.
 	#[method(name = "unique_tokenData")]
 	fn token_data(
 		&self,
@@ -129,8 +142,11 @@
 		at: Option<BlockHash>,
 	) -> Result<TokenData<CrossAccountId>>;
 
+	/// Get the amount of distinctive tokens present in a collection.
 	#[method(name = "unique_totalSupply")]
 	fn total_supply(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;
+
+	/// Get the amount of any user tokens owned by an account.
 	#[method(name = "unique_accountBalance")]
 	fn account_balance(
 		&self,
@@ -138,6 +154,8 @@
 		account: CrossAccountId,
 		at: Option<BlockHash>,
 	) -> Result<u32>;
+
+	/// Get the amount of a specific token owned by an account.
 	#[method(name = "unique_balance")]
 	fn balance(
 		&self,
@@ -146,6 +164,8 @@
 		token: TokenId,
 		at: Option<BlockHash>,
 	) -> Result<String>;
+
+	/// Get the amount of currently possible sponsored transactions on a token for the fee to be taken off a sponsor.
 	#[method(name = "unique_allowance")]
 	fn allowance(
 		&self,
@@ -156,18 +176,23 @@
 		at: Option<BlockHash>,
 	) -> Result<String>;
 
+	/// Get the list of admin accounts of a collection.
 	#[method(name = "unique_adminlist")]
 	fn adminlist(
 		&self,
 		collection: CollectionId,
 		at: Option<BlockHash>,
 	) -> Result<Vec<CrossAccountId>>;
+
+	/// Get the list of accounts allowed to operate within a collection.
 	#[method(name = "unique_allowlist")]
 	fn allowlist(
 		&self,
 		collection: CollectionId,
 		at: Option<BlockHash>,
 	) -> Result<Vec<CrossAccountId>>;
+
+	/// Check if a user is allowed to operate within a collection.
 	#[method(name = "unique_allowed")]
 	fn allowed(
 		&self,
@@ -175,17 +200,24 @@
 		user: CrossAccountId,
 		at: Option<BlockHash>,
 	) -> Result<bool>;
+
+	/// Get the last token ID created in a collection.
 	#[method(name = "unique_lastTokenId")]
 	fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;
+
+	/// Get collection info by the specified ID.
 	#[method(name = "unique_collectionById")]
 	fn collection_by_id(
 		&self,
 		collection: CollectionId,
 		at: Option<BlockHash>,
 	) -> Result<Option<RpcCollection<AccountId>>>;
+
+	/// Get chain stats about collections.
 	#[method(name = "unique_collectionStats")]
 	fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;
 
+	/// Get the number of blocks until sponsoring a transaction is available.
 	#[method(name = "unique_nextSponsored")]
 	fn next_sponsored(
 		&self,
@@ -195,6 +227,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Option<u64>>;
 
+	/// Get effective collection limits. If not explicitly set, get the chain defaults.
 	#[method(name = "unique_effectiveCollectionLimits")]
 	fn effective_collection_limits(
 		&self,
@@ -202,6 +235,7 @@
 		at: Option<BlockHash>,
 	) -> Result<Option<CollectionLimits>>;
 
+	/// Get the total amount of pieces of an RFT.
 	#[method(name = "unique_totalPieces")]
 	fn total_pieces(
 		&self,
@@ -228,20 +262,20 @@
 		Theme,
 	>
 	{
+		/// Get the latest created collection ID.
 		#[method(name = "rmrk_lastCollectionIdx")]
-		/// Get the latest created collection id
 		fn last_collection_idx(&self, at: Option<BlockHash>) -> Result<RmrkCollectionId>;
 
+		/// Get collection info by ID.
 		#[method(name = "rmrk_collectionById")]
-		/// Get collection by id
 		fn collection_by_id(
 			&self,
 			id: RmrkCollectionId,
 			at: Option<BlockHash>,
 		) -> Result<Option<CollectionInfo>>;
 
+		/// Get NFT info by collection and NFT IDs.
 		#[method(name = "rmrk_nftById")]
-		/// Get NFT by collection id and NFT id
 		fn nft_by_id(
 			&self,
 			collection_id: RmrkCollectionId,
@@ -249,8 +283,8 @@
 			at: Option<BlockHash>,
 		) -> Result<Option<NftInfo>>;
 
+		/// Get tokens owned by an account in a collection.
 		#[method(name = "rmrk_accountTokens")]
-		/// Get tokens owned by an account in a collection
 		fn account_tokens(
 			&self,
 			account_id: AccountId,
@@ -258,8 +292,8 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<RmrkNftId>>;
 
+		/// Get tokens nested in an NFT - its direct children (not the children's children).
 		#[method(name = "rmrk_nftChildren")]
-		/// Get NFT children
 		fn nft_children(
 			&self,
 			collection_id: RmrkCollectionId,
@@ -267,8 +301,8 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<RmrkNftChild>>;
 
+		/// Get collection properties, created by the user - not the proxy-specific properties.
 		#[method(name = "rmrk_collectionProperties")]
-		/// Get collection properties
 		fn collection_properties(
 			&self,
 			collection_id: RmrkCollectionId,
@@ -276,8 +310,8 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<PropertyInfo>>;
 
+		/// Get NFT properties, created by the user - not the proxy-specific properties.
 		#[method(name = "rmrk_nftProperties")]
-		/// Get NFT properties
 		fn nft_properties(
 			&self,
 			collection_id: RmrkCollectionId,
@@ -286,8 +320,8 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<PropertyInfo>>;
 
+		/// Get data of resources of an NFT.
 		#[method(name = "rmrk_nftResources")]
-		/// Get NFT resources
 		fn nft_resources(
 			&self,
 			collection_id: RmrkCollectionId,
@@ -295,8 +329,8 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<ResourceInfo>>;
 
+		/// Get the priority of a resource in an NFT.
 		#[method(name = "rmrk_nftResourcePriority")]
-		/// Get NFT resource priority
 		fn nft_resource_priority(
 			&self,
 			collection_id: RmrkCollectionId,
@@ -305,14 +339,15 @@
 			at: Option<BlockHash>,
 		) -> Result<Option<u32>>;
 
+		/// Get base info by its ID.
 		#[method(name = "rmrk_base")]
-		/// Get base info
 		fn base(&self, base_id: RmrkBaseId, at: Option<BlockHash>) -> Result<Option<BaseInfo>>;
 
+		/// Get all parts of a base.
 		#[method(name = "rmrk_baseParts")]
-		/// Get all Base's parts
 		fn base_parts(&self, base_id: RmrkBaseId, at: Option<BlockHash>) -> Result<Vec<PartType>>;
 
+		/// Get the theme names belonging to a base.
 		#[method(name = "rmrk_themeNames")]
 		fn theme_names(
 			&self,
@@ -320,6 +355,7 @@
 			at: Option<BlockHash>,
 		) -> Result<Vec<RmrkThemeName>>;
 
+		/// Get theme info, including properties, optionally limited to the provided keys.
 		#[method(name = "rmrk_themes")]
 		fn theme(
 			&self,
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -441,7 +441,7 @@
 			u128,
 		),
 
-		/// The colletion property has been set.
+		/// The colletion property has been added or edited.
 		CollectionPropertySet(
 			/// Id of collection to which property has been set.
 			CollectionId,
@@ -457,7 +457,7 @@
 			PropertyKey,
 		),
 
-		/// The token property has been set.
+		/// The token property has been added or edited.
 		TokenPropertySet(
 			/// Identifier of the collection whose token has the property set.
 			CollectionId,
@@ -477,9 +477,9 @@
 			PropertyKey,
 		),
 
-		/// The colletion property permission has been set.
+		/// The token property permission of a collection has been set.
 		PropertyPermissionSet(
-			/// Id of collection to which property permission has been set.
+			/// ID of collection to which property permission has been set.
 			CollectionId,
 			/// The property permission that was set.
 			PropertyKey,
@@ -524,26 +524,26 @@
 		/// Metadata flag frozen
 		MetadataFlagFrozen,
 
-		/// Item not exists.
+		/// Item does not exist
 		TokenNotFound,
-		/// Item balance not enough.
+		/// Item is balance not enough
 		TokenValueTooLow,
-		/// Requested value more than approved.
+		/// Requested value is more than the approved
 		ApprovedValueTooLow,
 		/// Tried to approve more than owned
 		CantApproveMoreThanOwned,
 
 		/// Can't transfer tokens to ethereum zero address
 		AddressIsZero,
-		/// Target collection doesn't supports this operation
+		/// Target collection doesn't support this operation
 		UnsupportedOperation,
 
-		/// Not sufficient funds to perform action
+		/// Insufficient funds to perform an action
 		NotSufficientFounds,
 
-		/// User not passed nesting rule
+		/// User does not satisfy the nesting rule
 		UserIsNotAllowedToNest,
-		/// Only tokens from specific collections may nest tokens under this
+		/// Only tokens from specific collections may nest tokens under this one
 		SourceCollectionIsNotAllowedToNest,
 
 		/// Tried to store more data than allowed in collection field
@@ -558,7 +558,7 @@
 		/// Property key is too long
 		PropertyKeyIsTooLong,
 
-		/// Only ASCII letters, digits, and '_', '-' are allowed
+		/// Only ASCII letters, digits, and symbols `_`, `-`, and `.` are allowed
 		InvalidCharacterInPropertyKey,
 
 		/// Empty property keys are forbidden
@@ -571,7 +571,7 @@
 		CollectionIsInternal,
 	}
 
-	/// Storage of the count of created collections.
+	/// Storage of the count of created collections. Essentially contains the last collection ID.
 	#[pallet::storage]
 	pub type CreatedCollectionCount<T> = StorageValue<Value = CollectionId, QueryKind = ValueQuery>;
 
@@ -600,7 +600,7 @@
 		OnEmpty = up_data_structs::CollectionProperties,
 	>;
 
-	/// Storage of collection properties permissions.
+	/// Storage of token property permissions of a collection.
 	#[pallet::storage]
 	#[pallet::getter(fn property_permissions)]
 	pub type CollectionPropertyPermissions<T> = StorageMap<
@@ -610,7 +610,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Storage of collection admins count.
+	/// Storage of the amount of collection admins.
 	#[pallet::storage]
 	pub type AdminAmount<T> = StorageMap<
 		Hasher = Blake2_128Concat,
@@ -619,7 +619,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// List of collection admins
+	/// List of collection admins.
 	#[pallet::storage]
 	pub type IsAdmin<T: Config> = StorageNMap<
 		Key = (
@@ -630,7 +630,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Allowlisted collection users
+	/// Allowlisted collection users.
 	#[pallet::storage]
 	pub type Allowlist<T: Config> = StorageNMap<
 		Key = (
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -119,8 +119,7 @@
 	pub enum Error<T> {
 		/// Not Fungible item data used to mint in Fungible collection.
 		NotFungibleDataUsedToMintFungibleCollectionToken,
-		/// Not default id passed as TokenId argument.
-		/// The default value of TokenId for Fungible collection is 0.
+		/// Fungible tokens hold no ID, and the default value of TokenId for Fungible collection is 0.
 		FungibleItemsHaveNoId,
 		/// Tried to set data for fungible item.
 		FungibleItemsDontHaveData,
@@ -157,7 +156,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Storage for delegated assets.
+	/// Storage for assets delegated to a limited extent to other users.
 	#[pallet::storage]
 	pub type Allowance<T: Config> = StorageNMap<
 		Key = (
@@ -172,7 +171,6 @@
 
 /// Wrapper around untyped collection handle, asserting inner collection is of fungible type.
 /// Required for interaction with Fungible collections, type safety and implementation [`solidity_interface`][`evm_coder::solidity_interface`].
-
 pub struct FungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);
 
 /// Implementation of methods required for dispatching during runtime.
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -21,7 +21,7 @@
 //! - [`Config`]
 //! - [`NonfungibleHandle`]
 //! - [`Pallet`]
-//! - [`CommonWeights`]
+//! - [`CommonWeights`](common::CommonWeights)
 //!
 //! ## Overview
 //!
@@ -130,6 +130,8 @@
 pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
+/// Token data, stored independently from other data used to describe it
+/// for the convenience of database access. Notably contains the owner account address.
 #[struct_versioning::versioned(version = 2, upper)]
 #[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
 pub struct ItemData<CrossAccountId> {
@@ -176,17 +178,17 @@
 	#[pallet::generate_store(pub(super) trait Store)]
 	pub struct Pallet<T>(_);
 
-	/// Amount of tokens minted for collection.
+	/// Total amount of minted tokens in a collection.
 	#[pallet::storage]
 	pub type TokensMinted<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
 
-	/// Amount of burnt tokens for collection.
+	/// Amount of burnt tokens in a collection.
 	#[pallet::storage]
 	pub type TokensBurnt<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
 
-	/// Custom data serialized to bytes for token.
+	/// Token data, used to partially describe a token.
 	#[pallet::storage]
 	pub type TokenData<T: Config> = StorageNMap<
 		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
@@ -194,7 +196,7 @@
 		QueryKind = OptionQuery,
 	>;
 
-	/// Key-Value map stored for token.
+	/// Map of key-value pairs, describing the metadata of a token.
 	#[pallet::storage]
 	#[pallet::getter(fn token_properties)]
 	pub type TokenProperties<T: Config> = StorageNMap<
@@ -204,7 +206,14 @@
 		OnEmpty = up_data_structs::TokenProperties,
 	>;
 
-	/// Custom data that is serialized to bytes and attached to a token property.
+	/// Custom data of a token that is serialized to bytes,
+	/// primarily reserved for on-chain operations,
+	/// normally obscured from the external users.
+	///
+	/// Auxiliary properties are slightly different from
+	/// usual [`TokenProperties`] due to an unlimited number
+	/// and separately stored and written-to key-value pairs.
+	///
 	/// Currently used to store RMRK data.
 	#[pallet::storage]
 	#[pallet::getter(fn token_aux_property)]
@@ -244,7 +253,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Amount of tokens owned by account.
+	/// Amount of tokens owned by an account in a collection.
 	#[pallet::storage]
 	pub type AccountBalance<T: Config> = StorageNMap<
 		Key = (
@@ -255,7 +264,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Allowance set by an owner for a spender for a token.
+	/// Allowance set by a token owner for another user to perform one of certain transactions on a token.
 	#[pallet::storage]
 	pub type Allowance<T: Config> = StorageNMap<
 		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
@@ -263,6 +272,7 @@
 		QueryKind = OptionQuery,
 	>;
 
+	/// Upgrade from the old schema to properties.
 	#[pallet::hooks]
 	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
 		fn on_runtime_upgrade() -> Weight {
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -21,7 +21,7 @@
 //! - [`Config`]
 //! - [`RefungibleHandle`]
 //! - [`Pallet`]
-//! - [`CommonWeights`]
+//! - [`CommonWeights`](common::CommonWeights)
 //!
 //! ## Overview
 //!
@@ -119,6 +119,8 @@
 pub mod weights;
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
+/// Token data, stored independently from other data used to describe it
+/// for the convenience of database access. Notably contains the token metadata.
 #[struct_versioning::versioned(version = 2, upper)]
 #[derive(Encode, Decode, Default, TypeInfo, MaxEncodedLen)]
 pub struct ItemData {
@@ -143,13 +145,13 @@
 	pub enum Error<T> {
 		/// Not Refungible item data used to mint in Refungible collection.
 		NotRefungibleDataUsedToMintFungibleCollectionToken,
-		/// Maximum refungibility exceeded
+		/// Maximum refungibility exceeded.
 		WrongRefungiblePieces,
-		/// Refungible token can't be repartitioned by user who isn't owns all pieces
+		/// Refungible token can't be repartitioned by user who isn't owns all pieces.
 		RepartitionWhileNotOwningAllPieces,
-		/// Refungible token can't nest other tokens
+		/// Refungible token can't nest other tokens.
 		RefungibleDisallowsNesting,
-		/// Setting item properties is not allowed
+		/// Setting item properties is not allowed.
 		SettingPropertiesNotAllowed,
 	}
 
@@ -167,17 +169,17 @@
 	#[pallet::generate_store(pub(super) trait Store)]
 	pub struct Pallet<T>(_);
 
-	/// Amount of tokens minted for collection
+	/// Total amount of minted tokens in a collection.
 	#[pallet::storage]
 	pub type TokensMinted<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
 
-	/// Amount of burnt tokens for collection
+	/// Amount of tokens burnt in a collection.
 	#[pallet::storage]
 	pub type TokensBurnt<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
 
-	/// Custom data serialized to bytes for token
+	/// Token data, used to partially describe a token.
 	#[pallet::storage]
 	pub type TokenData<T: Config> = StorageNMap<
 		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
@@ -185,6 +187,7 @@
 		QueryKind = ValueQuery,
 	>;
 
+	/// Amount of pieces a refungible token is split into.
 	#[pallet::storage]
 	#[pallet::getter(fn token_properties)]
 	pub type TokenProperties<T: Config> = StorageNMap<
@@ -202,7 +205,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Used to enumerate tokens owned by account
+	/// Used to enumerate tokens owned by account.
 	#[pallet::storage]
 	pub type Owned<T: Config> = StorageNMap<
 		Key = (
@@ -214,7 +217,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Amount of tokens owned by account
+	/// Amount of tokens (not pieces) partially owned by an account within a collection.
 	#[pallet::storage]
 	pub type AccountBalance<T: Config> = StorageNMap<
 		Key = (
@@ -226,7 +229,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Amount of token pieces owned by account
+	/// Amount of token pieces owned by account.
 	#[pallet::storage]
 	pub type Balance<T: Config> = StorageNMap<
 		Key = (
@@ -239,7 +242,7 @@
 		QueryKind = ValueQuery,
 	>;
 
-	/// Allowance set by an owner for a spender for a token
+	/// Allowance set by a token owner for another user to perform one of certain transactions on a number of pieces of a token.
 	#[pallet::storage]
 	pub type Allowance<T: Config> = StorageNMap<
 		Key = (
modifiedpallets/scheduler/src/lib.rsdiffbeforeafterboth
before · pallets/scheduler/src/lib.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// This file is part of Substrate.1920// Copyright (C) 2017-2022 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// 	http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435//! # Unique scheduler36//! A Pallet for scheduling dispatches.37//!38//! - [`Config`]39//! - [`Call`]40//! - [`Pallet`]41//!42//! ## Overview43//!44//! This Pallet exposes capabilities for scheduling dispatches to occur at a45//! specified block number or at a specified period. These scheduled dispatches46//! should be named and may be canceled.47//!48//! **NOTE:** The unique scheduler is designed for deferred transaction calls by block number.49//! Any user can book a call of a certain transaction to a specific block number.50//! Also possible to book a call with a certain frequency.51//!52//! Key differences from the original pallet:53//! https://crates.io/crates/pallet-scheduler54//! Schedule Id restricted by 16 bytes. Identificator for booked call.55//! Priority limited by HARD DEADLINE (<= 63). Calls over maximum weight don't include to block.56//! The maximum weight that may be scheduled per block for any dispatchables of less priority than `schedule::HARD_DEADLINE`.57//! Maybe_periodic limit is 100 calls. Reserved for future sponsored transaction support.58//! At 100 calls reserved amount is not so much and this is avoid potential problems with balance locks.59//! Any account allowed to schedule any calls. Account withdraw implemented through default transaction logic.60//!61//! ## Interface62//!63//! ### Dispatchable Functions64//!65//! * `schedule_named` - augments the `schedule` interface with an additional `Vec<u8>` parameter66//!   that can be used for identification.67//! * `cancel_named` - the named complement to the cancel function.6869// Ensure we're `no_std` when compiling for Wasm.70#![cfg_attr(not(feature = "std"), no_std)]7172#[cfg(feature = "runtime-benchmarks")]73mod benchmarking;7475pub mod weights;7677use sp_core::H160;78use codec::{Codec, Decode, Encode};79use frame_system::{self as system, ensure_signed};80pub use pallet::*;81use scale_info::TypeInfo;82use sp_runtime::{83	traits::{BadOrigin, One, Saturating, Zero},84	RuntimeDebug, DispatchErrorWithPostInfo,85};86use sp_std::{borrow::Borrow, cmp::Ordering, marker::PhantomData, prelude::*};8788use frame_support::{89	dispatch::{DispatchError, DispatchResult, Dispatchable, Parameter},90	traits::{91		schedule::{self, DispatchTime, MaybeHashed},92		NamedReservableCurrency, EnsureOrigin, Get, IsType, OriginTrait, PrivilegeCmp,93		StorageVersion,94	},95	weights::{GetDispatchInfo, Weight},96};9798pub use weights::WeightInfo;99100/// Just a simple index for naming period tasks.101pub type PeriodicIndex = u32;102/// The location of a scheduled task that can be used to remove it.103pub type TaskAddress<BlockNumber> = (BlockNumber, u32);104pub const MAX_TASK_ID_LENGTH_IN_BYTES: u8 = 16;105106type ScheduledId = [u8; MAX_TASK_ID_LENGTH_IN_BYTES as usize];107pub type CallOrHashOf<T> = MaybeHashed<<T as Config>::Call, <T as frame_system::Config>::Hash>;108109/// Information regarding an item to be executed in the future.110#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq))]111#[derive(Clone, RuntimeDebug, Encode, Decode, TypeInfo)]112pub struct ScheduledV3<Call, BlockNumber, PalletsOrigin, AccountId> {113	/// The unique identity for this task, if there is one.114	maybe_id: Option<ScheduledId>,115	/// This task's priority.116	priority: schedule::Priority,117	/// The call to be dispatched.118	call: Call,119	/// If the call is periodic, then this points to the information concerning that.120	maybe_periodic: Option<schedule::Period<BlockNumber>>,121	/// The origin to dispatch the call.122	origin: PalletsOrigin,123	_phantom: PhantomData<AccountId>,124}125126pub type ScheduledV3Of<T> = ScheduledV3<127	CallOrHashOf<T>,128	<T as frame_system::Config>::BlockNumber,129	<T as Config>::PalletsOrigin,130	<T as frame_system::Config>::AccountId,131>;132133pub type ScheduledOf<T> = ScheduledV3Of<T>;134135/// The current version of Scheduled struct.136pub type Scheduled<Call, BlockNumber, PalletsOrigin, AccountId> =137	ScheduledV3<Call, BlockNumber, PalletsOrigin, AccountId>;138139#[cfg(feature = "runtime-benchmarks")]140mod preimage_provider {141	use frame_support::traits::PreimageRecipient;142	pub trait PreimageProviderAndMaybeRecipient<H>: PreimageRecipient<H> {}143	impl<H, T: PreimageRecipient<H>> PreimageProviderAndMaybeRecipient<H> for T {}144}145146#[cfg(not(feature = "runtime-benchmarks"))]147mod preimage_provider {148	use frame_support::traits::PreimageProvider;149	pub trait PreimageProviderAndMaybeRecipient<H>: PreimageProvider<H> {}150	impl<H, T: PreimageProvider<H>> PreimageProviderAndMaybeRecipient<H> for T {}151}152153pub use preimage_provider::PreimageProviderAndMaybeRecipient;154155pub(crate) trait MarginalWeightInfo: WeightInfo {156	fn item(periodic: bool, named: bool, resolved: Option<bool>) -> Weight {157		match (periodic, named, resolved) {158			(_, false, None) => Self::on_initialize_aborted(2) - Self::on_initialize_aborted(1),159			(_, true, None) => {160				Self::on_initialize_named_aborted(2) - Self::on_initialize_named_aborted(1)161			}162			(false, false, Some(false)) => Self::on_initialize(2) - Self::on_initialize(1),163			(false, true, Some(false)) => {164				Self::on_initialize_named(2) - Self::on_initialize_named(1)165			}166			(true, false, Some(false)) => {167				Self::on_initialize_periodic(2) - Self::on_initialize_periodic(1)168			}169			(true, true, Some(false)) => {170				Self::on_initialize_periodic_named_resolved(2)171					- Self::on_initialize_periodic_named_resolved(1)172			}173			(false, false, Some(true)) => Self::on_initialize(2) - Self::on_initialize(1),174			(false, true, Some(true)) => {175				Self::on_initialize_named_resolved(2) - Self::on_initialize_named_resolved(1)176			}177			(true, false, Some(true)) => {178				Self::on_initialize_periodic_resolved(2) - Self::on_initialize_periodic_resolved(1)179			}180			(true, true, Some(true)) => {181				Self::on_initialize_periodic_named_resolved(2)182					- Self::on_initialize_periodic_named_resolved(1)183			}184		}185	}186}187impl<T: WeightInfo> MarginalWeightInfo for T {}188189#[frame_support::pallet]190pub mod pallet {191	use super::*;192	use frame_support::{193		dispatch::PostDispatchInfo,194		pallet_prelude::*,195		traits::{schedule::LookupError, PreimageProvider},196	};197	use frame_system::pallet_prelude::*;198199	/// The current storage version.200	const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);201202	#[pallet::pallet]203	#[pallet::generate_store(pub(super) trait Store)]204	#[pallet::storage_version(STORAGE_VERSION)]205	#[pallet::without_storage_info]206	pub struct Pallet<T>(_);207208	/// `system::Config` should always be included in our implied traits.209	#[pallet::config]210	pub trait Config: frame_system::Config {211		/// The overarching event type.212		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;213214		/// The aggregated origin which the dispatch will take.215		type Origin: OriginTrait<PalletsOrigin = Self::PalletsOrigin>216			+ From<Self::PalletsOrigin>217			+ IsType<<Self as system::Config>::Origin>;218219		/// The caller origin, overarching type of all pallets origins.220		type PalletsOrigin: From<system::RawOrigin<Self::AccountId>> + Codec + Clone + Eq + TypeInfo;221222		type Currency: NamedReservableCurrency<Self::AccountId, ReserveIdentifier = ScheduledId>;223224		/// The aggregated call type.225		type Call: Parameter226			+ Dispatchable<Origin = <Self as Config>::Origin, PostInfo = PostDispatchInfo>227			+ GetDispatchInfo228			+ From<system::Call<Self>>;229230		/// The maximum weight that may be scheduled per block for any dispatchables of less231		/// priority than `schedule::HARD_DEADLINE`.232		#[pallet::constant]233		type MaximumWeight: Get<Weight>;234235		/// Required origin to schedule or cancel calls.236		type ScheduleOrigin: EnsureOrigin<<Self as system::Config>::Origin>;237238		/// Compare the privileges of origins.239		///240		/// This will be used when canceling a task, to ensure that the origin that tries241		/// to cancel has greater or equal privileges as the origin that created the scheduled task.242		///243		/// For simplicity the [`EqualPrivilegeOnly`](frame_support::traits::EqualPrivilegeOnly) can244		/// be used. This will only check if two given origins are equal.245		type OriginPrivilegeCmp: PrivilegeCmp<Self::PalletsOrigin>;246247		/// The maximum number of scheduled calls in the queue for a single block.248		/// Not strictly enforced, but used for weight estimation.249		#[pallet::constant]250		type MaxScheduledPerBlock: Get<u32>;251252		/// Weight information for extrinsics in this pallet.253		type WeightInfo: WeightInfo;254255		/// The preimage provider with which we look up call hashes to get the call.256		type PreimageProvider: PreimageProviderAndMaybeRecipient<Self::Hash>;257258		/// If `Some` then the number of blocks to postpone execution for when the item is delayed.259		type NoPreimagePostponement: Get<Option<Self::BlockNumber>>;260261		/// Sponsoring function.262		// type SponsorshipHandler: SponsorshipHandler<Self::AccountId, <Self as Config>::Call>;263264		/// The helper type used for custom transaction fee logic.265		type CallExecutor: DispatchCall<Self, H160>;266	}267268	/// A Scheduler-Runtime interface for finer payment handling.269	pub trait DispatchCall<T: frame_system::Config + Config, SelfContainedSignedInfo> {270		fn reserve_balance(271			id: ScheduledId,272			sponsor: <T as frame_system::Config>::AccountId,273			call: <T as Config>::Call,274			count: u32,275		) -> Result<(), DispatchError>;276277		/// Unlock centain amount from payer278		fn pay_for_call(279			id: ScheduledId,280			sponsor: <T as frame_system::Config>::AccountId,281			call: <T as Config>::Call,282		) -> Result<u128, DispatchError>;283284		/// Resolve the call dispatch, including any post-dispatch operations.285		fn dispatch_call(286			signer: T::AccountId,287			function: <T as Config>::Call,288		) -> Result<289			Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,290			TransactionValidityError,291		>;292293		fn cancel_reserve(294			id: ScheduledId,295			sponsor: <T as frame_system::Config>::AccountId,296		) -> Result<u128, DispatchError>;297	}298299	/// Items to be executed, indexed by the block number that they should be executed on.300	#[pallet::storage]301	pub type Agenda<T: Config> =302		StorageMap<_, Twox64Concat, T::BlockNumber, Vec<Option<ScheduledV3Of<T>>>, ValueQuery>;303304	/// Lookup from identity to the block number and index of the task.305	#[pallet::storage]306	pub(crate) type Lookup<T: Config> =307		StorageMap<_, Twox64Concat, ScheduledId, TaskAddress<T::BlockNumber>>;308309	/// Events type.310	#[pallet::event]311	#[pallet::generate_deposit(pub(super) fn deposit_event)]312	pub enum Event<T: Config> {313		/// Scheduled some task.314		Scheduled { when: T::BlockNumber, index: u32 },315		/// Canceled some task.316		Canceled { when: T::BlockNumber, index: u32 },317		/// Dispatched some task.318		Dispatched {319			task: TaskAddress<T::BlockNumber>,320			id: Option<ScheduledId>,321			result: DispatchResult,322		},323		/// The call for the provided hash was not found so the task has been aborted.324		CallLookupFailed {325			task: TaskAddress<T::BlockNumber>,326			id: Option<ScheduledId>,327			error: LookupError,328		},329	}330331	#[pallet::error]332	pub enum Error<T> {333		/// Failed to schedule a call334		FailedToSchedule,335		/// Cannot find the scheduled call.336		NotFound,337		/// Given target block number is in the past.338		TargetBlockNumberInPast,339		/// Reschedule failed because it does not change scheduled time.340		RescheduleNoChange,341	}342343	#[pallet::hooks]344	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {345		/// Execute the scheduled calls346		fn on_initialize(now: T::BlockNumber) -> Weight {347			let limit = T::MaximumWeight::get();348349			let mut queued = Agenda::<T>::take(now)350				.into_iter()351				.enumerate()352				.filter_map(|(index, s)| Some((index as u32, s?)))353				.collect::<Vec<_>>();354355			if queued.len() as u32 > T::MaxScheduledPerBlock::get() {356				log::warn!(357					target: "runtime::scheduler",358					"Warning: This block has more items queued in Scheduler than \359					expected from the runtime configuration. An update might be needed."360				);361			}362363			queued.sort_by_key(|(_, s)| s.priority);364365			let next = now + One::one();366367			let mut total_weight: Weight = T::WeightInfo::on_initialize(0);368			for (order, (index, mut s)) in queued.into_iter().enumerate() {369				let named = if let Some(ref id) = s.maybe_id {370					Lookup::<T>::remove(id);371					true372				} else {373					false374				};375376				let (call, maybe_completed) = s.call.resolved::<T::PreimageProvider>();377				s.call = call;378379				let resolved = if let Some(completed) = maybe_completed {380					T::PreimageProvider::unrequest_preimage(&completed);381					true382				} else {383					false384				};385				let call = match s.call.as_value().cloned() {386					Some(c) => c,387					None => {388						// Preimage not available - postpone until some block.389						total_weight.saturating_accrue(T::WeightInfo::item(false, named, None));390						if let Some(delay) = T::NoPreimagePostponement::get() {391							let until = now.saturating_add(delay);392							if let Some(ref id) = s.maybe_id {393								let index = Agenda::<T>::decode_len(until).unwrap_or(0);394								Lookup::<T>::insert(id, (until, index as u32));395							}396							Agenda::<T>::append(until, Some(s));397						}398						continue;399					}400				};401402				let periodic = s.maybe_periodic.is_some();403				let call_weight = call.get_dispatch_info().weight;404				let mut item_weight = T::WeightInfo::item(periodic, named, Some(resolved));405				let origin =406					<<T as Config>::Origin as From<T::PalletsOrigin>>::from(s.origin.clone())407						.into();408				if ensure_signed(origin).is_ok() {409					// Weights of Signed dispatches expect their signing account to be whitelisted.410					item_weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));411				}412413				// We allow a scheduled call if any is true:414				// - It's priority is `HARD_DEADLINE`415				// - It does not push the weight past the limit.416				// - It is the first item in the schedule417				let hard_deadline = s.priority <= schedule::HARD_DEADLINE;418				let test_weight = total_weight419					.saturating_add(call_weight)420					.saturating_add(item_weight);421				if !hard_deadline && order > 0 && test_weight > limit {422					// Cannot be scheduled this block - postpone until next.423					total_weight.saturating_accrue(T::WeightInfo::item(false, named, None));424					if let Some(ref id) = s.maybe_id {425						// NOTE: We could reasonably not do this (in which case there would be one426						// block where the named and delayed item could not be referenced by name),427						// but we will do it anyway since it should be mostly free in terms of428						// weight and it is slightly cleaner.429						let index = Agenda::<T>::decode_len(next).unwrap_or(0);430						Lookup::<T>::insert(id, (next, index as u32));431					}432					Agenda::<T>::append(next, Some(s));433					continue;434				}435436				let sender = ensure_signed(437					<<T as Config>::Origin as From<T::PalletsOrigin>>::from(s.origin.clone())438						.into(),439				)440				.unwrap();441442				// // if call have id it was be reserved443				// if s.maybe_id.is_some() {444				// 	let _ = T::CallExecutor::pay_for_call(445				// 		s.maybe_id.unwrap(),446				// 		sender.clone(),447				// 		call.clone(),448				// 	);449				// }450451				// Execute transaction via chain default pipeline452				// That means dispatch will be processed like any user's extrinsic e.g. transaction fees will be taken453				let r = T::CallExecutor::dispatch_call(sender, call.clone());454455				let mut actual_call_weight: Weight = item_weight;456				let result: Result<_, DispatchError> = match r {457					Ok(o) => match o {458						Ok(di) => {459							actual_call_weight = di.actual_weight.unwrap_or(item_weight);460							Ok(())461						}462						Err(err) => Err(err.error),463					},464					Err(_) => {465						log::error!(466							target: "runtime::scheduler",467							"Warning: Scheduler has failed to execute a post-dispatch transaction. \468							This block might have become invalid.");469						Err(DispatchError::CannotLookup)470					} // todo possibly force a skip/return here, do something with the error471				};472473				total_weight.saturating_accrue(item_weight);474				total_weight.saturating_accrue(actual_call_weight);475476				Self::deposit_event(Event::Dispatched {477					task: (now, index),478					id: s.maybe_id.clone(),479					result,480				});481482				if let &Some((period, count)) = &s.maybe_periodic {483					if count > 1 {484						s.maybe_periodic = Some((period, count - 1));485					} else {486						s.maybe_periodic = None;487					}488					let wake = now + period;489					// If scheduled is named, place its information in `Lookup`490					if let Some(ref id) = s.maybe_id {491						let wake_index = Agenda::<T>::decode_len(wake).unwrap_or(0);492						Lookup::<T>::insert(id, (wake, wake_index as u32));493					}494					Agenda::<T>::append(wake, Some(s));495				}496			}497			/// Weight should be 0, because transaction already paid498			0499			//total_weight500		}501	}502503	#[pallet::call]504	impl<T: Config> Pallet<T> {505		/// Schedule a named task.506		#[pallet::weight(<T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))]507		pub fn schedule_named(508			origin: OriginFor<T>,509			id: ScheduledId,510			when: T::BlockNumber,511			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,512			priority: schedule::Priority,513			call: Box<CallOrHashOf<T>>,514		) -> DispatchResult {515			T::ScheduleOrigin::ensure_origin(origin.clone())?;516			let origin = <T as Config>::Origin::from(origin);517			Self::do_schedule_named(518				id,519				DispatchTime::At(when),520				maybe_periodic,521				priority,522				origin.caller().clone(),523				*call,524			)?;525			Ok(())526		}527528		/// Cancel a named scheduled task.529		#[pallet::weight(<T as Config>::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get()))]530		pub fn cancel_named(origin: OriginFor<T>, id: ScheduledId) -> DispatchResult {531			T::ScheduleOrigin::ensure_origin(origin.clone())?;532			let origin = <T as Config>::Origin::from(origin);533			Self::do_cancel_named(Some(origin.caller().clone()), id)?;534			Ok(())535		}536537		/// Schedule a named task after a delay.538		///539		/// # <weight>540		/// Same as [`schedule_named`](Self::schedule_named).541		/// # </weight>542		#[pallet::weight(<T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))]543		pub fn schedule_named_after(544			origin: OriginFor<T>,545			id: ScheduledId,546			after: T::BlockNumber,547			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,548			priority: schedule::Priority,549			call: Box<CallOrHashOf<T>>,550		) -> DispatchResult {551			T::ScheduleOrigin::ensure_origin(origin.clone())?;552			let origin = <T as Config>::Origin::from(origin);553			Self::do_schedule_named(554				id,555				DispatchTime::After(after),556				maybe_periodic,557				priority,558				origin.caller().clone(),559				*call,560			)?;561			Ok(())562		}563	}564}565566impl<T: Config> Pallet<T> {567	#[cfg(feature = "try-runtime")]568	pub fn pre_migrate_to_v3() -> Result<(), &'static str> {569		Ok(())570	}571572	#[cfg(feature = "try-runtime")]573	pub fn post_migrate_to_v3() -> Result<(), &'static str> {574		use frame_support::dispatch::GetStorageVersion;575576		assert!(Self::current_storage_version() == 3);577		for k in Agenda::<T>::iter_keys() {578			let _ = Agenda::<T>::try_get(k).map_err(|()| "Invalid item in Agenda")?;579		}580		Ok(())581	}582583	/// Helper to migrate scheduler when the pallet origin type has changed.584	pub fn migrate_origin<OldOrigin: Into<T::PalletsOrigin> + codec::Decode>() {585		Agenda::<T>::translate::<586			Vec<Option<Scheduled<CallOrHashOf<T>, T::BlockNumber, OldOrigin, T::AccountId>>>,587			_,588		>(|_, agenda| {589			Some(590				agenda591					.into_iter()592					.map(|schedule| {593						schedule.map(|schedule| Scheduled {594							maybe_id: schedule.maybe_id,595							priority: schedule.priority,596							call: schedule.call,597							maybe_periodic: schedule.maybe_periodic,598							origin: schedule.origin.into(),599							_phantom: Default::default(),600						})601					})602					.collect::<Vec<_>>(),603			)604		});605	}606607	fn resolve_time(when: DispatchTime<T::BlockNumber>) -> Result<T::BlockNumber, DispatchError> {608		let now = frame_system::Pallet::<T>::block_number();609610		let when = match when {611			DispatchTime::At(x) => x,612			// The current block has already completed it's scheduled tasks, so613			// Schedule the task at lest one block after this current block.614			DispatchTime::After(x) => now.saturating_add(x).saturating_add(One::one()),615		};616617		if when <= now {618			return Err(Error::<T>::TargetBlockNumberInPast.into());619		}620621		Ok(when)622	}623624	fn do_schedule_named(625		id: ScheduledId,626		when: DispatchTime<T::BlockNumber>,627		maybe_periodic: Option<schedule::Period<T::BlockNumber>>,628		priority: schedule::Priority,629		origin: T::PalletsOrigin,630		call: CallOrHashOf<T>,631	) -> Result<TaskAddress<T::BlockNumber>, DispatchError> {632		// ensure id it is unique633		if Lookup::<T>::contains_key(&id) {634			return Err(Error::<T>::FailedToSchedule)?;635		}636637		let when = Self::resolve_time(when)?;638639		call.ensure_requested::<T::PreimageProvider>();640641		// sanitize maybe_periodic642		let maybe_periodic = maybe_periodic643			.filter(|p| p.1 > 1 && !p.0.is_zero())644			// Remove one from the number of repetitions since we will schedule one now.645			.map(|(p, c)| (p, c - 1));646647		let s = Scheduled {648			maybe_id: Some(id.clone()),649			priority,650			call: call.clone(),651			maybe_periodic,652			origin: origin.clone(),653			_phantom: Default::default(),654		};655656		// reserve balance for periodic execution657		// let sender =658		// 	ensure_signed(<<T as Config>::Origin as From<T::PalletsOrigin>>::from(origin).into())?;659		// let repeats = match maybe_periodic {660		// 	Some(p) => p.1,661		// 	None => 1,662		// };663		// let _ = T::CallExecutor::reserve_balance(664		// 	id.clone(),665		// 	sender,666		// 	call.as_value().unwrap().clone(),667		// 	repeats,668		// );669670		Agenda::<T>::append(when, Some(s));671		let index = Agenda::<T>::decode_len(when).unwrap_or(1) as u32 - 1;672		let address = (when, index);673		Lookup::<T>::insert(&id, &address);674		Self::deposit_event(Event::Scheduled { when, index });675676		Ok(address)677	}678679	fn do_cancel_named(origin: Option<T::PalletsOrigin>, id: ScheduledId) -> DispatchResult {680		Lookup::<T>::try_mutate_exists(id, |lookup| -> DispatchResult {681			if let Some((when, index)) = lookup.take() {682				let i = index as usize;683				Agenda::<T>::try_mutate(when, |agenda| -> DispatchResult {684					if let Some(s) = agenda.get_mut(i) {685						if let (Some(ref o), Some(ref s)) = (origin.clone(), s.borrow()) {686							if matches!(687								T::OriginPrivilegeCmp::cmp_privilege(o, &s.origin),688								Some(Ordering::Less) | None689							) {690								return Err(BadOrigin.into());691							}692							// release balance reserve693							// let sender = ensure_signed(694							// 	<<T as Config>::Origin as From<T::PalletsOrigin>>::from(695							// 		origin.unwrap(),696							// 	)697							// 	.into(),698							// )?;699							// let _ = T::CallExecutor::cancel_reserve(id, sender);700701							s.call.ensure_unrequested::<T::PreimageProvider>();702						}703						*s = None;704					}705					Ok(())706				})?;707708				Self::deposit_event(Event::Canceled { when, index });709				Ok(())710			} else {711				Err(Error::<T>::NotFound)?712			}713		})714	}715}
after · pallets/scheduler/src/lib.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// This file is part of Substrate.1920// Copyright (C) 2017-2022 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// 	<http://www.apache.org/licenses/LICENSE-2.0>28//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435//! # Unique scheduler36//! A Pallet for scheduling dispatches.37//!38//! - [`Config`]39//! - [`Call`]40//! - [`Pallet`]41//!42//! ## Overview43//!44//! This Pallet exposes capabilities for scheduling dispatches to occur at a45//! specified block number or at a specified period. These scheduled dispatches46//! should be named and may be canceled.47//!48//! **NOTE:** The unique scheduler is designed for deferred transaction calls by block number.49//! Any user can book a call of a certain transaction to a specific block number.50//! Also possible to book a call with a certain frequency.51//!52//! Key differences from the original pallet:53//! <https://crates.io/crates/pallet-scheduler>54//! Schedule Id restricted by 16 bytes. Identificator for booked call.55//! Priority limited by HARD DEADLINE (<= 63). Calls over maximum weight don't include to block.56//! The maximum weight that may be scheduled per block for any dispatchables of less priority than `schedule::HARD_DEADLINE`.57//! Maybe_periodic limit is 100 calls. Reserved for future sponsored transaction support.58//! At 100 calls reserved amount is not so much and this is avoid potential problems with balance locks.59//! Any account allowed to schedule any calls. Account withdraw implemented through default transaction logic.60//!61//! ## Interface62//!63//! ### Dispatchable Functions64//!65//! * `schedule_named` - augments the `schedule` interface with an additional `Vec<u8>` parameter66//!   that can be used for identification.67//! * `cancel_named` - the named complement to the cancel function.6869// Ensure we're `no_std` when compiling for Wasm.70#![cfg_attr(not(feature = "std"), no_std)]7172#[cfg(feature = "runtime-benchmarks")]73mod benchmarking;7475pub mod weights;7677use sp_core::H160;78use codec::{Codec, Decode, Encode};79use frame_system::{self as system, ensure_signed};80pub use pallet::*;81use scale_info::TypeInfo;82use sp_runtime::{83	traits::{BadOrigin, One, Saturating, Zero},84	RuntimeDebug, DispatchErrorWithPostInfo,85};86use sp_std::{borrow::Borrow, cmp::Ordering, marker::PhantomData, prelude::*};8788use frame_support::{89	dispatch::{DispatchError, DispatchResult, Dispatchable, Parameter},90	traits::{91		schedule::{self, DispatchTime, MaybeHashed},92		NamedReservableCurrency, EnsureOrigin, Get, IsType, OriginTrait, PrivilegeCmp,93		StorageVersion,94	},95	weights::{GetDispatchInfo, Weight},96};9798pub use weights::WeightInfo;99100/// Just a simple index for naming period tasks.101pub type PeriodicIndex = u32;102/// The location of a scheduled task that can be used to remove it.103pub type TaskAddress<BlockNumber> = (BlockNumber, u32);104pub const MAX_TASK_ID_LENGTH_IN_BYTES: u8 = 16;105106type ScheduledId = [u8; MAX_TASK_ID_LENGTH_IN_BYTES as usize];107pub type CallOrHashOf<T> = MaybeHashed<<T as Config>::Call, <T as frame_system::Config>::Hash>;108109/// Information regarding an item to be executed in the future.110#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq))]111#[derive(Clone, RuntimeDebug, Encode, Decode, TypeInfo)]112pub struct ScheduledV3<Call, BlockNumber, PalletsOrigin, AccountId> {113	/// The unique identity for this task, if there is one.114	maybe_id: Option<ScheduledId>,115	/// This task's priority.116	priority: schedule::Priority,117	/// The call to be dispatched.118	call: Call,119	/// If the call is periodic, then this points to the information concerning that.120	maybe_periodic: Option<schedule::Period<BlockNumber>>,121	/// The origin to dispatch the call.122	origin: PalletsOrigin,123	_phantom: PhantomData<AccountId>,124}125126pub type ScheduledV3Of<T> = ScheduledV3<127	CallOrHashOf<T>,128	<T as frame_system::Config>::BlockNumber,129	<T as Config>::PalletsOrigin,130	<T as frame_system::Config>::AccountId,131>;132133pub type ScheduledOf<T> = ScheduledV3Of<T>;134135/// The current version of Scheduled struct.136pub type Scheduled<Call, BlockNumber, PalletsOrigin, AccountId> =137	ScheduledV3<Call, BlockNumber, PalletsOrigin, AccountId>;138139#[cfg(feature = "runtime-benchmarks")]140mod preimage_provider {141	use frame_support::traits::PreimageRecipient;142	pub trait PreimageProviderAndMaybeRecipient<H>: PreimageRecipient<H> {}143	impl<H, T: PreimageRecipient<H>> PreimageProviderAndMaybeRecipient<H> for T {}144}145146#[cfg(not(feature = "runtime-benchmarks"))]147mod preimage_provider {148	use frame_support::traits::PreimageProvider;149	pub trait PreimageProviderAndMaybeRecipient<H>: PreimageProvider<H> {}150	impl<H, T: PreimageProvider<H>> PreimageProviderAndMaybeRecipient<H> for T {}151}152153pub use preimage_provider::PreimageProviderAndMaybeRecipient;154155pub(crate) trait MarginalWeightInfo: WeightInfo {156	fn item(periodic: bool, named: bool, resolved: Option<bool>) -> Weight {157		match (periodic, named, resolved) {158			(_, false, None) => Self::on_initialize_aborted(2) - Self::on_initialize_aborted(1),159			(_, true, None) => {160				Self::on_initialize_named_aborted(2) - Self::on_initialize_named_aborted(1)161			}162			(false, false, Some(false)) => Self::on_initialize(2) - Self::on_initialize(1),163			(false, true, Some(false)) => {164				Self::on_initialize_named(2) - Self::on_initialize_named(1)165			}166			(true, false, Some(false)) => {167				Self::on_initialize_periodic(2) - Self::on_initialize_periodic(1)168			}169			(true, true, Some(false)) => {170				Self::on_initialize_periodic_named_resolved(2)171					- Self::on_initialize_periodic_named_resolved(1)172			}173			(false, false, Some(true)) => Self::on_initialize(2) - Self::on_initialize(1),174			(false, true, Some(true)) => {175				Self::on_initialize_named_resolved(2) - Self::on_initialize_named_resolved(1)176			}177			(true, false, Some(true)) => {178				Self::on_initialize_periodic_resolved(2) - Self::on_initialize_periodic_resolved(1)179			}180			(true, true, Some(true)) => {181				Self::on_initialize_periodic_named_resolved(2)182					- Self::on_initialize_periodic_named_resolved(1)183			}184		}185	}186}187impl<T: WeightInfo> MarginalWeightInfo for T {}188189#[frame_support::pallet]190pub mod pallet {191	use super::*;192	use frame_support::{193		dispatch::PostDispatchInfo,194		pallet_prelude::*,195		traits::{schedule::LookupError, PreimageProvider},196	};197	use frame_system::pallet_prelude::*;198199	/// The current storage version.200	const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);201202	#[pallet::pallet]203	#[pallet::generate_store(pub(super) trait Store)]204	#[pallet::storage_version(STORAGE_VERSION)]205	#[pallet::without_storage_info]206	pub struct Pallet<T>(_);207208	/// `system::Config` should always be included in our implied traits.209	#[pallet::config]210	pub trait Config: frame_system::Config {211		/// The overarching event type.212		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;213214		/// The aggregated origin which the dispatch will take.215		type Origin: OriginTrait<PalletsOrigin = Self::PalletsOrigin>216			+ From<Self::PalletsOrigin>217			+ IsType<<Self as system::Config>::Origin>;218219		/// The caller origin, overarching type of all pallets origins.220		type PalletsOrigin: From<system::RawOrigin<Self::AccountId>> + Codec + Clone + Eq + TypeInfo;221222		type Currency: NamedReservableCurrency<Self::AccountId, ReserveIdentifier = ScheduledId>;223224		/// The aggregated call type.225		type Call: Parameter226			+ Dispatchable<Origin = <Self as Config>::Origin, PostInfo = PostDispatchInfo>227			+ GetDispatchInfo228			+ From<system::Call<Self>>;229230		/// The maximum weight that may be scheduled per block for any dispatchables of less231		/// priority than `schedule::HARD_DEADLINE`.232		#[pallet::constant]233		type MaximumWeight: Get<Weight>;234235		/// Required origin to schedule or cancel calls.236		type ScheduleOrigin: EnsureOrigin<<Self as system::Config>::Origin>;237238		/// Compare the privileges of origins.239		///240		/// This will be used when canceling a task, to ensure that the origin that tries241		/// to cancel has greater or equal privileges as the origin that created the scheduled task.242		///243		/// For simplicity the [`EqualPrivilegeOnly`](frame_support::traits::EqualPrivilegeOnly) can244		/// be used. This will only check if two given origins are equal.245		type OriginPrivilegeCmp: PrivilegeCmp<Self::PalletsOrigin>;246247		/// The maximum number of scheduled calls in the queue for a single block.248		/// Not strictly enforced, but used for weight estimation.249		#[pallet::constant]250		type MaxScheduledPerBlock: Get<u32>;251252		/// Weight information for extrinsics in this pallet.253		type WeightInfo: WeightInfo;254255		/// The preimage provider with which we look up call hashes to get the call.256		type PreimageProvider: PreimageProviderAndMaybeRecipient<Self::Hash>;257258		/// If `Some` then the number of blocks to postpone execution for when the item is delayed.259		type NoPreimagePostponement: Get<Option<Self::BlockNumber>>;260261		/// Sponsoring function.262		// type SponsorshipHandler: SponsorshipHandler<Self::AccountId, <Self as Config>::Call>;263264		/// The helper type used for custom transaction fee logic.265		type CallExecutor: DispatchCall<Self, H160>;266	}267268	/// A Scheduler-Runtime interface for finer payment handling.269	pub trait DispatchCall<T: frame_system::Config + Config, SelfContainedSignedInfo> {270		/// Reserve (lock) the maximum spendings on a call, calculated from its weight and the repetition count.271		fn reserve_balance(272			id: ScheduledId,273			sponsor: <T as frame_system::Config>::AccountId,274			call: <T as Config>::Call,275			count: u32,276		) -> Result<(), DispatchError>;277278		/// Unreserve (unlock) a certain amount from the payer's reserved funds, returning the change.279		fn pay_for_call(280			id: ScheduledId,281			sponsor: <T as frame_system::Config>::AccountId,282			call: <T as Config>::Call,283		) -> Result<u128, DispatchError>;284285		/// Resolve the call dispatch, including any post-dispatch operations.286		fn dispatch_call(287			signer: T::AccountId,288			function: <T as Config>::Call,289		) -> Result<290			Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,291			TransactionValidityError,292		>;293294		/// Release unspent reserved funds in case of a schedule cancel.295		fn cancel_reserve(296			id: ScheduledId,297			sponsor: <T as frame_system::Config>::AccountId,298		) -> Result<u128, DispatchError>;299	}300301	/// Items to be executed, indexed by the block number that they should be executed on.302	#[pallet::storage]303	pub type Agenda<T: Config> =304		StorageMap<_, Twox64Concat, T::BlockNumber, Vec<Option<ScheduledV3Of<T>>>, ValueQuery>;305306	/// Lookup from identity to the block number and index of the task.307	#[pallet::storage]308	pub(crate) type Lookup<T: Config> =309		StorageMap<_, Twox64Concat, ScheduledId, TaskAddress<T::BlockNumber>>;310311	/// Events type.312	#[pallet::event]313	#[pallet::generate_deposit(pub(super) fn deposit_event)]314	pub enum Event<T: Config> {315		/// Scheduled some task.316		Scheduled { when: T::BlockNumber, index: u32 },317		/// Canceled some task.318		Canceled { when: T::BlockNumber, index: u32 },319		/// Dispatched some task.320		Dispatched {321			task: TaskAddress<T::BlockNumber>,322			id: Option<ScheduledId>,323			result: DispatchResult,324		},325		/// The call for the provided hash was not found so the task has been aborted.326		CallLookupFailed {327			task: TaskAddress<T::BlockNumber>,328			id: Option<ScheduledId>,329			error: LookupError,330		},331	}332333	#[pallet::error]334	pub enum Error<T> {335		/// Failed to schedule a call336		FailedToSchedule,337		/// Cannot find the scheduled call.338		NotFound,339		/// Given target block number is in the past.340		TargetBlockNumberInPast,341		/// Reschedule failed because it does not change scheduled time.342		RescheduleNoChange,343	}344345	#[pallet::hooks]346	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {347		/// Execute the scheduled calls348		fn on_initialize(now: T::BlockNumber) -> Weight {349			let limit = T::MaximumWeight::get();350351			let mut queued = Agenda::<T>::take(now)352				.into_iter()353				.enumerate()354				.filter_map(|(index, s)| Some((index as u32, s?)))355				.collect::<Vec<_>>();356357			if queued.len() as u32 > T::MaxScheduledPerBlock::get() {358				log::warn!(359					target: "runtime::scheduler",360					"Warning: This block has more items queued in Scheduler than \361					expected from the runtime configuration. An update might be needed."362				);363			}364365			queued.sort_by_key(|(_, s)| s.priority);366367			let next = now + One::one();368369			let mut total_weight: Weight = T::WeightInfo::on_initialize(0);370			for (order, (index, mut s)) in queued.into_iter().enumerate() {371				let named = if let Some(ref id) = s.maybe_id {372					Lookup::<T>::remove(id);373					true374				} else {375					false376				};377378				let (call, maybe_completed) = s.call.resolved::<T::PreimageProvider>();379				s.call = call;380381				let resolved = if let Some(completed) = maybe_completed {382					T::PreimageProvider::unrequest_preimage(&completed);383					true384				} else {385					false386				};387				let call = match s.call.as_value().cloned() {388					Some(c) => c,389					None => {390						// Preimage not available - postpone until some block.391						total_weight.saturating_accrue(T::WeightInfo::item(false, named, None));392						if let Some(delay) = T::NoPreimagePostponement::get() {393							let until = now.saturating_add(delay);394							if let Some(ref id) = s.maybe_id {395								let index = Agenda::<T>::decode_len(until).unwrap_or(0);396								Lookup::<T>::insert(id, (until, index as u32));397							}398							Agenda::<T>::append(until, Some(s));399						}400						continue;401					}402				};403404				let periodic = s.maybe_periodic.is_some();405				let call_weight = call.get_dispatch_info().weight;406				let mut item_weight = T::WeightInfo::item(periodic, named, Some(resolved));407				let origin =408					<<T as Config>::Origin as From<T::PalletsOrigin>>::from(s.origin.clone())409						.into();410				if ensure_signed(origin).is_ok() {411					// Weights of Signed dispatches expect their signing account to be whitelisted.412					item_weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));413				}414415				// We allow a scheduled call if any is true:416				// - It's priority is `HARD_DEADLINE`417				// - It does not push the weight past the limit.418				// - It is the first item in the schedule419				let hard_deadline = s.priority <= schedule::HARD_DEADLINE;420				let test_weight = total_weight421					.saturating_add(call_weight)422					.saturating_add(item_weight);423				if !hard_deadline && order > 0 && test_weight > limit {424					// Cannot be scheduled this block - postpone until next.425					total_weight.saturating_accrue(T::WeightInfo::item(false, named, None));426					if let Some(ref id) = s.maybe_id {427						// NOTE: We could reasonably not do this (in which case there would be one428						// block where the named and delayed item could not be referenced by name),429						// but we will do it anyway since it should be mostly free in terms of430						// weight and it is slightly cleaner.431						let index = Agenda::<T>::decode_len(next).unwrap_or(0);432						Lookup::<T>::insert(id, (next, index as u32));433					}434					Agenda::<T>::append(next, Some(s));435					continue;436				}437438				let sender = ensure_signed(439					<<T as Config>::Origin as From<T::PalletsOrigin>>::from(s.origin.clone())440						.into(),441				)442				.unwrap();443444				// // if call have id it was be reserved445				// if s.maybe_id.is_some() {446				// 	let _ = T::CallExecutor::pay_for_call(447				// 		s.maybe_id.unwrap(),448				// 		sender.clone(),449				// 		call.clone(),450				// 	);451				// }452453				// Execute transaction via chain default pipeline454				// That means dispatch will be processed like any user's extrinsic e.g. transaction fees will be taken455				let r = T::CallExecutor::dispatch_call(sender, call.clone());456457				let mut actual_call_weight: Weight = item_weight;458				let result: Result<_, DispatchError> = match r {459					Ok(o) => match o {460						Ok(di) => {461							actual_call_weight = di.actual_weight.unwrap_or(item_weight);462							Ok(())463						}464						Err(err) => Err(err.error),465					},466					Err(_) => {467						log::error!(468							target: "runtime::scheduler",469							"Warning: Scheduler has failed to execute a post-dispatch transaction. \470							This block might have become invalid.");471						Err(DispatchError::CannotLookup)472					} // todo possibly force a skip/return here, do something with the error473				};474475				total_weight.saturating_accrue(item_weight);476				total_weight.saturating_accrue(actual_call_weight);477478				Self::deposit_event(Event::Dispatched {479					task: (now, index),480					id: s.maybe_id.clone(),481					result,482				});483484				if let &Some((period, count)) = &s.maybe_periodic {485					if count > 1 {486						s.maybe_periodic = Some((period, count - 1));487					} else {488						s.maybe_periodic = None;489					}490					let wake = now + period;491					// If scheduled is named, place its information in `Lookup`492					if let Some(ref id) = s.maybe_id {493						let wake_index = Agenda::<T>::decode_len(wake).unwrap_or(0);494						Lookup::<T>::insert(id, (wake, wake_index as u32));495					}496					Agenda::<T>::append(wake, Some(s));497				}498			}499			// Total weight should be 0, because the transaction is already paid for500			0501		}502	}503504	#[pallet::call]505	impl<T: Config> Pallet<T> {506		/// Schedule a named task.507		#[pallet::weight(<T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))]508		pub fn schedule_named(509			origin: OriginFor<T>,510			id: ScheduledId,511			when: T::BlockNumber,512			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,513			priority: schedule::Priority,514			call: Box<CallOrHashOf<T>>,515		) -> DispatchResult {516			T::ScheduleOrigin::ensure_origin(origin.clone())?;517			let origin = <T as Config>::Origin::from(origin);518			Self::do_schedule_named(519				id,520				DispatchTime::At(when),521				maybe_periodic,522				priority,523				origin.caller().clone(),524				*call,525			)?;526			Ok(())527		}528529		/// Cancel a named scheduled task.530		#[pallet::weight(<T as Config>::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get()))]531		pub fn cancel_named(origin: OriginFor<T>, id: ScheduledId) -> DispatchResult {532			T::ScheduleOrigin::ensure_origin(origin.clone())?;533			let origin = <T as Config>::Origin::from(origin);534			Self::do_cancel_named(Some(origin.caller().clone()), id)?;535			Ok(())536		}537538		/// Schedule a named task after a delay.539		///540		/// # <weight>541		/// Same as [`schedule_named`](Self::schedule_named).542		/// # </weight>543		#[pallet::weight(<T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))]544		pub fn schedule_named_after(545			origin: OriginFor<T>,546			id: ScheduledId,547			after: T::BlockNumber,548			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,549			priority: schedule::Priority,550			call: Box<CallOrHashOf<T>>,551		) -> DispatchResult {552			T::ScheduleOrigin::ensure_origin(origin.clone())?;553			let origin = <T as Config>::Origin::from(origin);554			Self::do_schedule_named(555				id,556				DispatchTime::After(after),557				maybe_periodic,558				priority,559				origin.caller().clone(),560				*call,561			)?;562			Ok(())563		}564	}565}566567impl<T: Config> Pallet<T> {568	#[cfg(feature = "try-runtime")]569	pub fn pre_migrate_to_v3() -> Result<(), &'static str> {570		Ok(())571	}572573	#[cfg(feature = "try-runtime")]574	pub fn post_migrate_to_v3() -> Result<(), &'static str> {575		use frame_support::dispatch::GetStorageVersion;576577		assert!(Self::current_storage_version() == 3);578		for k in Agenda::<T>::iter_keys() {579			let _ = Agenda::<T>::try_get(k).map_err(|()| "Invalid item in Agenda")?;580		}581		Ok(())582	}583584	/// Helper to migrate scheduler when the pallet origin type has changed.585	pub fn migrate_origin<OldOrigin: Into<T::PalletsOrigin> + codec::Decode>() {586		Agenda::<T>::translate::<587			Vec<Option<Scheduled<CallOrHashOf<T>, T::BlockNumber, OldOrigin, T::AccountId>>>,588			_,589		>(|_, agenda| {590			Some(591				agenda592					.into_iter()593					.map(|schedule| {594						schedule.map(|schedule| Scheduled {595							maybe_id: schedule.maybe_id,596							priority: schedule.priority,597							call: schedule.call,598							maybe_periodic: schedule.maybe_periodic,599							origin: schedule.origin.into(),600							_phantom: Default::default(),601						})602					})603					.collect::<Vec<_>>(),604			)605		});606	}607608	fn resolve_time(when: DispatchTime<T::BlockNumber>) -> Result<T::BlockNumber, DispatchError> {609		let now = frame_system::Pallet::<T>::block_number();610611		let when = match when {612			DispatchTime::At(x) => x,613			// The current block has already completed it's scheduled tasks, so614			// Schedule the task at lest one block after this current block.615			DispatchTime::After(x) => now.saturating_add(x).saturating_add(One::one()),616		};617618		if when <= now {619			return Err(Error::<T>::TargetBlockNumberInPast.into());620		}621622		Ok(when)623	}624625	fn do_schedule_named(626		id: ScheduledId,627		when: DispatchTime<T::BlockNumber>,628		maybe_periodic: Option<schedule::Period<T::BlockNumber>>,629		priority: schedule::Priority,630		origin: T::PalletsOrigin,631		call: CallOrHashOf<T>,632	) -> Result<TaskAddress<T::BlockNumber>, DispatchError> {633		// ensure id it is unique634		if Lookup::<T>::contains_key(&id) {635			return Err(Error::<T>::FailedToSchedule)?;636		}637638		let when = Self::resolve_time(when)?;639640		call.ensure_requested::<T::PreimageProvider>();641642		// sanitize maybe_periodic643		let maybe_periodic = maybe_periodic644			.filter(|p| p.1 > 1 && !p.0.is_zero())645			// Remove one from the number of repetitions since we will schedule one now.646			.map(|(p, c)| (p, c - 1));647648		let s = Scheduled {649			maybe_id: Some(id.clone()),650			priority,651			call: call.clone(),652			maybe_periodic,653			origin: origin.clone(),654			_phantom: Default::default(),655		};656657		// reserve balance for periodic execution658		// let sender =659		// 	ensure_signed(<<T as Config>::Origin as From<T::PalletsOrigin>>::from(origin).into())?;660		// let repeats = match maybe_periodic {661		// 	Some(p) => p.1,662		// 	None => 1,663		// };664		// let _ = T::CallExecutor::reserve_balance(665		// 	id.clone(),666		// 	sender,667		// 	call.as_value().unwrap().clone(),668		// 	repeats,669		// );670671		Agenda::<T>::append(when, Some(s));672		let index = Agenda::<T>::decode_len(when).unwrap_or(1) as u32 - 1;673		let address = (when, index);674		Lookup::<T>::insert(&id, &address);675		Self::deposit_event(Event::Scheduled { when, index });676677		Ok(address)678	}679680	fn do_cancel_named(origin: Option<T::PalletsOrigin>, id: ScheduledId) -> DispatchResult {681		Lookup::<T>::try_mutate_exists(id, |lookup| -> DispatchResult {682			if let Some((when, index)) = lookup.take() {683				let i = index as usize;684				Agenda::<T>::try_mutate(when, |agenda| -> DispatchResult {685					if let Some(s) = agenda.get_mut(i) {686						if let (Some(ref o), Some(ref s)) = (origin.clone(), s.borrow()) {687							if matches!(688								T::OriginPrivilegeCmp::cmp_privilege(o, &s.origin),689								Some(Ordering::Less) | None690							) {691								return Err(BadOrigin.into());692							}693							// release balance reserve694							// let sender = ensure_signed(695							// 	<<T as Config>::Origin as From<T::PalletsOrigin>>::from(696							// 		origin.unwrap(),697							// 	)698							// 	.into(),699							// )?;700							// let _ = T::CallExecutor::cancel_reserve(id, sender);701702							s.call.ensure_unrequested::<T::PreimageProvider>();703						}704						*s = None;705					}706					Ok(())707				})?;708709				Self::deposit_event(Event::Canceled { when, index });710				Ok(())711			} else {712				Err(Error::<T>::NotFound)?713			}714		})715	}716}
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -78,19 +78,19 @@
 
 	#[pallet::error]
 	pub enum Error<T> {
-		/// While searched for owner, got already checked account
+		/// While nesting, encountered an already checked account, detecting a loop.
 		OuroborosDetected,
-		/// While searched for owner, encountered depth limit
+		/// While nesting, reached the depth limit of nesting, exceeding the provided budget.
 		DepthLimit,
-		/// While iterating over children, encountered breadth limit
+		/// While nesting, reached the breadth limit of nesting, exceeding the provided budget.
 		BreadthLimit,
-		/// While searched for owner, found token owner by not-yet-existing token
+		/// Couldn't find the token owner that is itself a token.
 		TokenNotFound,
 	}
 
 	#[pallet::event]
 	pub enum Event<T> {
-		/// Executed call on behalf of token
+		/// Executed call on behalf of the token.
 		Executed(DispatchResult),
 	}
 
@@ -126,11 +126,11 @@
 
 #[derive(PartialEq)]
 pub enum Parent<CrossAccountId> {
-	/// Token owned by normal account
+	/// Token owned by a normal account.
 	User(CrossAccountId),
-	/// Passed token not found
+	/// Could not find the token provided as the owner.
 	TokenNotFound,
-	/// Token owner is another token (target token still may not exist)
+	/// Token owner is another token (still, the target token may not exist).
 	Token(CollectionId, TokenId),
 }
 
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -14,6 +14,8 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
+//! Implementation of CollectionHelpers contract.
+
 use core::marker::PhantomData;
 use evm_coder::{execution::*, generate_stubgen, solidity_interface, weight, types::*};
 use ethereum as _;
@@ -33,7 +35,8 @@
 use sp_std::vec::Vec;
 use alloc::format;
 
-struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);
+/// See [`CollectionHelpersCall`]
+pub struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);
 impl<T: Config> WithRecorder<T> for EvmCollectionHelpers<T> {
 	fn recorder(&self) -> &SubstrateRecorder<T> {
 		&self.0
@@ -44,8 +47,14 @@
 	}
 }
 
+/// @title Contract, which allows users to operate with collections
 #[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]
 impl<T: Config + pallet_nonfungible::Config> EvmCollectionHelpers<T> {
+	/// Create an NFT collection
+	/// @param name Name of the collection
+	/// @param description Informative description of the collection
+	/// @param token_prefix Token prefix to represent the collection tokens in UI and user applications
+	/// @return address Address of the newly created collection
 	#[weight(<SelfWeightOf<T>>::create_collection())]
 	fn create_nonfungible_collection(
 		&mut self,
@@ -100,6 +109,9 @@
 		Ok(address)
 	}
 
+	/// Check if a collection exists
+	/// @param collection_address Address of the collection in question
+	/// @return bool Does the collection exist?
 	fn is_collection_exist(&self, _caller: caller, collection_address: address) -> Result<bool> {
 		if let Some(id) = pallet_common::eth::map_eth_to_id(&collection_address) {
 			let collection_id = id;
@@ -110,6 +122,7 @@
 	}
 }
 
+/// Implements [`OnMethodCall`], which delegates call to [`EvmCollectionHelpers`]
 pub struct CollectionHelpersOnMethodCall<T: Config>(PhantomData<*const T>);
 impl<T: Config + pallet_nonfungible::Config> OnMethodCall<T> for CollectionHelpersOnMethodCall<T> {
 	fn is_reserved(contract: &sp_core::H160) -> bool {
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -14,6 +14,55 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
+//! # Unique Pallet
+//!
+//! A pallet governing Unique transactions.
+//!
+//! - [`Config`]
+//! - [`Call`]
+//! - [`Pallet`]
+//!
+//! ## Overview
+//!
+//! The Unique pallet's purpose is to be the primary interface between
+//! external users and the inner structure of the Unique chains.
+//!
+//! It also contains an implementation of [`CollectionHelpers`][`eth`],
+//! an Ethereum contract dealing with collection operations.
+//!
+//! ## Interface
+//!
+//! ### Dispatchables
+//!
+//! - `create_collection` - Create a collection of tokens. **Deprecated**, use `create_collection_ex`.
+//! - `create_collection_ex` - Create a collection of tokens with explicit parameters.
+//! - `destroy_collection` - Destroy a collection if no tokens exist within.
+//! - `add_to_allow_list` - Add an address to allow list.
+//! - `remove_from_allow_list` - Remove an address from allow list.
+//! - `change_collection_owner` - Change the owner of the collection.
+//! - `add_collection_admin` - Add an admin to a collection.
+//! - `remove_collection_admin` - Remove admin of a collection.
+//! - `set_collection_sponsor` - Invite a new collection sponsor.
+//! - `confirm_sponsorship` - Confirm own sponsorship of a collection, becoming the sponsor.
+//! - `remove_collection_sponsor` - Remove a sponsor from a collection.
+//! - `create_item` - Create an item within a collection.
+//! - `create_multiple_items` - Create multiple items within a collection.
+//! - `set_collection_properties` - Add or change collection properties.
+//! - `delete_collection_properties` - Delete specified collection properties.
+//! - `set_token_properties` - Add or change token properties.
+//! - `delete_token_properties` - Delete token properties.
+//! - `set_token_property_permissions` - Add or change token property permissions of a collection.
+//! - `create_multiple_items_ex` - Create multiple items within a collection with explicitly specified initial parameters.
+//! - `set_transfers_enabled_flag` - Completely allow or disallow transfers for a particular collection.
+//! - `burn_item` - Destroy an item.
+//! - `burn_from` - Destroy an item on behalf of the owner as a non-owner account.
+//! - `transfer` - Change ownership of the token.
+//! - `transfer_from` - Change ownership of the token on behalf of the owner as a non-owner account.
+//! - `approve` - Allow a non-permissioned address to transfer or burn an item.
+//! - `set_collection_limits` - Set specific limits of a collection.
+//! - `set_collection_permissions` - Set specific permissions of a collection.
+//! - `repartition` - Re-partition a refungible token, while owning all of its parts.
+
 #![recursion_limit = "1024"]
 #![cfg_attr(not(feature = "std"), no_std)]
 #![allow(
@@ -54,28 +103,35 @@
 pub mod weights;
 use weights::WeightInfo;
 
-const NESTING_BUDGET: u32 = 5;
+/// Maximum number of levels of depth in the token nesting tree.
+pub const NESTING_BUDGET: u32 = 5;
 
 decl_error! {
-	/// Error for non-fungible-token module.
+	/// Errors for the common Unique transactions.
 	pub enum Error for Module<T: Config> {
-		/// Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.
+		/// Decimal_points parameter must be lower than [`up_data_structs::MAX_DECIMAL_POINTS`].
 		CollectionDecimalPointLimitExceeded,
 		/// This address is not set as sponsor, use setCollectionSponsor first.
 		ConfirmUnsetSponsorFail,
 		/// Length of items properties must be greater than 0.
 		EmptyArgument,
-		/// Repertition is only supported by refungible collection
+		/// Repertition is only supported by refungible collection.
 		RepartitionCalledOnNonRefungibleCollection,
 	}
 }
 
+/// Configuration trait of this pallet.
 pub trait Config: system::Config + pallet_common::Config + Sized + TypeInfo {
+	/// Overarching event type.
 	type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
 
 	/// Weight information for extrinsics in this pallet.
 	type WeightInfo: WeightInfo;
+
+	/// Weight information for common pallet operations.
 	type CommonWeightInfo: CommonWeightInfo<Self::CrossAccountId>;
+
+	/// Weight info information for extra refungible pallet operations.
 	type RefungibleExtensionsWeightInfo: RefungibleExtensionsWeightInfo;
 }
 
@@ -88,80 +144,68 @@
 		/// Collection sponsor was removed
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
+		/// * collection_id: ID of the affected collection.
 		CollectionSponsorRemoved(CollectionId),
 
 		/// Collection admin was added
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * admin:  Admin address.
+		/// * collection_id: ID of the affected collection.
+		/// * admin: Admin address.
 		CollectionAdminAdded(CollectionId, CrossAccountId),
 
-		/// Collection owned was change
+		/// Collection owned was changed
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * owner:  New owner address.
+		/// * collection_id: ID of the affected collection.
+		/// * owner: New owner address.
 		CollectionOwnedChanged(CollectionId, AccountId),
 
 		/// Collection sponsor was set
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * owner:  New sponsor address.
+		/// * collection_id: ID of the affected collection.
+		/// * owner: New sponsor address.
 		CollectionSponsorSet(CollectionId, AccountId),
 
 		/// New sponsor was confirm
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * sponsor:  New sponsor address.
+		/// * collection_id: ID of the affected collection.
+		/// * sponsor: New sponsor address.
 		SponsorshipConfirmed(CollectionId, AccountId),
 
 		/// Collection admin was removed
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * admin:  Admin address.
+		/// * collection_id: ID of the affected collection.
+		/// * admin: Removed admin address.
 		CollectionAdminRemoved(CollectionId, CrossAccountId),
 
-		/// Address was remove from allow list
+		/// Address was removed from the allow list
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * user:  Address.
+		/// * collection_id: ID of the affected collection.
+		/// * user: Address of the removed account.
 		AllowListAddressRemoved(CollectionId, CrossAccountId),
 
-		/// Address was add to allow list
+		/// Address was added to the allow list
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
-		///
-		/// * user:  Address.
+		/// * collection_id: ID of the affected collection.
+		/// * user: Address of the added account.
 		AllowListAddressAdded(CollectionId, CrossAccountId),
 
-		/// Collection limits was set
+		/// Collection limits were set
 		///
 		/// # Arguments
-		///
-		/// * collection_id: Globally unique collection identifier.
+		/// * collection_id: ID of the affected collection.
 		CollectionLimitSet(CollectionId),
 
+		/// Collection permissions were set
+		///
+		/// # Arguments
+		/// * collection_id: ID of the affected collection.
 		CollectionPermissionSet(CollectionId),
 	}
 }
@@ -198,7 +242,7 @@
 		ChainVersion: u64;
 		//#endregion
 
-		//#region Tokens transfer rate limit baskets
+		//#region Tokens transfer sponosoring rate limit baskets
 		/// (Collection id (controlled?2), who created (real))
 		/// TODO: Off chain worker should remove from this map when collection gets removed
 		pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => Option<T::BlockNumber>;
@@ -214,16 +258,20 @@
 		/// Collection id (controlled?2), token id (controlled?2)
 		#[deprecated]
 		pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
+		/// Last sponsoring of token property setting // todo:doc rephrase this and the following
 		pub TokenPropertyBasket get(fn token_property_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
 
-		/// Approval sponsoring
+		/// Last sponsoring of NFT approval in a collection
 		pub NftApproveBasket get(fn nft_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
+		/// Last sponsoring of fungible tokens approval in a collection
 		pub FungibleApproveBasket get(fn fungible_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
+		/// Last sponsoring of RFT approval in a collection
 		pub RefungibleApproveBasket get(fn refungible_approve_basket): nmap hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
 	}
 }
 
 decl_module! {
+	/// Type alias to Pallet, to be used by construct_runtime.
 	pub struct Module<T: Config> for enum Call
 	where
 		origin: T::Origin
@@ -244,30 +292,38 @@
 			0
 		}
 
-		/// This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner of the collection is set to the address that signed the transaction and can be changed later.
-		///
-		/// # Permissions
+		/// Create a collection of tokens.
 		///
-		/// * Anyone.
+		/// Each Token may have multiple properties encoded as an array of bytes
+		/// of certain length. The initial owner of the collection is set
+		/// to the address that signed the transaction and can be changed later.
 		///
-		/// # Arguments
+		/// Prefer the more advanced [`create_collection_ex`][`Pallet::create_collection_ex`] instead.
 		///
-		/// * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.
+		/// # Permissions
 		///
-		/// * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.
+		/// * Anyone - becomes the owner of the new collection.
 		///
-		/// * token_prefix: UTF-8 string with token prefix.
+		/// # Arguments
 		///
-		/// * mode: [CollectionMode] collection type and type dependent data.
+		/// * `collection_name`: Wide-character string with collection name
+		/// (limit [`MAX_COLLECTION_NAME_LENGTH`]).
+		/// * `collection_description`: Wide-character string with collection description
+		/// (limit [`MAX_COLLECTION_DESCRIPTION_LENGTH`]).
+		/// * `token_prefix`: Byte string containing the token prefix to mark a collection
+		/// to which a token belongs (limit [`MAX_TOKEN_PREFIX_LENGTH`]).
+		/// * `mode`: Type of items stored in the collection and type dependent data.
 		// returns collection ID
 		#[weight = <SelfWeightOf<T>>::create_collection()]
 		#[transactional]
-		#[deprecated]
-		pub fn create_collection(origin,
-								 collection_name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,
-								 collection_description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,
-								 token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,
-								 mode: CollectionMode) -> DispatchResult  {
+		#[deprecated(note = "`create_collection_ex` is more up-to-date and advanced, prefer it instead")]
+		pub fn create_collection(
+			origin,
+			collection_name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,
+			collection_description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,
+			token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,
+			mode: CollectionMode
+		) -> DispatchResult {
 			let data: CreateCollectionData<T::AccountId> = CreateCollectionData {
 				name: collection_name,
 				description: collection_description,
@@ -278,9 +334,17 @@
 			Self::create_collection_ex(origin, data)
 		}
 
-		/// This method creates a collection
+		/// Create a collection with explicit parameters.
+		///
+		/// Prefer it to the deprecated [`create_collection`][`Pallet::create_collection`] method.
+		///
+		/// # Permissions
+		///
+		/// * Anyone - becomes the owner of the new collection.
 		///
-		/// Prefer it to deprecated [`created_collection`] method
+		/// # Arguments
+		///
+		/// * `data`: Explicit data of a collection used for its creation.
 		#[weight = <SelfWeightOf<T>>::create_collection()]
 		#[transactional]
 		pub fn create_collection_ex(origin, data: CreateCollectionData<T::AccountId>) -> DispatchResult {
@@ -293,15 +357,15 @@
 			Ok(())
 		}
 
-		/// Destroys collection if no tokens within this collection
+		/// Destroy a collection if no tokens exist within.
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
+		/// * Collection owner
 		///
 		/// # Arguments
 		///
-		/// * collection_id: collection to destroy.
+		/// * `collection_id`: Collection to destroy.
 		#[weight = <SelfWeightOf<T>>::destroy_collection()]
 		#[transactional]
 		pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {
@@ -328,14 +392,13 @@
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner
-		/// * Collection Admin
+		/// * Collection owner
+		/// * Collection admin
 		///
 		/// # Arguments
 		///
-		/// * collection_id.
-		///
-		/// * address.
+		/// * `collection_id`: ID of the modified collection.
+		/// * `address`: ID of the address to be added to the allowlist.
 		#[weight = <SelfWeightOf<T>>::add_to_allow_list()]
 		#[transactional]
 		pub fn add_to_allow_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{
@@ -363,14 +426,13 @@
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner
-		/// * Collection Admin
+		/// * Collection owner
+		/// * Collection admin
 		///
 		/// # Arguments
 		///
-		/// * collection_id.
-		///
-		/// * address.
+		/// * `collection_id`: ID of the modified collection.
+		/// * `address`: ID of the address to be removed from the allowlist.
 		#[weight = <SelfWeightOf<T>>::remove_from_allow_list()]
 		#[transactional]
 		pub fn remove_from_allow_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{
@@ -398,13 +460,12 @@
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
+		/// * Collection owner
 		///
 		/// # Arguments
 		///
-		/// * collection_id.
-		///
-		/// * new_owner.
+		/// * `collection_id`: ID of the modified collection.
+		/// * `new_owner`: ID of the account that will become the owner.
 		#[weight = <SelfWeightOf<T>>::change_collection_owner()]
 		#[transactional]
 		pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {
@@ -424,46 +485,51 @@
 			target_collection.save()
 		}
 
-		/// Adds an admin of the Collection.
-		/// NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.
+		/// Add an admin to a collection.
 		///
+		/// NFT Collection can be controlled by multiple admin addresses
+		/// (some which can also be servers, for example). Admins can issue
+		/// and burn NFTs, as well as add and remove other admins,
+		/// but cannot change NFT or Collection ownership.
+		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
-		/// * Collection Admin.
+		/// * Collection owner
+		/// * Collection admin
 		///
 		/// # Arguments
 		///
-		/// * collection_id: ID of the Collection to add admin for.
-		///
-		/// * new_admin_id: Address of new admin to add.
+		/// * `collection_id`: ID of the Collection to add an admin for.
+		/// * `new_admin`: Address of new admin to add.
 		#[weight = <SelfWeightOf<T>>::add_collection_admin()]
 		#[transactional]
-		pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {
+		pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin: T::CrossAccountId) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let collection = <CollectionHandle<T>>::try_get(collection_id)?;
 			collection.check_is_internal()?;
 
 			<Pallet<T>>::deposit_event(Event::<T>::CollectionAdminAdded(
 				collection_id,
-				new_admin_id.clone()
+				new_admin.clone()
 			));
 
-			<PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin_id, true)
+			<PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin, true)
 		}
 
-		/// Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.
+		/// Remove admin of a collection.
+		///
+		/// An admin address can remove itself. List of admins may become empty,
+		/// in which case only Collection Owner will be able to add an Admin.
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
-		/// * Collection Admin.
+		/// * Collection owner
+		/// * Collection admin
 		///
 		/// # Arguments
 		///
-		/// * collection_id: ID of the Collection to remove admin for.
-		///
-		/// * account_id: Address of admin to remove.
+		/// * `collection_id`: ID of the collection to remove the admin for.
+		/// * `account_id`: Address of the admin to remove.
 		#[weight = <SelfWeightOf<T>>::remove_collection_admin()]
 		#[transactional]
 		pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {
@@ -479,15 +545,19 @@
 			<PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)
 		}
 
+		/// Set (invite) a new collection sponsor.
+		///
+		/// If successful, confirmation from the sponsor-to-be will be pending.
+		///
 		/// # Permissions
 		///
-		/// * Collection Owner
+		/// * Collection owner
+		/// * Collection admin
 		///
 		/// # Arguments
 		///
-		/// * collection_id.
-		///
-		/// * new_sponsor.
+		/// * `collection_id`: ID of the modified collection.
+		/// * `new_sponsor`: ID of the account of the sponsor-to-be.
 		#[weight = <SelfWeightOf<T>>::set_collection_sponsor()]
 		#[transactional]
 		pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {
@@ -507,13 +577,19 @@
 			target_collection.save()
 		}
 
+		/// Confirm own sponsorship of a collection, becoming the sponsor.
+		///
+		/// An invitation must be pending, see [`set_collection_sponsor`][`Pallet::set_collection_sponsor`].
+		/// Sponsor can pay the fees of a transaction instead of the sender,
+		/// but only within specified limits.
+		///
 		/// # Permissions
 		///
-		/// * Sponsor.
+		/// * Sponsor-to-be
 		///
 		/// # Arguments
 		///
-		/// * collection_id.
+		/// * `collection_id`: ID of the collection with the pending sponsor.
 		#[weight = <SelfWeightOf<T>>::confirm_sponsorship()]
 		#[transactional]
 		pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {
@@ -534,15 +610,15 @@
 			target_collection.save()
 		}
 
-		/// Switch back to pay-per-own-transaction model.
+		/// Remove a collection's a sponsor, making everyone pay for their own transactions.
 		///
 		/// # Permissions
 		///
-		/// * Collection owner.
+		/// * Collection owner
 		///
 		/// # Arguments
 		///
-		/// * collection_id.
+		/// * `collection_id`: ID of the collection with the sponsor to remove.
 		#[weight = <SelfWeightOf<T>>::remove_collection_sponsor()]
 		#[transactional]
 		pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {
@@ -560,24 +636,24 @@
 			target_collection.save()
 		}
 
-		/// This method creates a concrete instance of NFT Collection created with CreateCollection method.
+		/// Mint an item within a collection.
+		///
+		/// A collection must exist first, see [`create_collection_ex`][`Pallet::create_collection_ex`].
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
-		/// * Collection Admin.
+		/// * Collection owner
+		/// * Collection admin
 		/// * Anyone if
 		///     * Allow List is enabled, and
 		///     * Address is added to allow list, and
-		///     * MintPermission is enabled (see SetMintPermission method)
+		///     * MintPermission is enabled (see [`set_collection_permissions`][`Pallet::set_collection_permissions`])
 		///
 		/// # Arguments
-		///
-		/// * collection_id: ID of the collection.
 		///
-		/// * owner: Address, initial owner of the NFT.
-		///
-		/// * data: Token data to store on chain.
+		/// * `collection_id`: ID of the collection to which an item would belong.
+		/// * `owner`: Address of the initial owner of the item.
+		/// * `data`: Token data describing the item to store on chain.
 		#[weight = T::CommonWeightInfo::create_item()]
 		#[transactional]
 		pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {
@@ -587,24 +663,24 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.create_item(sender, owner, data, &budget))
 		}
 
-		/// This method creates multiple items in a collection created with CreateCollection method.
+		/// Create multiple items within a collection.
 		///
+		/// A collection must exist first, see [`create_collection_ex`][`Pallet::create_collection_ex`].
+		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
-		/// * Collection Admin.
+		/// * Collection owner
+		/// * Collection admin
 		/// * Anyone if
 		///     * Allow List is enabled, and
-		///     * Address is added to allow list, and
-		///     * MintPermission is enabled (see SetMintPermission method)
+		///     * Address is added to the allow list, and
+		///     * MintPermission is enabled (see [`set_collection_permissions`][`Pallet::set_collection_permissions`])
 		///
 		/// # Arguments
 		///
-		/// * collection_id: ID of the collection.
-		///
-		/// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].
-		///
-		/// * owner: Address, initial owner of the NFT.
+		/// * `collection_id`: ID of the collection to which the tokens would belong.
+		/// * `owner`: Address of the initial owner of the tokens.
+		/// * `items_data`: Vector of data describing each item to be created.
 		#[weight = T::CommonWeightInfo::create_multiple_items(&items_data)]
 		#[transactional]
 		pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {
@@ -615,6 +691,18 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data, &budget))
 		}
 
+		/// Add or change collection properties.
+		///
+		/// # Permissions
+		///
+		/// * Collection owner
+		/// * Collection admin
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the modified collection.
+		/// * `properties`: Vector of key-value pairs stored as the collection's metadata.
+		/// Keys support Latin letters, `-`, `_`, and `.` as symbols.
 		#[weight = T::CommonWeightInfo::set_collection_properties(properties.len() as u32)]
 		#[transactional]
 		pub fn set_collection_properties(
@@ -629,6 +717,18 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.set_collection_properties(sender, properties))
 		}
 
+		/// Delete specified collection properties.
+		///
+		/// # Permissions
+		///
+		/// * Collection Owner
+		/// * Collection Admin
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the modified collection.
+		/// * `property_keys`: Vector of keys of the properties to be deleted.
+		/// Keys support Latin letters, `-`, `_`, and `.` as symbols.
 		#[weight = T::CommonWeightInfo::delete_collection_properties(property_keys.len() as u32)]
 		#[transactional]
 		pub fn delete_collection_properties(
@@ -643,6 +743,24 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.delete_collection_properties(&sender, property_keys))
 		}
 
+		/// Add or change token properties according to collection's permissions.
+		/// Currently properties only work with NFTs.
+		///
+		/// # Permissions
+		///
+		/// * Depends on collection's token property permissions and specified property mutability:
+		/// 	* Collection owner
+		/// 	* Collection admin
+		/// 	* Token owner
+		///
+		/// See [`set_token_property_permissions`][`Pallet::set_token_property_permissions`].
+		///
+		/// # Arguments
+		///
+		/// * `collection_id: ID of the collection to which the token belongs.
+		/// * `token_id`: ID of the modified token.
+		/// * `properties`: Vector of key-value pairs stored as the token's metadata.
+		/// Keys support Latin letters, `-`, `_`, and `.` as symbols.
 		#[weight = T::CommonWeightInfo::set_token_properties(properties.len() as u32)]
 		#[transactional]
 		pub fn set_token_properties(
@@ -659,6 +777,21 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.set_token_properties(sender, token_id, properties, &budget))
 		}
 
+		/// Delete specified token properties. Currently properties only work with NFTs.
+		///
+		/// # Permissions
+		///
+		/// * Depends on collection's token property permissions and specified property mutability:
+		/// 	* Collection owner
+		/// 	* Collection admin
+		/// 	* Token owner
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the collection to which the token belongs.
+		/// * `token_id`: ID of the modified token.
+		/// * `property_keys`: Vector of keys of the properties to be deleted.
+		/// Keys support Latin letters, `-`, `_`, and `.` as symbols.
 		#[weight = T::CommonWeightInfo::delete_token_properties(property_keys.len() as u32)]
 		#[transactional]
 		pub fn delete_token_properties(
@@ -675,6 +808,21 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.delete_token_properties(sender, token_id, property_keys, &budget))
 		}
 
+		/// Add or change token property permissions of a collection.
+		///
+		/// Without a permission for a particular key, a property with that key
+		/// cannot be created in a token.
+		///
+		/// # Permissions
+		///
+		/// * Collection owner
+		/// * Collection admin
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the modified collection.
+		/// * `property_permissions`: Vector of permissions for property keys.
+		/// Keys support Latin letters, `-`, `_`, and `.` as symbols.
 		#[weight = T::CommonWeightInfo::set_token_property_permissions(property_permissions.len() as u32)]
 		#[transactional]
 		pub fn set_token_property_permissions(
@@ -689,6 +837,21 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.set_token_property_permissions(&sender, property_permissions))
 		}
 
+		/// Create multiple items within a collection with explicitly specified initial parameters.
+		///
+		/// # Permissions
+		///
+		/// * Collection owner
+		/// * Collection admin
+		/// * Anyone if
+		///     * Allow List is enabled, and
+		///     * Address is added to allow list, and
+		///     * MintPermission is enabled (see [`set_collection_permissions`][`Pallet::set_collection_permissions`])
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the collection to which the tokens would belong.
+		/// * `data`: Explicit item creation data.
 		#[weight = T::CommonWeightInfo::create_multiple_items_ex(&data)]
 		#[transactional]
 		pub fn create_multiple_items_ex(origin, collection_id: CollectionId, data: CreateItemExData<T::CrossAccountId>) -> DispatchResultWithPostInfo {
@@ -698,17 +861,16 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data, &budget))
 		}
 
-		/// Set transfers_enabled value for particular collection
+		/// Completely allow or disallow transfers for a particular collection.
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
+		/// * Collection owner
 		///
 		/// # Arguments
 		///
-		/// * collection_id: ID of the collection.
-		///
-		/// * value: New flag value.
+		/// * `collection_id`: ID of the collection.
+		/// * `value`: New value of the flag, are transfers allowed?
 		#[weight = <SelfWeightOf<T>>::set_transfers_enabled_flag()]
 		#[transactional]
 		pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {
@@ -723,19 +885,22 @@
 			target_collection.save()
 		}
 
-		/// Destroys a concrete instance of NFT.
+		/// Destroy an item.
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
-		/// * Collection Admin.
-		/// * Current NFT Owner.
+		/// * Collection owner
+		/// * Collection admin
+		/// * Current item owner
 		///
 		/// # Arguments
 		///
-		/// * collection_id: ID of the collection.
-		///
-		/// * item_id: ID of NFT to burn.
+		/// * `collection_id`: ID of the collection to which the item belongs.
+		/// * `item_id`: ID of item to burn.
+		/// * `value`: Number of pieces of the item to destroy.
+		/// 	* Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+		///     * Fungible Mode: The desired number of pieces to burn.
+		///     * Re-Fungible Mode: The desired number of pieces to burn.
 		#[weight = T::CommonWeightInfo::burn_item()]
 		#[transactional]
 		pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {
@@ -752,22 +917,29 @@
 			Ok(post_info)
 		}
 
-		/// Destroys a concrete instance of NFT on behalf of the owner
-		/// See also: [`approve`]
+		/// Destroy a token on behalf of the owner as a non-owner account.
+		///
+		/// See also: [`approve`][`Pallet::approve`].
+		///
+		/// After this method executes, one approval is removed from the total so that
+		/// the approved address will not be able to transfer this item again from this owner.
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner.
-		/// * Collection Admin.
-		/// * Current NFT Owner.
+		/// * Collection owner
+		/// * Collection admin
+		/// * Current token owner
+		/// * Address approved by current item owner
 		///
 		/// # Arguments
 		///
-		/// * collection_id: ID of the collection.
-		///
-		/// * item_id: ID of NFT to burn.
-		///
-		/// * from: owner of item
+		/// * `from`: The owner of the burning item.
+		/// * `collection_id`: ID of the collection to which the item belongs.
+		/// * `item_id`: ID of item to burn.
+		/// * `value`: Number of pieces to burn.
+		/// 	* Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+		///     * Fungible Mode: The desired number of pieces to burn.
+		///     * Re-Fungible Mode: The desired number of pieces to burn.
 		#[weight = T::CommonWeightInfo::burn_from()]
 		#[transactional]
 		pub fn burn_from(origin, collection_id: CollectionId, from: T::CrossAccountId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {
@@ -781,25 +953,23 @@
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner
-		/// * Collection Admin
-		/// * Current NFT owner
+		/// * Collection owner
+		/// * Collection admin
+		/// * Current token owner
 		///
 		/// # Arguments
-		///
-		/// * recipient: Address of token recipient.
 		///
-		/// * collection_id.
-		///
-		/// * item_id: ID of the item
+		/// * `recipient`: Address of token recipient.
+		/// * `collection_id`: ID of the collection the item belongs to.
+		/// * `item_id`: ID of the item.
 		///     * Non-Fungible Mode: Required.
 		///     * Fungible Mode: Ignored.
 		///     * Re-Fungible Mode: Required.
 		///
-		/// * value: Amount to transfer.
-		///     * Non-Fungible Mode: Ignored
-		///     * Fungible Mode: Must specify transferred amount
-		///     * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)
+		/// * `value`: Amount to transfer.
+		/// 	* Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+		///     * Fungible Mode: The desired number of pieces to transfer.
+		///     * Re-Fungible Mode: The desired number of pieces to transfer.
 		#[weight = T::CommonWeightInfo::transfer()]
 		#[transactional]
 		pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {
@@ -809,21 +979,21 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value, &budget))
 		}
 
-		/// Set, change, or remove approved address to transfer the ownership of the NFT.
+		/// Allow a non-permissioned address to transfer or burn an item.
 		///
 		/// # Permissions
 		///
-		/// * Collection Owner
-		/// * Collection Admin
-		/// * Current NFT owner
+		/// * Collection owner
+		/// * Collection admin
+		/// * Current item owner
 		///
 		/// # Arguments
 		///
-		/// * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).
-		///
-		/// * collection_id.
-		///
-		/// * item_id: ID of the item.
+		/// * `spender`: Account to be approved to make specific transactions on non-owned tokens.
+		/// * `collection_id`: ID of the collection the item belongs to.
+		/// * `item_id`: ID of the item transactions on which are now approved.
+		/// * `amount`: Number of pieces of the item approved for a transaction (maximum of 1 for NFTs).
+		/// Set to 0 to revoke the approval.
 		#[weight = T::CommonWeightInfo::approve()]
 		#[transactional]
 		pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {
@@ -832,25 +1002,30 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))
 		}
 
-		/// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.
+		/// Change ownership of an item on behalf of the owner as a non-owner account.
 		///
-		/// # Permissions
-		/// * Collection Owner
-		/// * Collection Admin
-		/// * Current NFT owner
-		/// * Address approved by current NFT owner
+		/// See the [`approve`][`Pallet::approve`] method for additional information.
 		///
-		/// # Arguments
+		/// After this method executes, one approval is removed from the total so that
+		/// the approved address will not be able to transfer this item again from this owner.
 		///
-		/// * from: Address that owns token.
+		/// # Permissions
 		///
-		/// * recipient: Address of token recipient.
+		/// * Collection owner
+		/// * Collection admin
+		/// * Current item owner
+		/// * Address approved by current item owner
 		///
-		/// * collection_id.
+		/// # Arguments
 		///
-		/// * item_id: ID of the item.
-		///
-		/// * value: Amount to transfer.
+		/// * `from`: Address that currently owns the token.
+		/// * `recipient`: Address of the new token-owner-to-be.
+		/// * `collection_id`: ID of the collection the item.
+		/// * `item_id`: ID of the item to be transferred.
+		/// * `value`: Amount to transfer.
+		/// 	* Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+		///     * Fungible Mode: The desired number of pieces to transfer.
+		///     * Re-Fungible Mode: The desired number of pieces to transfer.
 		#[weight = T::CommonWeightInfo::transfer_from()]
 		#[transactional]
 		pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResultWithPostInfo {
@@ -860,6 +1035,18 @@
 			dispatch_tx::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value, &budget))
 		}
 
+		/// Set specific limits of a collection. Empty, or None fields mean chain default.
+		///
+		/// # Permissions
+		///
+		/// * Collection owner
+		/// * Collection admin
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the modified collection.
+		/// * `new_limit`: New limits of the collection. Fields that are not set (None)
+		/// will not overwrite the old ones.
 		#[weight = <SelfWeightOf<T>>::set_collection_limits()]
 		#[transactional]
 		pub fn set_collection_limits(
@@ -882,12 +1069,24 @@
 			target_collection.save()
 		}
 
+		/// Set specific permissions of a collection. Empty, or None fields mean chain default.
+		///
+		/// # Permissions
+		///
+		/// * Collection owner
+		/// * Collection admin
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the modified collection.
+		/// * `new_permission`: New permissions of the collection. Fields that are not set (None)
+		/// will not overwrite the old ones.
 		#[weight = <SelfWeightOf<T>>::set_collection_limits()]
 		#[transactional]
 		pub fn set_collection_permissions(
 			origin,
 			collection_id: CollectionId,
-			new_limit: CollectionPermissions,
+			new_permission: CollectionPermissions,
 		) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
@@ -895,7 +1094,7 @@
 			target_collection.check_is_owner_or_admin(&sender)?;
 			let old_limit = &target_collection.permissions;
 
-			target_collection.permissions = <PalletCommon<T>>::clamp_permissions(target_collection.mode.clone(), &old_limit, new_limit)?;
+			target_collection.permissions = <PalletCommon<T>>::clamp_permissions(target_collection.mode.clone(), &old_limit, new_permission)?;
 
 			<Pallet<T>>::deposit_event(Event::<T>::CollectionPermissionSet(
 				collection_id
@@ -904,18 +1103,29 @@
 			target_collection.save()
 		}
 
+		/// Re-partition a refungible token, while owning all of its parts/pieces.
+		///
+		/// # Permissions
+		///
+		/// * Token owner (must own every part)
+		///
+		/// # Arguments
+		///
+		/// * `collection_id`: ID of the collection the RFT belongs to.
+		/// * `token_id`: ID of the RFT.
+		/// * `amount`: New number of parts/pieces into which the token shall be partitioned.
 		#[weight = T::RefungibleExtensionsWeightInfo::repartition()]
 		#[transactional]
 		pub fn repartition(
 			origin,
 			collection_id: CollectionId,
-			token: TokenId,
+			token_id: TokenId,
 			amount: u128,
 		) -> DispatchResultWithPostInfo {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 			dispatch_tx::<T, _>(collection_id, |d| {
 				if let Some(refungible_extensions) = d.refungible_extensions() {
-					refungible_extensions.repartition(&sender, token, amount)
+					refungible_extensions.repartition(&sender, token_id, amount)
 				} else {
 					fail!(<Error<T>>::RepartitionCalledOnNonRefungibleCollection)
 				}
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -197,7 +197,6 @@
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CollectionMode {
 	NFT,
-	// decimal points
 	Fungible(DecimalPoints),
 	ReFungible,
 }
@@ -252,12 +251,14 @@
 pub enum SponsorshipState<AccountId> {
 	/// The fees are applied to the transaction sender
 	Disabled,
+	/// Pending confirmation from a sponsor-to-be
 	Unconfirmed(AccountId),
 	/// Transactions are sponsored by specified account
 	Confirmed(AccountId),
 }
 
 impl<AccountId> SponsorshipState<AccountId> {
+	/// Get the acting sponsor account, if present
 	pub fn sponsor(&self) -> Option<&AccountId> {
 		match self {
 			Self::Confirmed(sponsor) => Some(sponsor),
@@ -265,6 +266,7 @@
 		}
 	}
 
+	/// Get the sponsor account currently pending confirmation, if present
 	pub fn pending_sponsor(&self) -> Option<&AccountId> {
 		match self {
 			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),
@@ -272,6 +274,7 @@
 		}
 	}
 
+	/// Is sponsorship set and acting
 	pub fn confirmed(&self) -> bool {
 		matches!(self, Self::Confirmed(_))
 	}
@@ -283,7 +286,7 @@
 	}
 }
 
-/// Used in storage
+/// Collection parameters, used in storage (see [`RpcCollection`] for the RPC version).
 #[struct_versioning::versioned(version = 2, upper)]
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 pub struct Collection<AccountId> {
@@ -324,7 +327,7 @@
 	pub meta_update_permission: MetaUpdatePermission,
 }
 
-/// Used in RPC calls
+/// Collection parameters, used in RPC calls (see [`Collection`] for the storage version).
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct RpcCollection<AccountId> {
@@ -362,26 +365,41 @@
 
 pub type CollectionPropertiesVec = BoundedVec<Property, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
 
-/// All fields are wrapped in `Option`s, where None means chain default
-// When adding/removing fields from this struct - don't forget to also update clamp_limits
+/// Limits and restrictions of a collection.
+/// All fields are wrapped in `Option`s, where None means chain default.
+///
+/// todo:doc links to chain defaults
+// IMPORTANT: When adding/removing fields from this struct - don't forget to also
+// update clamp_limits() in pallet-common.
 #[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct CollectionLimits {
+	/// Maximum number of owned tokens per account. Chain default: [`ACCOUNT_TOKEN_OWNERSHIP_LIMIT`]
 	pub account_token_ownership_limit: Option<u32>,
+	/// Maximum size of data in bytes of a sponsored transaction. Chain default: [`CUSTOM_DATA_LIMIT`]
 	pub sponsored_data_size: Option<u32>,
 
 	/// FIXME should we delete this or repurpose it?
 	/// None - setVariableMetadata is not sponsored
 	/// Some(v) - setVariableMetadata is sponsored
 	///           if there is v block between txs
+	///
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	pub sponsored_data_rate_limit: Option<SponsoringRateLimit>,
+	/// Maximum amount of tokens inside the collection. Chain default: [`COLLECTION_TOKEN_LIMIT`]
 	pub token_limit: Option<u32>,
 
-	// Timeouts for item types in passed blocks
+	/// Timeout for sponsoring a token transfer in passed blocks. Chain default:
+	/// either [`NFT_SPONSOR_TRANSFER_TIMEOUT`], [`FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`], or [`REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`],
+	/// depending on the collection type.
 	pub sponsor_transfer_timeout: Option<u32>,
+	/// Timeout for sponsoring an approval in passed blocks. Chain default: [`SPONSOR_APPROVE_TIMEOUT`]
 	pub sponsor_approve_timeout: Option<u32>,
+	/// Can a token be transferred by the owner. Chain default: `false`
 	pub owner_can_transfer: Option<bool>,
+	/// Can a token be burned by the owner. Chain default: `true`
 	pub owner_can_destroy: Option<bool>,
+	/// Can a token be transferred at all. Chain default: `true`
 	pub transfers_enabled: Option<bool>,
 }
 
@@ -434,7 +452,10 @@
 	}
 }
 
-// When adding/removing fields from this struct - don't forget to also update clamp_limits
+/// Permissions on certain operations within a collection.
+/// All fields are wrapped in `Option`s, where None means chain default.
+// IMPORTANT: When adding/removing fields from this struct - don't forget to also
+// update clamp_limits() in pallet-common.
 #[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct CollectionPermissions {
@@ -489,6 +510,7 @@
 	}
 }
 
+/// Part of collection permissions, if set, defines who is able to nest tokens into other tokens.
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
@@ -505,38 +527,49 @@
 	pub permissive: bool,
 }
 
+/// Enum denominating how often can sponsoring occur if it is enabled.
 #[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum SponsoringRateLimit {
+	/// Sponsoring is disabled, and the collection sponsor will not pay for transactions
 	SponsoringDisabled,
+	/// Once per how many blocks can sponsorship of a transaction type occur
 	Blocks(u32),
 }
 
+/// Data used to describe an NFT at creation.
 #[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
 pub struct CreateNftData {
+	/// Key-value pairs used to describe the token as metadata
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub properties: CollectionPropertiesVec,
 }
 
+/// Data used to describe a Fungible token at creation.
 #[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct CreateFungibleData {
+	/// Number of fungible coins minted
 	pub value: u128,
 }
 
+/// Data used to describe a Refungible token at creation.
 #[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
 pub struct CreateReFungibleData {
+	/// Immutable metadata of the token
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
 
+	/// Number of pieces the RFT is split into
 	pub pieces: u128,
 
+	/// Key-value pairs used to describe the token as metadata
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub properties: CollectionPropertiesVec,
@@ -550,6 +583,7 @@
 	None,
 }
 
+/// Enum holding data used for creation of all three item types.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CreateItemData {
@@ -558,6 +592,7 @@
 	ReFungible(CreateReFungibleData),
 }
 
+/// Explicit NFT creation data with meta parameters.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
 #[derivative(Debug)]
 pub struct CreateNftExData<CrossAccountId> {
@@ -566,6 +601,7 @@
 	pub owner: CrossAccountId,
 }
 
+/// Explicit RFT creation data with meta parameters.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
 #[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
 pub struct CreateRefungibleExData<CrossAccountId> {
@@ -577,6 +613,7 @@
 	pub properties: CollectionPropertiesVec,
 }
 
+/// Explicit item creation data with meta parameters, namely the owner.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
 #[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
 pub enum CreateItemExData<CrossAccountId> {
@@ -624,6 +661,7 @@
 	}
 }
 
+/// Token's address, dictated by its collection and token IDs.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 // todo possibly rename to be used generally as an address pair
modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -57,7 +57,7 @@
        **/
       AddressNotInAllowlist: AugmentedError<ApiType>;
       /**
-       * Requested value more than approved.
+       * Requested value is more than the approved
        **/
       ApprovedValueTooLow: AugmentedError<ApiType>;
       /**
@@ -113,7 +113,7 @@
        **/
       EmptyPropertyKey: AugmentedError<ApiType>;
       /**
-       * Only ASCII letters, digits, and '_', '-' are allowed
+       * Only ASCII letters, digits, and symbols `_`, `-`, and `.` are allowed
        **/
       InvalidCharacterInPropertyKey: AugmentedError<ApiType>;
       /**
@@ -133,7 +133,7 @@
        **/
       NoSpaceForProperty: AugmentedError<ApiType>;
       /**
-       * Not sufficient funds to perform action
+       * Insufficient funds to perform an action
        **/
       NotSufficientFounds: AugmentedError<ApiType>;
       /**
@@ -153,15 +153,15 @@
        **/
       PublicMintingNotAllowed: AugmentedError<ApiType>;
       /**
-       * Only tokens from specific collections may nest tokens under this
+       * Only tokens from specific collections may nest tokens under this one
        **/
       SourceCollectionIsNotAllowedToNest: AugmentedError<ApiType>;
       /**
-       * Item not exists.
+       * Item does not exist
        **/
       TokenNotFound: AugmentedError<ApiType>;
       /**
-       * Item balance not enough.
+       * Item is balance not enough
        **/
       TokenValueTooLow: AugmentedError<ApiType>;
       /**
@@ -173,11 +173,11 @@
        **/
       TransferNotAllowed: AugmentedError<ApiType>;
       /**
-       * Target collection doesn't supports this operation
+       * Target collection doesn't support this operation
        **/
       UnsupportedOperation: AugmentedError<ApiType>;
       /**
-       * User not passed nesting rule
+       * User does not satisfy the nesting rule
        **/
       UserIsNotAllowedToNest: AugmentedError<ApiType>;
       /**
@@ -285,8 +285,7 @@
        **/
       FungibleItemsDontHaveData: AugmentedError<ApiType>;
       /**
-       * Not default id passed as TokenId argument.
-       * The default value of TokenId for Fungible collection is 0.
+       * Fungible tokens hold no ID, and the default value of TokenId for Fungible collection is 0.
        **/
       FungibleItemsHaveNoId: AugmentedError<ApiType>;
       /**
@@ -426,19 +425,19 @@
        **/
       NotRefungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;
       /**
-       * Refungible token can't nest other tokens
+       * Refungible token can't nest other tokens.
        **/
       RefungibleDisallowsNesting: AugmentedError<ApiType>;
       /**
-       * Refungible token can't be repartitioned by user who isn't owns all pieces
+       * Refungible token can't be repartitioned by user who isn't owns all pieces.
        **/
       RepartitionWhileNotOwningAllPieces: AugmentedError<ApiType>;
       /**
-       * Setting item properties is not allowed
+       * Setting item properties is not allowed.
        **/
       SettingPropertiesNotAllowed: AugmentedError<ApiType>;
       /**
-       * Maximum refungibility exceeded
+       * Maximum refungibility exceeded.
        **/
       WrongRefungiblePieces: AugmentedError<ApiType>;
       /**
@@ -509,19 +508,19 @@
     };
     structure: {
       /**
-       * While iterating over children, encountered breadth limit
+       * While iterating over children, reached the breadth limit.
        **/
       BreadthLimit: AugmentedError<ApiType>;
       /**
-       * While searched for owner, encountered depth limit
+       * While searching for the owner, reached the depth limit.
        **/
       DepthLimit: AugmentedError<ApiType>;
       /**
-       * While searched for owner, got already checked account
+       * While searching for the owner, encountered an already checked account, detecting a loop.
        **/
       OuroborosDetected: AugmentedError<ApiType>;
       /**
-       * While searched for owner, found token owner by not-yet-existing token
+       * Couldn't find the token owner that is itself a token.
        **/
       TokenNotFound: AugmentedError<ApiType>;
       /**
@@ -597,7 +596,7 @@
     };
     unique: {
       /**
-       * Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.
+       * Decimal_points parameter must be lower than [`up_data_structs::MAX_DECIMAL_POINTS`].
        **/
       CollectionDecimalPointLimitExceeded: AugmentedError<ApiType>;
       /**
@@ -609,7 +608,7 @@
        **/
       EmptyArgument: AugmentedError<ApiType>;
       /**
-       * Repertition is only supported by refungible collection
+       * Repertition is only supported by refungible collection.
        **/
       RepartitionCalledOnNonRefungibleCollection: AugmentedError<ApiType>;
       /**
modifiedtests/src/interfaces/augment-api-events.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-events.ts
+++ b/tests/src/interfaces/augment-api-events.ts
@@ -75,7 +75,7 @@
        **/
       CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;
       /**
-       * The colletion property has been set.
+       * The colletion property has been added or edited.
        **/
       CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;
       /**
@@ -87,7 +87,7 @@
        **/
       ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
       /**
-       * The colletion property permission has been set.
+       * The token property permission of a collection has been set.
        **/
       PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;
       /**
@@ -95,7 +95,7 @@
        **/
       TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;
       /**
-       * The token property has been set.
+       * The token property has been added or edited.
        **/
       TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;
       /**
@@ -407,7 +407,7 @@
     };
     structure: {
       /**
-       * Executed call on behalf of token
+       * Executed call on behalf of the token.
        **/
       Executed: AugmentedEvent<ApiType, [Result<Null, SpRuntimeDispatchError>]>;
       /**
@@ -499,90 +499,80 @@
     };
     unique: {
       /**
-       * Address was add to allow list
+       * Address was added to the allow list
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * user:  Address.
+       * * collection_id: ID of the affected collection.
+       * * user: Address of the added account.
        **/
       AllowListAddressAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Address was remove from allow list
+       * Address was removed from the allow list
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * user:  Address.
+       * * collection_id: ID of the affected collection.
+       * * user: Address of the removed account.
        **/
       AllowListAddressRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
        * Collection admin was added
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * admin:  Admin address.
+       * * collection_id: ID of the affected collection.
+       * * admin: Admin address.
        **/
       CollectionAdminAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
        * Collection admin was removed
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * admin:  Admin address.
+       * * collection_id: ID of the affected collection.
+       * * admin: Removed admin address.
        **/
       CollectionAdminRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Collection limits was set
+       * Collection limits were set
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
+       * * collection_id: ID of the affected collection.
        **/
       CollectionLimitSet: AugmentedEvent<ApiType, [u32]>;
       /**
-       * Collection owned was change
+       * Collection owned was changed
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * owner:  New owner address.
+       * * collection_id: ID of the affected collection.
+       * * owner: New owner address.
        **/
       CollectionOwnedChanged: AugmentedEvent<ApiType, [u32, AccountId32]>;
+      /**
+       * Collection permissions were set
+       * 
+       * # Arguments
+       * * collection_id: ID of the affected collection.
+       **/
       CollectionPermissionSet: AugmentedEvent<ApiType, [u32]>;
       /**
        * Collection sponsor was removed
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
+       * * collection_id: ID of the affected collection.
        **/
       CollectionSponsorRemoved: AugmentedEvent<ApiType, [u32]>;
       /**
        * Collection sponsor was set
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * owner:  New sponsor address.
+       * * collection_id: ID of the affected collection.
+       * * owner: New sponsor address.
        **/
       CollectionSponsorSet: AugmentedEvent<ApiType, [u32, AccountId32]>;
       /**
        * New sponsor was confirm
        * 
        * # Arguments
-       * 
-       * * collection_id: Globally unique collection identifier.
-       * 
-       * * sponsor:  New sponsor address.
+       * * collection_id: ID of the affected collection.
+       * * sponsor: New sponsor address.
        **/
       SponsorshipConfirmed: AugmentedEvent<ApiType, [u32, AccountId32]>;
       /**
modifiedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -70,11 +70,11 @@
     };
     common: {
       /**
-       * Storage of collection admins count.
+       * Storage of the amount of collection admins.
        **/
       adminAmount: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
-       * Allowlisted collection users
+       * Allowlisted collection users.
        **/
       allowlist: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
@@ -86,11 +86,11 @@
        **/
       collectionProperties: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
-       * Storage of collection properties permissions.
+       * Storage of token property permissions of a collection.
        **/
       collectionPropertyPermissions: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<BTreeMap<Bytes, UpDataStructsPropertyPermission>>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
-       * Storage of the count of created collections.
+       * Storage of the count of created collections. Essentially contains the last collection ID.
        **/
       createdCollectionCount: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;
       /**
@@ -102,7 +102,7 @@
        **/
       dummyStorageValue: AugmentedQuery<ApiType, () => Observable<Option<ITuple<[UpDataStructsCollectionStats, u32, u32, UpDataStructsTokenChild, PhantomTypeUpDataStructs]>>>, []> & QueryableStorageEntry<ApiType, []>;
       /**
-       * List of collection admins
+       * List of collection admins.
        **/
       isAdmin: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
@@ -200,7 +200,7 @@
     };
     fungible: {
       /**
-       * Storage for delegated assets.
+       * Storage for assets delegated to a limited extent to other users.
        **/
       allowance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u128>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
@@ -244,11 +244,11 @@
     };
     nonfungible: {
       /**
-       * Amount of tokens owned by account.
+       * Amount of tokens owned by an account in a collection.
        **/
       accountBalance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u32>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Allowance set by an owner for a spender for a token.
+       * Allowance set by a token owner for another user to perform one of certain transactions on a token.
        **/
       allowance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
@@ -256,7 +256,14 @@
        **/
       owned: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: u32 | AnyNumber | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]>;
       /**
-       * Custom data that is serialized to bytes and attached to a token property.
+       * Custom data of a token that is serialized to bytes,
+       * primarily reserved for on-chain operations,
+       * normally obscured from the external users.
+       * 
+       * Auxiliary properties are slightly different from
+       * usual [`TokenProperties`] due to an unlimited number
+       * and separately stored and written-to key-value pairs.
+       * 
        * Currently used to store RMRK data.
        **/
       tokenAuxProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: UpDataStructsPropertyScope | 'None' | 'Rmrk' | number | Uint8Array, arg4: Bytes | string | Uint8Array) => Observable<Option<Bytes>>, [u32, u32, UpDataStructsPropertyScope, Bytes]> & QueryableStorageEntry<ApiType, [u32, u32, UpDataStructsPropertyScope, Bytes]>;
@@ -265,19 +272,19 @@
        **/
       tokenChildren: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: ITuple<[u32, u32]> | [u32 | AnyNumber | Uint8Array, u32 | AnyNumber | Uint8Array]) => Observable<bool>, [u32, u32, ITuple<[u32, u32]>]> & QueryableStorageEntry<ApiType, [u32, u32, ITuple<[u32, u32]>]>;
       /**
-       * Custom data serialized to bytes for token.
+       * Token data, used to partially describe a token.
        **/
       tokenData: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<PalletNonfungibleItemData>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
-       * Key-Value map stored for token.
+       * Map of key-value pairs, describing the metadata of a token.
        **/
       tokenProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
-       * Amount of burnt tokens for collection.
+       * Amount of burnt tokens in a collection.
        **/
       tokensBurnt: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
-       * Amount of tokens minted for collection.
+       * Total amount of minted tokens in a collection.
        **/
       tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
@@ -444,32 +451,35 @@
     };
     refungible: {
       /**
-       * Amount of tokens owned by account
+       * Amount of tokens (not pieces) partially owned by an account within a collection.
        **/
       accountBalance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u32>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Allowance set by an owner for a spender for a token
+       * Allowance set by a token owner for another user to perform one of certain transactions on a number of pieces of a token.
        **/
       allowance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg4: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u128>, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Amount of token pieces owned by account
+       * Amount of token pieces owned by account.
        **/
       balance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u128>, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Used to enumerate tokens owned by account
+       * Used to enumerate tokens owned by account.
        **/
       owned: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: u32 | AnyNumber | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]>;
       /**
-       * Custom data serialized to bytes for token
+       * Token data, used to partially describe a token.
        **/
       tokenData: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<PalletRefungibleItemData>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
+      /**
+       * Amount of pieces a refungible token is split into.
+       **/
       tokenProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
-       * Amount of burnt tokens for collection
+       * Amount of tokens burnt in a collection.
        **/
       tokensBurnt: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
-       * Amount of tokens minted for collection
+       * Total amount of minted tokens in a collection.
        **/
       tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
       /**
@@ -663,24 +673,33 @@
        * TODO: Off chain worker should remove from this map when collection gets removed
        **/
       createItemBasket: AugmentedQuery<ApiType, (arg: ITuple<[u32, AccountId32]> | [u32 | AnyNumber | Uint8Array, AccountId32 | string | Uint8Array]) => Observable<Option<u32>>, [ITuple<[u32, AccountId32]>]> & QueryableStorageEntry<ApiType, [ITuple<[u32, AccountId32]>]>;
+      /**
+       * Last sponsoring of fungible tokens approval in a collection
+       **/
       fungibleApproveBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: AccountId32 | string | Uint8Array) => Observable<Option<u32>>, [u32, AccountId32]> & QueryableStorageEntry<ApiType, [u32, AccountId32]>;
       /**
        * Collection id (controlled?2), owning user (real)
        **/
       fungibleTransferBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: AccountId32 | string | Uint8Array) => Observable<Option<u32>>, [u32, AccountId32]> & QueryableStorageEntry<ApiType, [u32, AccountId32]>;
       /**
-       * Approval sponsoring
+       * Last sponsoring of NFT approval in a collection
        **/
       nftApproveBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<u32>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
        * Collection id (controlled?2), token id (controlled?2)
        **/
       nftTransferBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<u32>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
+      /**
+       * Last sponsoring of RFT approval in a collection
+       **/
       refungibleApproveBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: AccountId32 | string | Uint8Array) => Observable<Option<u32>>, [u32, u32, AccountId32]> & QueryableStorageEntry<ApiType, [u32, u32, AccountId32]>;
       /**
        * Collection id (controlled?2), token id (controlled?2)
        **/
       reFungibleTransferBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: AccountId32 | string | Uint8Array) => Observable<Option<u32>>, [u32, u32, AccountId32]> & QueryableStorageEntry<ApiType, [u32, u32, AccountId32]>;
+      /**
+       * Last sponsoring of token property setting // todo:doc rephrase this and the following
+       **/
       tokenPropertyBasket: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<u32>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
       /**
        * Variable metadata sponsoring
modifiedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -629,47 +629,47 @@
     };
     unique: {
       /**
-       * Get amount of different user tokens
+       * Get the amount of any user tokens owned by an account
        **/
       accountBalance: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u32>>;
       /**
-       * Get tokens owned by account
+       * Get tokens owned by an account in a collection
        **/
       accountTokens: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<u32>>>;
       /**
-       * Get admin list
+       * Get the list of admin accounts of a collection
        **/
       adminlist: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<PalletEvmAccountBasicCrossAccountIdRepr>>>;
       /**
-       * Get allowed amount
+       * Get the amount of currently possible sponsored transactions on a token for the fee to be taken off a sponsor
        **/
       allowance: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, sender: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, spender: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
       /**
-       * Check if user is allowed to use collection
+       * Check if a user is allowed to operate within a collection
        **/
       allowed: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<bool>>;
       /**
-       * Get allowlist
+       * Get the list of accounts allowed to operate within a collection
        **/
       allowlist: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<PalletEvmAccountBasicCrossAccountIdRepr>>>;
       /**
-       * Get amount of specific account token
+       * Get the amount of a specific token owned by an account
        **/
       balance: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
       /**
-       * Get collection by specified id
+       * Get a collection by the specified ID
        **/
       collectionById: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsRpcCollection>>>;
       /**
-       * Get collection properties
+       * Get collection properties, optionally limited to the provided keys
        **/
       collectionProperties: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsProperty>>>;
       /**
-       * Get collection stats
+       * Get chain stats about collections
        **/
       collectionStats: AugmentedRpc<(at?: Hash | string | Uint8Array) => Observable<UpDataStructsCollectionStats>>;
       /**
-       * Get tokens contained in collection
+       * Get tokens contained within a collection
        **/
       collectionTokens: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<u32>>>;
       /**
@@ -681,15 +681,15 @@
        **/
       effectiveCollectionLimits: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsCollectionLimits>>>;
       /**
-       * Get last token id
+       * Get the last token ID created in a collection
        **/
       lastTokenId: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u32>>;
       /**
-       * Get number of blocks when sponsored transaction is available
+       * Get the number of blocks until sponsoring a transaction is available
        **/
       nextSponsored: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<u64>>>;
       /**
-       * Get property permissions
+       * Get property permissions, optionally limited to the provided keys
        **/
       propertyPermissions: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsPropertyKeyPermission>>>;
       /**
@@ -697,15 +697,15 @@
        **/
       tokenChildren: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsTokenChild>>>;
       /**
-       * Get token data
+       * Get token data, including properties, optionally limited to the provided keys, and total pieces for an RFT
        **/
       tokenData: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<UpDataStructsTokenData>>;
       /**
-       * Check if token exists
+       * Check if the token exists
        **/
       tokenExists: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<bool>>;
       /**
-       * Get token owner
+       * Get the token owner
        **/
       tokenOwner: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>>;
       /**
@@ -713,19 +713,19 @@
        **/
       tokenOwners: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<PalletEvmAccountBasicCrossAccountIdRepr>>>;
       /**
-       * Get token properties
+       * Get token properties, optionally limited to the provided keys
        **/
       tokenProperties: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsProperty>>>;
       /**
-       * Get token owner, in case of nested token - find parent recursive
+       * Get the topmost token owner in the hierarchy of a possibly nested token
        **/
       topmostTokenOwner: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>>;
       /**
-       * Get total pieces of token
+       * Get the total amount of pieces of an RFT
        **/
       totalPieces: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<u128>>>;
       /**
-       * Get amount of unique collection tokens
+       * Get the amount of distinctive tokens present in a collection
        **/
       totalSupply: 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
@@ -730,87 +730,99 @@
     };
     unique: {
       /**
-       * Adds an admin of the Collection.
-       * NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.
+       * Add an admin to a collection.
+       * 
+       * NFT Collection can be controlled by multiple admin addresses
+       * (some which can also be servers, for example). Admins can issue
+       * and burn NFTs, as well as add and remove other admins,
+       * but cannot change NFT or Collection ownership.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
-       * * Collection Admin.
+       * * Collection owner
+       * * Collection admin
        * 
        * # Arguments
-       * 
-       * * collection_id: ID of the Collection to add admin for.
        * 
-       * * new_admin_id: Address of new admin to add.
+       * * `collection_id`: ID of the Collection to add an admin for.
+       * * `new_admin`: Address of new admin to add.
        **/
-      addCollectionAdmin: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newAdminId: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
+      addCollectionAdmin: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newAdmin: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
        * Add an address to allow list.
        * 
        * # Permissions
        * 
-       * * Collection Owner
-       * * Collection Admin
+       * * Collection owner
+       * * Collection admin
        * 
        * # Arguments
        * 
-       * * collection_id.
-       * 
-       * * address.
+       * * `collection_id`: ID of the modified collection.
+       * * `address`: ID of the address to be added to the allowlist.
        **/
       addToAllowList: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, address: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Set, change, or remove approved address to transfer the ownership of the NFT.
+       * Allow a non-permissioned address to transfer or burn an item.
        * 
        * # Permissions
        * 
-       * * Collection Owner
-       * * Collection Admin
-       * * Current NFT owner
+       * * Collection owner
+       * * Collection admin
+       * * Current item owner
        * 
        * # Arguments
-       * 
-       * * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).
        * 
-       * * collection_id.
-       * 
-       * * item_id: ID of the item.
+       * * `spender`: Account to be approved to make specific transactions on non-owned tokens.
+       * * `collection_id`: ID of the collection the item belongs to.
+       * * `item_id`: ID of the item transactions on which are now approved.
+       * * `amount`: Number of pieces of the item approved for a transaction (maximum of 1 for NFTs).
+       * Set to 0 to revoke the approval.
        **/
       approve: AugmentedSubmittable<(spender: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PalletEvmAccountBasicCrossAccountIdRepr, u32, u32, u128]>;
       /**
-       * Destroys a concrete instance of NFT on behalf of the owner
-       * See also: [`approve`]
+       * Destroy a token on behalf of the owner as a non-owner account.
+       * 
+       * See also: [`approve`][`Pallet::approve`].
+       * 
+       * After this method executes, one approval is removed from the total so that
+       * the approved address will not be able to transfer this item again from this owner.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
-       * * Collection Admin.
-       * * Current NFT Owner.
+       * * Collection owner
+       * * Collection admin
+       * * Current token owner
+       * * Address approved by current item owner
        * 
        * # Arguments
        * 
-       * * collection_id: ID of the collection.
-       * 
-       * * item_id: ID of NFT to burn.
-       * 
-       * * from: owner of item
+       * * `from`: The owner of the burning item.
+       * * `collection_id`: ID of the collection to which the item belongs.
+       * * `item_id`: ID of item to burn.
+       * * `value`: Number of pieces to burn.
+       * * Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+       * * Fungible Mode: The desired number of pieces to burn.
+       * * Re-Fungible Mode: The desired number of pieces to burn.
        **/
       burnFrom: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, from: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, itemId: u32 | AnyNumber | Uint8Array, value: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32, u128]>;
       /**
-       * Destroys a concrete instance of NFT.
+       * Destroy an item.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
-       * * Collection Admin.
-       * * Current NFT Owner.
+       * * Collection owner
+       * * Collection admin
+       * * Current item owner
        * 
        * # Arguments
        * 
-       * * collection_id: ID of the collection.
-       * 
-       * * item_id: ID of NFT to burn.
+       * * `collection_id`: ID of the collection to which the item belongs.
+       * * `item_id`: ID of item to burn.
+       * * `value`: Number of pieces of the item to destroy.
+       * * Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+       * * Fungible Mode: The desired number of pieces to burn.
+       * * Re-Fungible Mode: The desired number of pieces to burn.
        **/
       burnItem: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array, value: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;
       /**
@@ -818,131 +830,200 @@
        * 
        * # Permissions
        * 
-       * * Collection Owner.
+       * * Collection owner
        * 
        * # Arguments
        * 
-       * * collection_id.
-       * 
-       * * new_owner.
+       * * `collection_id`: ID of the modified collection.
+       * * `new_owner`: ID of the account that will become the owner.
        **/
       changeCollectionOwner: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newOwner: AccountId32 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, AccountId32]>;
       /**
+       * Confirm own sponsorship of a collection, becoming the sponsor.
+       * 
+       * An invitation must be pending, see [`set_collection_sponsor`][`Pallet::set_collection_sponsor`].
+       * Sponsor can pay the fees of a transaction instead of the sender,
+       * but only within specified limits.
+       * 
        * # Permissions
        * 
-       * * Sponsor.
+       * * Sponsor-to-be
        * 
        * # Arguments
        * 
-       * * collection_id.
+       * * `collection_id`: ID of the collection with the pending sponsor.
        **/
       confirmSponsorship: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
       /**
-       * This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner of the collection is set to the address that signed the transaction and can be changed later.
+       * Create a collection of tokens.
+       * 
+       * Each Token may have multiple properties encoded as an array of bytes
+       * of certain length. The initial owner of the collection is set
+       * to the address that signed the transaction and can be changed later.
+       * 
+       * Prefer the more advanced [`create_collection_ex`][`Pallet::create_collection_ex`] instead.
        * 
        * # Permissions
        * 
-       * * Anyone.
+       * * Anyone - becomes the owner of the new collection.
        * 
        * # Arguments
        * 
-       * * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.
+       * * `collection_name`: Wide-character string with collection name
+       * (limit [`MAX_COLLECTION_NAME_LENGTH`]).
+       * * `collection_description`: Wide-character string with collection description
+       * (limit [`MAX_COLLECTION_DESCRIPTION_LENGTH`]).
+       * * `token_prefix`: Byte string containing the token prefix to mark a collection
+       * to which a token belongs (limit [`MAX_TOKEN_PREFIX_LENGTH`]).
+       * * `mode`: Type of items stored in the collection and type dependent data.
+       **/
+      createCollection: AugmentedSubmittable<(collectionName: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], collectionDescription: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], tokenPrefix: Bytes | string | Uint8Array, mode: UpDataStructsCollectionMode | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [Vec<u16>, Vec<u16>, Bytes, UpDataStructsCollectionMode]>;
+      /**
+       * Create a collection with explicit parameters.
        * 
-       * * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.
+       * Prefer it to the deprecated [`create_collection`][`Pallet::create_collection`] method.
+       * 
+       * # Permissions
        * 
-       * * token_prefix: UTF-8 string with token prefix.
+       * * Anyone - becomes the owner of the new collection.
        * 
-       * * mode: [CollectionMode] collection type and type dependent data.
-       **/
-      createCollection: AugmentedSubmittable<(collectionName: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], collectionDescription: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], tokenPrefix: Bytes | string | Uint8Array, mode: UpDataStructsCollectionMode | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [Vec<u16>, Vec<u16>, Bytes, UpDataStructsCollectionMode]>;
-      /**
-       * This method creates a collection
+       * # Arguments
        * 
-       * Prefer it to deprecated [`created_collection`] method
+       * * `data`: Explicit data of a collection used for its creation.
        **/
       createCollectionEx: AugmentedSubmittable<(data: UpDataStructsCreateCollectionData | { mode?: any; access?: any; name?: any; description?: any; tokenPrefix?: any; pendingSponsor?: any; limits?: any; permissions?: any; tokenPropertyPermissions?: any; properties?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [UpDataStructsCreateCollectionData]>;
       /**
-       * This method creates a concrete instance of NFT Collection created with CreateCollection method.
+       * Mint an item within a collection.
        * 
+       * A collection must exist first, see [`create_collection_ex`][`Pallet::create_collection_ex`].
+       * 
        * # Permissions
        * 
-       * * Collection Owner.
-       * * Collection Admin.
+       * * Collection owner
+       * * Collection admin
        * * Anyone if
        * * Allow List is enabled, and
        * * Address is added to allow list, and
-       * * MintPermission is enabled (see SetMintPermission method)
+       * * MintPermission is enabled (see [`set_collection_permissions`][`Pallet::set_collection_permissions`])
        * 
        * # Arguments
        * 
-       * * collection_id: ID of the collection.
+       * * `collection_id`: ID of the collection to which an item would belong.
+       * * `owner`: Address of the initial owner of the item.
+       * * `data`: Token data describing the item to store on chain.
+       **/
+      createItem: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, owner: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, data: UpDataStructsCreateItemData | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCreateItemData]>;
+      /**
+       * Create multiple items within a collection.
        * 
-       * * owner: Address, initial owner of the NFT.
+       * A collection must exist first, see [`create_collection_ex`][`Pallet::create_collection_ex`].
+       * 
+       * # Permissions
+       * 
+       * * Collection owner
+       * * Collection admin
+       * * Anyone if
+       * * Allow List is enabled, and
+       * * Address is added to the allow list, and
+       * * MintPermission is enabled (see [`set_collection_permissions`][`Pallet::set_collection_permissions`])
        * 
-       * * data: Token data to store on chain.
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the collection to which the tokens would belong.
+       * * `owner`: Address of the initial owner of the tokens.
+       * * `items_data`: Vector of data describing each item to be created.
        **/
-      createItem: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, owner: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, data: UpDataStructsCreateItemData | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCreateItemData]>;
+      createMultipleItems: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, owner: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, itemsData: Vec<UpDataStructsCreateItemData> | (UpDataStructsCreateItemData | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, Vec<UpDataStructsCreateItemData>]>;
       /**
-       * This method creates multiple items in a collection created with CreateCollection method.
+       * Create multiple items within a collection with explicitly specified initial parameters.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
-       * * Collection Admin.
+       * * Collection owner
+       * * Collection admin
        * * Anyone if
        * * Allow List is enabled, and
        * * Address is added to allow list, and
-       * * MintPermission is enabled (see SetMintPermission method)
+       * * MintPermission is enabled (see [`set_collection_permissions`][`Pallet::set_collection_permissions`])
        * 
        * # Arguments
        * 
-       * * collection_id: ID of the collection.
+       * * `collection_id`: ID of the collection to which the tokens would belong.
+       * * `data`: Explicit item creation data.
+       **/
+      createMultipleItemsEx: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, data: UpDataStructsCreateItemExData | { NFT: any } | { Fungible: any } | { RefungibleMultipleItems: any } | { RefungibleMultipleOwners: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsCreateItemExData]>;
+      /**
+       * Delete specified collection properties.
        * 
-       * * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].
+       * # Permissions
+       * 
+       * * Collection Owner
+       * * Collection Admin
+       * 
+       * # Arguments
        * 
-       * * owner: Address, initial owner of the NFT.
+       * * `collection_id`: ID of the modified collection.
+       * * `property_keys`: Vector of keys of the properties to be deleted.
+       * Keys support Latin letters, `-`, `_`, and `.` as symbols.
        **/
-      createMultipleItems: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, owner: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, itemsData: Vec<UpDataStructsCreateItemData> | (UpDataStructsCreateItemData | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, Vec<UpDataStructsCreateItemData>]>;
-      createMultipleItemsEx: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, data: UpDataStructsCreateItemExData | { NFT: any } | { Fungible: any } | { RefungibleMultipleItems: any } | { RefungibleMultipleOwners: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsCreateItemExData]>;
       deleteCollectionProperties: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, propertyKeys: Vec<Bytes> | (Bytes | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, Vec<Bytes>]>;
+      /**
+       * Delete specified token properties. Currently properties only work with NFTs.
+       * 
+       * # Permissions
+       * 
+       * * Depends on collection's token property permissions and specified property mutability:
+       * * Collection owner
+       * * Collection admin
+       * * Token owner
+       * 
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the collection to which the token belongs.
+       * * `token_id`: ID of the modified token.
+       * * `property_keys`: Vector of keys of the properties to be deleted.
+       * Keys support Latin letters, `-`, `_`, and `.` as symbols.
+       **/
       deleteTokenProperties: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys: Vec<Bytes> | (Bytes | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, u32, Vec<Bytes>]>;
       /**
-       * Destroys collection if no tokens within this collection
+       * Destroy a collection if no tokens exist within.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
+       * * Collection owner
        * 
        * # Arguments
        * 
-       * * collection_id: collection to destroy.
+       * * `collection_id`: Collection to destroy.
        **/
       destroyCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
       /**
-       * Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.
+       * Remove admin of a collection.
+       * 
+       * An admin address can remove itself. List of admins may become empty,
+       * in which case only Collection Owner will be able to add an Admin.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
-       * * Collection Admin.
+       * * Collection owner
+       * * Collection admin
        * 
        * # Arguments
        * 
-       * * collection_id: ID of the Collection to remove admin for.
-       * 
-       * * account_id: Address of admin to remove.
+       * * `collection_id`: ID of the collection to remove the admin for.
+       * * `account_id`: Address of the admin to remove.
        **/
       removeCollectionAdmin: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, accountId: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
       /**
-       * Switch back to pay-per-own-transaction model.
+       * Remove a collection's a sponsor, making everyone pay for their own transactions.
        * 
        * # Permissions
        * 
-       * * Collection owner.
+       * * Collection owner
        * 
        * # Arguments
        * 
-       * * collection_id.
+       * * `collection_id`: ID of the collection with the sponsor to remove.
        **/
       removeCollectionSponsor: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
       /**
@@ -950,46 +1031,140 @@
        * 
        * # Permissions
        * 
-       * * Collection Owner
-       * * Collection Admin
+       * * Collection owner
+       * * Collection admin
        * 
        * # Arguments
        * 
-       * * collection_id.
+       * * `collection_id`: ID of the modified collection.
+       * * `address`: ID of the address to be removed from the allowlist.
+       **/
+      removeFromAllowList: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, address: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
+      /**
+       * Re-partition a refungible token, while owning all of its parts/pieces.
+       * 
+       * # Permissions
+       * 
+       * * Token owner (must own every part)
+       * 
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the collection the RFT belongs to.
+       * * `token_id`: ID of the RFT.
+       * * `amount`: New number of parts/pieces into which the token shall be partitioned.
+       **/
+      repartition: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;
+      /**
+       * Set specific limits of a collection. Empty, or None fields mean chain default.
+       * 
+       * # Permissions
        * 
-       * * address.
+       * * Collection owner
+       * * Collection admin
+       * 
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the modified collection.
+       * * `new_limit`: New limits of the collection. Fields that are not set (None)
+       * will not overwrite the old ones.
        **/
-      removeFromAllowList: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, address: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
-      repartition: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, token: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;
       setCollectionLimits: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newLimit: UpDataStructsCollectionLimits | { accountTokenOwnershipLimit?: any; sponsoredDataSize?: any; sponsoredDataRateLimit?: any; tokenLimit?: any; sponsorTransferTimeout?: any; sponsorApproveTimeout?: any; ownerCanTransfer?: any; ownerCanDestroy?: any; transfersEnabled?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsCollectionLimits]>;
-      setCollectionPermissions: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newLimit: UpDataStructsCollectionPermissions | { access?: any; mintMode?: any; nesting?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsCollectionPermissions]>;
-      setCollectionProperties: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, properties: Vec<UpDataStructsProperty> | (UpDataStructsProperty | { key?: any; value?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, Vec<UpDataStructsProperty>]>;
       /**
+       * Set specific permissions of a collection. Empty, or None fields mean chain default.
+       * 
        * # Permissions
        * 
-       * * Collection Owner
+       * * Collection owner
+       * * Collection admin
        * 
        * # Arguments
        * 
-       * * collection_id.
+       * * `collection_id`: ID of the modified collection.
+       * * `new_permission`: New permissions of the collection. Fields that are not set (None)
+       * will not overwrite the old ones.
+       **/
+      setCollectionPermissions: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newPermission: UpDataStructsCollectionPermissions | { access?: any; mintMode?: any; nesting?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsCollectionPermissions]>;
+      /**
+       * Add or change collection properties.
+       * 
+       * # Permissions
+       * 
+       * * Collection owner
+       * * Collection admin
        * 
-       * * new_sponsor.
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the modified collection.
+       * * `properties`: Vector of key-value pairs stored as the collection's metadata.
+       * Keys support Latin letters, `-`, `_`, and `.` as symbols.
        **/
+      setCollectionProperties: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, properties: Vec<UpDataStructsProperty> | (UpDataStructsProperty | { key?: any; value?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, Vec<UpDataStructsProperty>]>;
+      /**
+       * Set (invite) a new collection sponsor.
+       * 
+       * If successful, confirmation from the sponsor-to-be will be pending.
+       * 
+       * # Permissions
+       * 
+       * * Collection owner
+       * * Collection admin
+       * 
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the modified collection.
+       * * `new_sponsor`: ID of the account of the sponsor-to-be.
+       **/
       setCollectionSponsor: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, newSponsor: AccountId32 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, AccountId32]>;
+      /**
+       * Add or change token properties according to collection's permissions.
+       * Currently properties only work with NFTs.
+       * 
+       * # Permissions
+       * 
+       * * Depends on collection's token property permissions and specified property mutability:
+       * * Collection owner
+       * * Collection admin
+       * * Token owner
+       * 
+       * See [`set_token_property_permissions`][`Pallet::set_token_property_permissions`].
+       * 
+       * # Arguments
+       * 
+       * * `collection_id: ID of the collection to which the token belongs.
+       * * `token_id`: ID of the modified token.
+       * * `properties`: Vector of key-value pairs stored as the token's metadata.
+       * Keys support Latin letters, `-`, `_`, and `.` as symbols.
+       **/
       setTokenProperties: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, properties: Vec<UpDataStructsProperty> | (UpDataStructsProperty | { key?: any; value?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, u32, Vec<UpDataStructsProperty>]>;
-      setTokenPropertyPermissions: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, propertyPermissions: Vec<UpDataStructsPropertyKeyPermission> | (UpDataStructsPropertyKeyPermission | { key?: any; permission?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, Vec<UpDataStructsPropertyKeyPermission>]>;
       /**
-       * Set transfers_enabled value for particular collection
+       * Add or change token property permissions of a collection.
+       * 
+       * Without a permission for a particular key, a property with that key
+       * cannot be created in a token.
        * 
        * # Permissions
        * 
-       * * Collection Owner.
+       * * Collection owner
+       * * Collection admin
        * 
        * # Arguments
        * 
-       * * collection_id: ID of the collection.
+       * * `collection_id`: ID of the modified collection.
+       * * `property_permissions`: Vector of permissions for property keys.
+       * Keys support Latin letters, `-`, `_`, and `.` as symbols.
+       **/
+      setTokenPropertyPermissions: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, propertyPermissions: Vec<UpDataStructsPropertyKeyPermission> | (UpDataStructsPropertyKeyPermission | { key?: any; permission?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [u32, Vec<UpDataStructsPropertyKeyPermission>]>;
+      /**
+       * Completely allow or disallow transfers for a particular collection.
        * 
-       * * value: New flag value.
+       * # Permissions
+       * 
+       * * Collection owner
+       * 
+       * # Arguments
+       * 
+       * * `collection_id`: ID of the collection.
+       * * `value`: New value of the flag, are transfers allowed?
        **/
       setTransfersEnabledFlag: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, value: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, bool]>;
       /**
@@ -997,47 +1172,50 @@
        * 
        * # Permissions
        * 
-       * * Collection Owner
-       * * Collection Admin
-       * * Current NFT owner
+       * * Collection owner
+       * * Collection admin
+       * * Current token owner
        * 
        * # Arguments
        * 
-       * * recipient: Address of token recipient.
-       * 
-       * * collection_id.
-       * 
-       * * item_id: ID of the item
+       * * `recipient`: Address of token recipient.
+       * * `collection_id`: ID of the collection the item belongs to.
+       * * `item_id`: ID of the item.
        * * Non-Fungible Mode: Required.
        * * Fungible Mode: Ignored.
        * * Re-Fungible Mode: Required.
        * 
-       * * value: Amount to transfer.
-       * * Non-Fungible Mode: Ignored
-       * * Fungible Mode: Must specify transferred amount
-       * * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)
+       * * `value`: Amount to transfer.
+       * * Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+       * * Fungible Mode: The desired number of pieces to transfer.
+       * * Re-Fungible Mode: The desired number of pieces to transfer.
        **/
       transfer: AugmentedSubmittable<(recipient: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array, value: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PalletEvmAccountBasicCrossAccountIdRepr, u32, u32, u128]>;
       /**
-       * Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.
-       * 
-       * # Permissions
-       * * Collection Owner
-       * * Collection Admin
-       * * Current NFT owner
-       * * Address approved by current NFT owner
+       * Change ownership of an item on behalf of the owner as a non-owner account.
        * 
-       * # Arguments
+       * See the [`approve`][`Pallet::approve`] method for additional information.
        * 
-       * * from: Address that owns token.
+       * After this method executes, one approval is removed from the total so that
+       * the approved address will not be able to transfer this item again from this owner.
        * 
-       * * recipient: Address of token recipient.
+       * # Permissions
        * 
-       * * collection_id.
+       * * Collection owner
+       * * Collection admin
+       * * Current item owner
+       * * Address approved by current item owner
        * 
-       * * item_id: ID of the item.
+       * # Arguments
        * 
-       * * value: Amount to transfer.
+       * * `from`: Address that currently owns the token.
+       * * `recipient`: Address of the new token-owner-to-be.
+       * * `collection_id`: ID of the collection the item.
+       * * `item_id`: ID of the item to be transferred.
+       * * `value`: Amount to transfer.
+       * * Non-Fungible Mode: An NFT is indivisible, there is always 1 corresponding to an ID.
+       * * Fungible Mode: The desired number of pieces to transfer.
+       * * Re-Fungible Mode: The desired number of pieces to transfer.
        **/
       transferFrom: AugmentedSubmittable<(from: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, recipient: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array, value: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u32, u32, u128]>;
       /**
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -1672,7 +1672,7 @@
   readonly isAddCollectionAdmin: boolean;
   readonly asAddCollectionAdmin: {
     readonly collectionId: u32;
-    readonly newAdminId: PalletEvmAccountBasicCrossAccountIdRepr;
+    readonly newAdmin: PalletEvmAccountBasicCrossAccountIdRepr;
   } & Struct;
   readonly isRemoveCollectionAdmin: boolean;
   readonly asRemoveCollectionAdmin: {
@@ -1784,12 +1784,12 @@
   readonly isSetCollectionPermissions: boolean;
   readonly asSetCollectionPermissions: {
     readonly collectionId: u32;
-    readonly newLimit: UpDataStructsCollectionPermissions;
+    readonly newPermission: UpDataStructsCollectionPermissions;
   } & Struct;
   readonly isRepartition: boolean;
   readonly asRepartition: {
     readonly collectionId: u32;
-    readonly token: u32;
+    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';
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1269,7 +1269,7 @@
       },
       add_collection_admin: {
         collectionId: 'u32',
-        newAdminId: 'PalletEvmAccountBasicCrossAccountIdRepr',
+        newAdmin: 'PalletEvmAccountBasicCrossAccountIdRepr',
       },
       remove_collection_admin: {
         collectionId: 'u32',
@@ -1361,11 +1361,11 @@
       },
       set_collection_permissions: {
         collectionId: 'u32',
-        newLimit: 'UpDataStructsCollectionPermissions',
+        newPermission: 'UpDataStructsCollectionPermissions',
       },
       repartition: {
         collectionId: 'u32',
-        token: 'u32',
+        tokenId: 'u32',
         amount: 'u128'
       }
     }
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1385,7 +1385,7 @@
     readonly isAddCollectionAdmin: boolean;
     readonly asAddCollectionAdmin: {
       readonly collectionId: u32;
-      readonly newAdminId: PalletEvmAccountBasicCrossAccountIdRepr;
+      readonly newAdmin: PalletEvmAccountBasicCrossAccountIdRepr;
     } & Struct;
     readonly isRemoveCollectionAdmin: boolean;
     readonly asRemoveCollectionAdmin: {
@@ -1497,12 +1497,12 @@
     readonly isSetCollectionPermissions: boolean;
     readonly asSetCollectionPermissions: {
       readonly collectionId: u32;
-      readonly newLimit: UpDataStructsCollectionPermissions;
+      readonly newPermission: UpDataStructsCollectionPermissions;
     } & Struct;
     readonly isRepartition: boolean;
     readonly asRepartition: {
       readonly collectionId: u32;
-      readonly token: u32;
+      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';
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/definitions.ts
+++ b/tests/src/interfaces/unique/definitions.ts
@@ -37,49 +37,143 @@
 export default {
   types: {},
   rpc: {
-    adminlist: fun('Get admin list', [collectionParam], 'Vec<PalletEvmAccountBasicCrossAccountIdRepr>'),
-    allowlist: fun('Get allowlist', [collectionParam], 'Vec<PalletEvmAccountBasicCrossAccountIdRepr>'),
+    accountTokens: fun(
+      'Get tokens owned by an account in a collection', 
+      [collectionParam, crossAccountParam()], 
+      'Vec<u32>',
+    ),
+    collectionTokens: fun(
+      'Get tokens contained within a collection', 
+      [collectionParam], 
+      'Vec<u32>',
+    ),
+    tokenExists: fun(
+      'Check if the token exists', 
+      [collectionParam, tokenParam], 
+      'bool',
+    ),
 
-    accountTokens: fun('Get tokens owned by account', [collectionParam, crossAccountParam()], 'Vec<u32>'),
-    collectionTokens: fun('Get tokens contained in collection', [collectionParam], 'Vec<u32>'),
+    tokenOwner: fun(
+      'Get the token owner', 
+      [collectionParam, tokenParam], 
+      `Option<${CROSS_ACCOUNT_ID_TYPE}>`,
+    ),
+    topmostTokenOwner: fun(
+      'Get the topmost token owner in the hierarchy of a possibly nested token', 
+      [collectionParam, tokenParam], 
+      `Option<${CROSS_ACCOUNT_ID_TYPE}>`,
+    ),
+    tokenOwners: fun(
+      'Returns 10 tokens owners in no particular order', 
+      [collectionParam, tokenParam], 
+      `Vec<${CROSS_ACCOUNT_ID_TYPE}>`,
+    ),
+    tokenChildren: fun(
+      'Get tokens nested directly into the token', 
+      [collectionParam, tokenParam], 
+      'Vec<UpDataStructsTokenChild>',
+    ),
 
-    lastTokenId: fun('Get last token id', [collectionParam], 'u32'),
-    totalSupply: fun('Get amount of unique collection tokens', [collectionParam], 'u32'),
-    accountBalance: fun('Get amount of different user tokens', [collectionParam, crossAccountParam()], 'u32'),
-    balance: fun('Get amount of specific account token', [collectionParam, crossAccountParam(), tokenParam], 'u128'),
-    allowance: fun('Get allowed amount', [collectionParam, crossAccountParam('sender'), crossAccountParam('spender'), tokenParam], 'u128'),
-    tokenOwner: fun('Get token owner', [collectionParam, tokenParam], `Option<${CROSS_ACCOUNT_ID_TYPE}>`),
-    tokenOwners: fun('Returns 10 tokens owners in no particular order', [collectionParam, tokenParam], `Vec<${CROSS_ACCOUNT_ID_TYPE}>`),
-    topmostTokenOwner: fun('Get token owner, in case of nested token - find parent recursive', [collectionParam, tokenParam], `Option<${CROSS_ACCOUNT_ID_TYPE}>`),
-    tokenChildren: fun('Get tokens nested directly into the token', [collectionParam, tokenParam], 'Vec<UpDataStructsTokenChild>'),
-    constMetadata: fun('Get token constant metadata', [collectionParam, tokenParam], 'Vec<u8>'),
-    variableMetadata: fun('Get token variable metadata', [collectionParam, tokenParam], 'Vec<u8>'),
     collectionProperties: fun(
-      'Get collection properties',
+      'Get collection properties, optionally limited to the provided keys',
       [collectionParam, propertyKeysParam],
       'Vec<UpDataStructsProperty>',
     ),
     tokenProperties: fun(
-      'Get token properties',
+      'Get token properties, optionally limited to the provided keys',
       [collectionParam, tokenParam, propertyKeysParam],
       'Vec<UpDataStructsProperty>',
     ),
     propertyPermissions: fun(
-      'Get property permissions',
+      'Get property permissions, optionally limited to the provided keys',
       [collectionParam, propertyKeysParam],
       'Vec<UpDataStructsPropertyKeyPermission>',
     ),
+
+    constMetadata: fun(
+      'Get token constant metadata', 
+      [collectionParam, tokenParam], 
+      'Vec<u8>',
+    ),
+    variableMetadata: fun(
+      'Get token variable metadata', 
+      [collectionParam, tokenParam], 
+      'Vec<u8>',
+    ),
+
     tokenData: fun(
-      'Get token data',
+      'Get token data, including properties, optionally limited to the provided keys, and total pieces for an RFT',
       [collectionParam, tokenParam, propertyKeysParam],
       'UpDataStructsTokenData',
     ),
-    tokenExists: fun('Check if token exists', [collectionParam, tokenParam], 'bool'),
-    collectionById: fun('Get collection by specified id', [collectionParam], 'Option<UpDataStructsRpcCollection>'),
-    collectionStats: fun('Get collection stats', [], 'UpDataStructsCollectionStats'),
-    allowed: fun('Check if user is allowed to use collection', [collectionParam, crossAccountParam()], 'bool'),
-    nextSponsored: fun('Get number of blocks when sponsored transaction is available', [collectionParam, crossAccountParam(), tokenParam], 'Option<u64>'),
-    effectiveCollectionLimits: fun('Get effective collection limits', [collectionParam], 'Option<UpDataStructsCollectionLimits>'),
-    totalPieces: fun('Get total pieces of token', [collectionParam, tokenParam], 'Option<u128>'),
+    totalSupply: fun(
+      'Get the amount of distinctive tokens present in a collection', 
+      [collectionParam], 
+      'u32',
+    ),
+
+    accountBalance: fun(
+      'Get the amount of any user tokens owned by an account', 
+      [collectionParam, crossAccountParam()], 
+      'u32',
+    ),
+    balance: fun(
+      'Get the amount of a specific token owned by an account', 
+      [collectionParam, crossAccountParam(), tokenParam], 
+      'u128',
+    ),
+    allowance: fun(
+      'Get the amount of currently possible sponsored transactions on a token for the fee to be taken off a sponsor', 
+      [collectionParam, crossAccountParam('sender'), crossAccountParam('spender'), tokenParam], 
+      'u128',
+    ),
+
+    adminlist: fun(
+      'Get the list of admin accounts of a collection', 
+      [collectionParam], 
+      'Vec<PalletEvmAccountBasicCrossAccountIdRepr>',
+    ),
+    allowlist: fun(
+      'Get the list of accounts allowed to operate within a collection', 
+      [collectionParam], 
+      'Vec<PalletEvmAccountBasicCrossAccountIdRepr>',
+    ),
+    allowed: fun(
+      'Check if a user is allowed to operate within a collection', 
+      [collectionParam, crossAccountParam()], 
+      'bool',
+    ),
+
+    lastTokenId: fun(
+      'Get the last token ID created in a collection', 
+      [collectionParam], 
+      'u32',
+    ),
+    collectionById: fun(
+      'Get a collection by the specified ID', 
+      [collectionParam], 
+      'Option<UpDataStructsRpcCollection>',
+    ),
+    collectionStats: fun(
+      'Get chain stats about collections', 
+      [], 
+      'UpDataStructsCollectionStats',
+    ),
+
+    nextSponsored: fun(
+      'Get the number of blocks until sponsoring a transaction is available', 
+      [collectionParam, crossAccountParam(), tokenParam], 
+      'Option<u64>',
+    ),
+    effectiveCollectionLimits: fun(
+      'Get effective collection limits', 
+      [collectionParam], 
+      'Option<UpDataStructsCollectionLimits>',
+    ),
+    totalPieces: fun(
+      'Get the total amount of pieces of an RFT', 
+      [collectionParam, tokenParam], 
+      'Option<u128>',
+    ),
   },
 };