git.delta.rocks / unique-network / refs/commits / 0ad944f65fd2

difftreelog

Merge branch 'develop' into ci-build-workflow-v3

Alexander Aksenov2022-08-04parents: #0643ad5 #19daf00.patch.diff
in: master

13 files changed

added.docker/.envdiffbeforeafterboth
--- /dev/null
+++ b/.docker/.env
@@ -0,0 +1,7 @@
+RUST_TOOLCHAIN=nightly-2022-05-11
+RUST_C=1.62.0-nightly
+POLKA_VERSION=release-v0.9.24
+UNIQUE_BRANCH=develop
+FEATURE='--features=quartz-runtime'
+USER=***
+PASS=***
modified.docker/Dockerfile-parachaindiffbeforeafterboth
--- a/.docker/Dockerfile-parachain
+++ b/.docker/Dockerfile-parachain
@@ -12,7 +12,9 @@
 
 RUN apt-get update && \
     apt-get dist-upgrade -y -o Dpkg::Options::="--force-confold" && \
-    apt-get install -y cmake pkg-config libssl-dev git clang
+    apt-get install -y cmake pkg-config libssl-dev git clang && \
+    apt-get clean && \
+    rm -r /var/lib/apt/lists/*
 
 RUN rustup toolchain uninstall $(rustup toolchain list) && \
     rustup toolchain install $RUST_TOOLCHAIN && \
@@ -27,7 +29,7 @@
 WORKDIR /unique_parachain
 
 # ===== BUILD ======
-FROM rust-builder as builder
+FROM rust-builder as builder-unique
 
 ARG PROFILE=release
 
@@ -56,8 +58,6 @@
 # ===== RUN ======
 
 FROM ubuntu:20.04
-
-ARG PROFILE=release
 
 RUN apt-get -y update && \
       apt-get -y upgrade && \
@@ -68,7 +68,7 @@
       nvm install v16.16.0 && \
       nvm use v16.16.0
 
-RUN git clone https://github.com/uniquenetwork/polkadot-launch -b feature/parachain-forking
+RUN git clone https://github.com/uniquenetwork/polkadot-launch -b feature/runtime-upgrade-testing
 
 RUN export NVM_DIR="$HOME/.nvm" && \
     [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
@@ -76,8 +76,11 @@
     npm install --global yarn && \
     yarn install
 
-COPY --from=builder /unique_parachain/target/$PROFILE/unique-collator /unique-chain/target/$PROFILE/
-COPY --from=builder-polkadot /unique_parachain/polkadot/target/$PROFILE/polkadot /polkadot/target/$PROFILE/
+COPY --from=builder-unique /unique_parachain/target/release/unique-collator /unique-chain/target/release/
+COPY --from=builder-polkadot /unique_parachain/polkadot/target/release/polkadot /polkadot/target/release/
+
+COPY ["./launch-config.json", "/polkadot-launch/launch-config.json"]
+
 
 CMD export NVM_DIR="$HOME/.nvm" && \
     [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
added.docker/Dockerfile-parachain-v2diffbeforeafterboth
--- /dev/null
+++ b/.docker/Dockerfile-parachain-v2
@@ -0,0 +1,97 @@
+# ===== Rust builder =====
+FROM phusion/baseimage:focal-1.1.0 as rust-builder
+LABEL maintainer="Unique.Network"
+
+ARG RUST_TOOLCHAIN={{ actual_toolchain }}
+ARG POLKA_VERSION=release-v0.9.24
+
+
+ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN
+ENV POLKA_VERSION $POLKA_VERSION
+
+ENV CARGO_HOME="/cargo-home"
+ENV PATH="/cargo-home/bin:$PATH"
+
+RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none
+
+RUN apt-get update && \
+    apt-get dist-upgrade -y -o Dpkg::Options::="--force-confold" && \
+    apt-get install -y cmake pkg-config libssl-dev git clang
+
+RUN rustup toolchain uninstall $(rustup toolchain list) && \
+    rustup toolchain install $RUST_TOOLCHAIN && \
+    rustup default $RUST_TOOLCHAIN && \
+    rustup target list --installed && \
+    rustup show
+RUN rustup target add wasm32-unknown-unknown --toolchain $RUST_TOOLCHAIN
+
+####works inside repo folder###
+
+
+# ===== BUILD ======
+FROM rust-builder as builder-unique
+
+RUN mkdir unique_parachain
+WORKDIR /unique_parachain
+
+ARG PROFILE='features=quartz-runtime'
+
+ENV PROFILE $PROFILE
+
+COPY . .
+RUN cargo build --$PROFILE
+   # && \
+   # cargo test
+
+# ===== BUILD POLKADOT =====
+FROM rust-builder as builder-polkadot
+
+RUN mkdir unique_parachain
+WORKDIR /unique_parachain
+
+RUN git clone -b $POLKA_VERSION --depth 1 https://github.com/paritytech/polkadot.git && \
+    cd polkadot && \
+    git tag -n && \
+	cargo build --release
+
+# ===== RUN ======
+
+FROM phusion/baseimage:focal-1.1.0
+
+
+RUN apt-get -y update && \
+      apt-get -y upgrade && \
+      apt-get -y install curl git && \
+      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \
+      export NVM_DIR="$HOME/.nvm" && \
+      [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
+      nvm install v15.5.0 && \
+      nvm use v15.5.0
+
+RUN git clone https://github.com/UniqueNetwork/polkadot-launch.git && \
+    cd ./polkadot-launch && \
+    git checkout feature/runtime-upgrade-testing
+
+RUN export NVM_DIR="$HOME/.nvm" && \
+    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
+    cd /polkadot-launch && \
+    npm install --global yarn && \
+    yarn
+
+COPY --from=builder-unique /unique_parachain/target/release/unique-collator /unique-chain/target/release/
+COPY --from=builder-polkadot /unique_parachain/polkadot/target/release/polkadot /polkadot/target/release/
+
+COPY ["./launch-config.json", "/polkadot-launch/launch-config.json"]
+
+
+EXPOSE 9844
+EXPOSE 9944
+EXPOSE 9933
+EXPOSE 9833
+EXPOSE 40333
+EXPOSE 30333
+
+CMD export NVM_DIR="$HOME/.nvm" && \
+    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
+    cd /polkadot-launch && \
+    yarn start launch-config.json
modified.docker/docker-compose-dev.yamldiffbeforeafterboth
--- a/.docker/docker-compose-dev.yaml
+++ b/.docker/docker-compose-dev.yaml
@@ -3,8 +3,8 @@
 services:
   node-dev:
     build:
-      context: .
-      dockerfile: Dockerfile-chain-dev
+      context: ../
+      dockerfile: .docker/Dockerfile-chain-dev
     image: node-dev
     container_name: node-dev
     expose:
added.docker/docker-compose-tests-parachain.ymldiffbeforeafterboth
--- /dev/null
+++ b/.docker/docker-compose-tests-parachain.yml
@@ -0,0 +1,34 @@
+version: "3.5"
+
+services:
+  blockchain_nodes:
+    build:
+      context: ../
+      dockerfile: .docker/Dockerfile-parachain
+      args:
+        - RUST_TOOLCHAIN=${RUST_TOOLCHAIN:?err}
+        - RUST_C=${RUST_C:?err}
+        - POLKA_VERSION=${POLKA_VERSION:?err}
+        - FEATURE=${FEATURE:?err}
+    volumes:
+      - ../launch-config.json:/polkadot-launch/launch-config.json
+    env_file:
+      - ./.env
+    expose:
+      - 9944
+      - 9933
+    ports:
+      - 127.0.0.1:9944:9944
+      - 127.0.0.1:9933:9933
+
+#  integration_tests:
+#    build:
+#      context: ../tests/
+#      dockerfile: Dockerfile-tests
+#    environment:
+#      RPC_URL: http://blockchain_nodes:9933/
+#    volumes:
+#      - ./tests/src/config_docker.ts:/unique_parachain/src/config.ts
+#      - /home/ubuntu/mochawesome-report:/unique_parachain/mochawesome-report
+#    depends_on:
+#      - blockchain_nodes
added.docker/docker-compose.tmp-master.j2diffbeforeafterboth
--- /dev/null
+++ b/.docker/docker-compose.tmp-master.j2
@@ -0,0 +1,10 @@
+version: "3.5"
+
+services:
+  blockchain_nodes:
+    build:
+      args:
+        - "RUST_TOOLCHAIN={{ RUST_TOOLCHAIN }}"
+        - "BRANCH={{ BRANCH }}"
+        - "REPO_URL={{ REPO_URL }}"
+        - "FEATURE={{ FEATURE }}"
modified.docker/docker-compose.tmp.j2diffbeforeafterboth
--- a/.docker/docker-compose.tmp.j2
+++ b/.docker/docker-compose.tmp.j2
@@ -4,6 +4,7 @@
   node-dev:
     build:
       args:
+<<<<<<< HEAD
         - "RUST_TOOLCHAIN={{ RUST_TOOLCHAIN:?err }}"
         - "BRANCH={{ BRANCH:?err }}"
         - "REPO_URL={{ REPO_URL:?err }}"
@@ -11,3 +12,9 @@
         - "POLKA_VERSION={{ POLKA_VERSION:?err }}"
 
     command: cargo run --release $FEATURE -- --dev -linfo --unsafe-ws-external --rpc-cors=all --unsafe-rpc-external
+=======
+        - "RUST_TOOLCHAIN={{ RUST_TOOLCHAIN }}"
+        - "BRANCH={{ BRANCH }}"
+        - "REPO_URL={{ REPO_URL }}"
+        - "FEATURE={{ FEATURE }}"
+>>>>>>> develop
added.github/workflows/build-test-master.ymldiffbeforeafterboth
--- /dev/null
+++ b/.github/workflows/build-test-master.yml
@@ -0,0 +1,126 @@
+name: Build & Test Master
+
+# Controls when the action will run.
+on:
+ # Triggers the workflow on push or pull request events but only for the master branch
+  #push:
+  #  branches: [ develop ]
+  pull_request:
+    branches:
+      - master
+    types:
+      - opened
+      - edited
+      - reopened
+  # pull_request:
+ #   branches: [ develop ]
+  # Allows you to run this workflow manually from the Actions tab
+  workflow_dispatch:
+
+#Define Workflow variables
+env:
+  ubuntu_version: focal
+  chains_release_dir: /opt/runner/chains_release
+  opal_chain_workdir: ./src_opal_chain
+  quartz_chain_workdir: ./src_quartz_chain
+  unique_chain_workdir: ./src_unique_chain
+  RUST_TOOLCHAIN: nightly-2022-05-11
+  REPO_URL: ${{ github.server_url }}/${{ github.repository }}
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+  pre-requisites:
+    # The type of runner that the job will run on
+    runs-on: self-hosted-ci
+
+    steps:
+      #runs ssh connection
+      - name: Install dependencies
+        run: |
+          sudo apt-get install git curl libssl-dev llvm pkg-config libclang-dev clang make cmake
+          sudo apt autoremove
+          curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none
+          . $HOME/.cargo/env && cargo install --locked --git https://github.com/chevdor/subwasm
+          rustup toolchain install ${{ env.RUST_TOOLCHAIN }}
+          rustup default ${{ env.RUST_TOOLCHAIN }}
+          rustup target add wasm32-unknown-unknown --toolchain ${{ env.RUST_TOOLCHAIN }}
+
+
+  build:
+    # The type of runner that the job will run on
+    runs-on: self-hosted-ci
+
+    needs: pre-requisites
+    name: Build Container, Spin it Up an test
+
+    continue-on-error: true         #Do not stop testing of matrix runs failed.
+
+    strategy:
+      matrix:
+        include:
+          - network: "Opal"
+            features: " "
+          - network: "Quartz"
+            features: "--features=quartz-runtime"
+          - network: "Unique"
+            features: "--features=unique-runtime"
+
+    steps:
+      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+      - uses: actions/checkout@v3
+
+      - name: Generate ENV related extend file for docker-compose
+        uses: cuchi/jinja2-action@v1.2.0
+        with:
+          template: .docker/docker-compose.tmp-master.j2
+          output_file: .docker/docker-compose.${{ matrix.network }}.yml
+          variables: |
+            REPO_URL=${{ github.server_url }}/${{ github.repository }}.git
+            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
+            FEATURE=${{ matrix.features }}
+            BRANCH=${{ github.head_ref }}
+
+      - name: Show temporary file
+        run: cat .docker/docker-compose.${{ matrix.network }}.yml
+
+      - name: Build the stack
+        run: docker-compose -f ".docker/docker-compose-tests-parachain.yml" -f ".docker/docker-compose.${{ matrix.network }}.yml" up -d --build
+
+#      - name: "Build the Docker image with Feature: ${{ env.features }}"
+#        run: docker build -t build-${{ github.head_ref }} --file .docker/Dockerfile-chain-dev --build-arg REPO_URL=${{ github.server_url }}/${{ github.repository }}.git --build-arg RUST_TOOLCHAIN=${{ env.actual_toolchain }} --build-arg FEATURE="${{ env.features }}" --build-arg BRANCH=${{ github.head_ref }} --no-cache .
+
+      - name: Wait
+        run: sleep 420s
+
+      - name: Install node
+        uses: actions/setup-node@v1
+        with:
+          node-version: 14.x
+
+      - name: Install dependencies
+        run: |
+          cd tests
+          yarn install
+          yarn add mochawesome
+          yarn --pure-lockfile
+
+      - name: Run tests
+        run: |
+          cd tests
+          NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-${NOW}
+        env:
+          RPC_URL: http://127.0.0.1:9933/
+
+      - name: Test Report
+        uses: phoenix-actions/test-reporting@v8
+        id: test-report               # Set ID reference for step
+        if: success() || failure()    # run this step even if previous step failed
+        with:
+          name: Tests ${{ matrix.network }}            # Name of the check run which will be created
+          path: tests/mochawesome-report/test-*.json    # Path to test results
+          reporter: mochawesome-json
+          fail-on-error: 'false'
+
+      - name: Stop running containers
+        if: always()                   # run this step always
+        run: docker-compose -f ".docker/docker-compose-tests-parachain.yml" -f ".docker/docker-compose.${{ matrix.network }}.yml" down
modifiedpallets/common/CHANGELOG.mddiffbeforeafterboth
--- a/pallets/common/CHANGELOG.md
+++ b/pallets/common/CHANGELOG.md
@@ -2,11 +2,13 @@
 
 All notable changes to this project will be documented in this file.
 
-## [0.1.1] - 2022-07-14
+## [0.1.3] - 2022-07-25
+### Add
+-   Some static property keys and values.
 
-### Added
+## [0.1.2] - 2022-07-20
 
- - Implementation of RPC method `token_owners` returning 10 owners in no particular order.
-    This was an internal request to improve the web interface and support fractionalization event. 
+### Fixed
 
- 
\ No newline at end of file
+-   Some methods in `#[solidity_interface]` for `CollectionHandle` had invalid
+    mutability modifiers, causing invalid stub/abi generation.
modifiedprimitives/data-structs/src/bounded.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/bounded.rs
+++ b/primitives/data-structs/src/bounded.rs
@@ -1,3 +1,21 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+//! This module contins implementations for support bounded structures ([`BoundedVec`], [`BoundedBTreeMap`], [`BoundedBTreeSet`]) in [`serde`].
+
 use core::fmt;
 use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
 use sp_std::vec::Vec;
@@ -7,7 +25,7 @@
 	storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet},
 };
 
-/// BoundedVec doesn't supports serde
+/// [`serde`] implementations for [`BoundedVec`].
 #[cfg(feature = "serde1")]
 pub mod vec_serde {
 	use core::convert::TryFrom;
@@ -39,6 +57,7 @@
 	}
 }
 
+/// Format [`BoundedVec`] for debug output.
 pub fn vec_debug<V, S>(v: &BoundedVec<V, S>, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
 where
 	V: fmt::Debug,
@@ -49,6 +68,7 @@
 
 #[cfg(feature = "serde1")]
 #[allow(dead_code)]
+/// [`serde`] implementations for [`BoundedBTreeMap`].
 pub mod map_serde {
 	use core::convert::TryFrom;
 	use sp_std::collections::btree_map::BTreeMap;
@@ -84,6 +104,7 @@
 	}
 }
 
+/// Format [`BoundedBTreeMap`] for debug output.
 pub fn map_debug<K, V, S>(
 	v: &BoundedBTreeMap<K, V, S>,
 	f: &mut fmt::Formatter,
@@ -98,6 +119,7 @@
 
 #[cfg(feature = "serde1")]
 #[allow(dead_code)]
+/// [`serde`] implementations for [`BoundedBTreeSet`].
 pub mod set_serde {
 	use core::convert::TryFrom;
 	use sp_std::collections::btree_set::BTreeSet;
@@ -129,6 +151,7 @@
 	}
 }
 
+/// Format [`BoundedBTreeSet`] for debug output.
 pub fn set_debug<K, S>(v: &BoundedBTreeSet<K, S>, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
 where
 	K: fmt::Debug + Ord,
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -14,6 +14,10 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
+//! # Primitives crate.
+//!
+//! This crate contains types, traits and constants.
+
 #![cfg_attr(not(feature = "std"), no_std)]
 
 use core::{
@@ -55,38 +59,55 @@
 pub mod mapping;
 mod migration;
 
+/// Maximum of decimal points.
 pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;
+
+/// Maximum pieces for refungible token.
 pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;
 pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;
 
+/// Maximum tokens for user.
 pub const MAX_TOKEN_OWNERSHIP: u32 = if cfg!(not(feature = "limit-testing")) {
 	100_000
 } else {
 	10
 };
+
+/// Maximum for collections can be created.
 pub const COLLECTION_NUMBER_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
 	100_000
 } else {
 	10
 };
+
+/// Maximum for various custom data of token.
 pub const CUSTOM_DATA_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
 	2048
 } else {
 	10
 };
+
+/// Maximum admins per collection.
 pub const COLLECTION_ADMINS_LIMIT: u32 = 5;
+
+/// Maximum tokens per collection.
 pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;
+
+/// Maximum tokens per account.
 pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
 	1_000_000
 } else {
 	10
 };
 
-// Timeouts for item types in passed blocks
+/// Default timeout for transfer sponsoring NFT item.
 pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+/// Default timeout for transfer sponsoring fungible item.
 pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+/// Default timeout for transfer sponsoring refungible item.
 pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
 
+/// Default timeout for sponsored approving.
 pub const SPONSOR_APPROVE_TIMEOUT: u32 = 5;
 
 // Schema limits
@@ -94,27 +115,44 @@
 pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 8192;
 pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 32768;
 
+// TODO: not used. Delete?
 pub const COLLECTION_FIELD_LIMIT: u32 = CONST_ON_CHAIN_SCHEMA_LIMIT;
 
+/// Maximum length for collection name.
 pub const MAX_COLLECTION_NAME_LENGTH: u32 = 64;
+
+/// Maximum length for collection description.
 pub const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = 256;
+
+/// Maximal token prefix length.
 pub const MAX_TOKEN_PREFIX_LENGTH: u32 = 16;
 
+/// Maximal lenght of property key.
 pub const MAX_PROPERTY_KEY_LENGTH: u32 = 256;
+
+/// Maximal lenght of property value.
 pub const MAX_PROPERTY_VALUE_LENGTH: u32 = 32768;
+
+/// Maximum properties that can be assigned to token.
 pub const MAX_PROPERTIES_PER_ITEM: u32 = 64;
 
+/// Maximal lenght of extended property value.
 pub const MAX_AUX_PROPERTY_VALUE_LENGTH: u32 = 2048;
 
+/// Maximum size for all collection properties.
 pub const MAX_COLLECTION_PROPERTIES_SIZE: u32 = 40960;
+
+/// Maximum size for all token properties.
 pub const MAX_TOKEN_PROPERTIES_SIZE: u32 = 32768;
 
 /// How much items can be created per single
-/// create_many call
+/// create_many call.
 pub const MAX_ITEMS_PER_BATCH: u32 = 200;
 
+/// Used for limit bounded types of token custom data.
 pub type CustomDataLimit = ConstU32<CUSTOM_DATA_LIMIT>;
 
+/// Collection id.
 #[derive(
 	Encode,
 	Decode,
@@ -134,6 +172,7 @@
 impl EncodeLike<u32> for CollectionId {}
 impl EncodeLike<CollectionId> for u32 {}
 
+/// Token id.
 #[derive(
 	Encode,
 	Decode,
@@ -154,6 +193,9 @@
 impl EncodeLike<TokenId> for u32 {}
 
 impl TokenId {
+	/// Try to get next token id.
+	///
+	/// If next id cause overflow, then [`ArithmeticError::Overflow`] returned.
 	pub fn try_next(self) -> Result<TokenId, ArithmeticError> {
 		self.0
 			.checked_add(1)
@@ -176,14 +218,21 @@
 	}
 }
 
+/// Token data.
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct TokenData<CrossAccountId> {
+	/// Properties of token.
 	pub properties: Vec<Property>,
+
+	/// Token owner.
 	pub owner: Option<CrossAccountId>,
+
+	/// Token pieces.
 	pub pieces: u128,
 }
 
+// TODO: unused type
 pub struct OverflowError;
 impl From<OverflowError> for &'static str {
 	fn from(_: OverflowError) -> Self {
@@ -191,17 +240,27 @@
 	}
 }
 
+/// Alias for decimal points type.
 pub type DecimalPoints = u8;
 
+/// Collection mode.
+///
+/// Collection can represent various types of tokens.
+/// Each collection can contain only one type of tokens at a time.
+/// This type helps to understand which tokens the collection contains.
 #[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CollectionMode {
+	/// Non fungible tokens.
 	NFT,
+	/// Fungible tokens.
 	Fungible(DecimalPoints),
+	/// Refungible tokens.
 	ReFungible,
 }
 
 impl CollectionMode {
+	/// Get collection mod as number.
 	pub fn id(&self) -> u8 {
 		match self {
 			CollectionMode::NFT => 1,
@@ -211,14 +270,18 @@
 	}
 }
 
+// TODO: unused trait
 pub trait SponsoringResolve<AccountId, Call> {
 	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;
 }
 
+/// Access mode for some token operations.
 #[derive(Encode, Decode, Eq, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
 	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
 	AllowList,
 }
 impl Default for AccessMode {
@@ -227,6 +290,7 @@
 	}
 }
 
+// TODO: remove in future.
 #[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum SchemaVersion {
@@ -239,6 +303,7 @@
 	}
 }
 
+// TODO: unused type
 #[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct Ownership<AccountId> {
@@ -246,19 +311,21 @@
 	pub fraction: u128,
 }
 
+/// The state of collection sponsorship.
 #[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum SponsorshipState<AccountId> {
-	/// The fees are applied to the transaction sender
+	/// The fees are applied to the transaction sender.
 	Disabled,
-	/// Pending confirmation from a sponsor-to-be
+	/// The sponsor is under consideration. Until the sponsor gives his consent,
+	/// the fee will still be charged to sender.
 	Unconfirmed(AccountId),
-	/// Transactions are sponsored by specified account
+	/// Transactions are sponsored by specified account.
 	Confirmed(AccountId),
 }
 
 impl<AccountId> SponsorshipState<AccountId> {
-	/// Get the acting sponsor account, if present
+	/// Get a sponsor of the collection who has confirmed his status.
 	pub fn sponsor(&self) -> Option<&AccountId> {
 		match self {
 			Self::Confirmed(sponsor) => Some(sponsor),
@@ -266,7 +333,7 @@
 		}
 	}
 
-	/// Get the sponsor account currently pending confirmation, if present
+	/// Get a sponsor of the collection who has pending or confirmed status.
 	pub fn pending_sponsor(&self) -> Option<&AccountId> {
 		match self {
 			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),
@@ -274,7 +341,7 @@
 		}
 	}
 
-	/// Is sponsorship set and acting
+	/// Whether the sponsorship is confirmed.
 	pub fn confirmed(&self) -> bool {
 		matches!(self, Self::Confirmed(_))
 	}
@@ -290,16 +357,32 @@
 pub type CollectionDescription = BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>;
 pub type CollectionTokenPrefix = BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>;
 
+/// Base structure for represent collection.
+///
+/// Used to provide basic functionality for all types of collections.
+///
+/// #### Note
 /// 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> {
+	/// Collection owner account.
 	pub owner: AccountId,
+
+	/// Collection mode.
 	pub mode: CollectionMode,
+
+	/// Access mode.
 	#[version(..2)]
 	pub access: AccessMode,
+
+	/// Collection name.
 	pub name: CollectionName,
+
+	/// Collection description.
 	pub description: CollectionDescription,
+
+	/// Token prefix.
 	pub token_prefix: CollectionTokenPrefix,
 
 	#[version(..2)]
@@ -310,10 +393,14 @@
 
 	#[version(..2)]
 	pub schema_version: SchemaVersion,
+
+	/// The state of sponsorship of the collection.
 	pub sponsorship: SponsorshipState<AccountId>,
 
+	/// Collection limits.
 	pub limits: CollectionLimits,
 
+	/// Collection permissions.
 	#[version(2.., upper(Default::default()))]
 	pub permissions: CollectionPermissions,
 
@@ -335,116 +422,215 @@
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct RpcCollection<AccountId> {
+	/// Collection owner account.
 	pub owner: AccountId,
+
+	/// Collection mode.
 	pub mode: CollectionMode,
+
+	/// Collection name.
 	pub name: Vec<u16>,
+
+	/// Collection description.
 	pub description: Vec<u16>,
+
+	/// Token prefix.
 	pub token_prefix: Vec<u8>,
+
+	/// The state of sponsorship of the collection.
 	pub sponsorship: SponsorshipState<AccountId>,
+
+	/// Collection limits.
 	pub limits: CollectionLimits,
+
+	/// Collection permissions.
 	pub permissions: CollectionPermissions,
+
+	/// Token property permissions.
 	pub token_property_permissions: Vec<PropertyKeyPermission>,
+
+	/// Collection properties.
 	pub properties: Vec<Property>,
+
+	/// Is collection read only.
 	pub read_only: bool,
 }
 
+/// Data used for create collection.
+///
+/// All fields are wrapped in [`Option`], where `None` means chain default.
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Derivative, MaxEncodedLen)]
 #[derivative(Debug, Default(bound = ""))]
 pub struct CreateCollectionData<AccountId> {
+	/// Collection mode.
 	#[derivative(Default(value = "CollectionMode::NFT"))]
 	pub mode: CollectionMode,
+
+	/// Access mode.
 	pub access: Option<AccessMode>,
+
+	/// Collection name.
 	pub name: CollectionName,
+
+	/// Collection description.
 	pub description: CollectionDescription,
+
+	/// Token prefix.
 	pub token_prefix: CollectionTokenPrefix,
+
+	/// Pending collection sponsor.
 	pub pending_sponsor: Option<AccountId>,
+
+	/// Collection limits.
 	pub limits: Option<CollectionLimits>,
+
+	/// Collection permissions.
 	pub permissions: Option<CollectionPermissions>,
+
+	/// Token property permissions.
 	pub token_property_permissions: CollectionPropertiesPermissionsVec,
+
+	/// Collection properties.
 	pub properties: CollectionPropertiesVec,
 }
 
+/// Bounded vector of properties permissions. Max length is [`MAX_PROPERTIES_PER_ITEM`].
+// TODO: maybe rename to PropertiesPermissionsVec
 pub type CollectionPropertiesPermissionsVec =
 	BoundedVec<PropertyKeyPermission, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
 
+/// Bounded vector of properties. Max length is [`MAX_PROPERTIES_PER_ITEM`].
 pub type CollectionPropertiesVec = BoundedVec<Property, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
 
 /// Limits and restrictions of a collection.
-/// All fields are wrapped in `Option`s, where None means chain default.
 ///
-/// todo:doc links to chain defaults
+/// All fields are wrapped in [`Option`], where `None` means chain default.
+///
+/// Update with `pallet_common::Pallet::clamp_limits`.
 // 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))]
+// When adding/removing fields from this struct - don't forget to also update with `pallet_common::Pallet::clamp_limits`.
+// TODO: move `pallet_common::Pallet::clamp_limits` into `impl CollectionLimits`.
+// TODO: may be remove [`Option`] and **pub** from fields and create struct with default values.
 pub struct CollectionLimits {
-	/// Maximum number of owned tokens per account. Chain default: [`ACCOUNT_TOKEN_OWNERSHIP_LIMIT`]
+	/// How many tokens can a user have on one account.
+	/// * Default - [`ACCOUNT_TOKEN_OWNERSHIP_LIMIT`].
+	/// * Limit - [`MAX_TOKEN_OWNERSHIP`].
 	pub account_token_ownership_limit: Option<u32>,
-	/// Maximum size of data in bytes of a sponsored transaction. Chain default: [`CUSTOM_DATA_LIMIT`]
+
+	/// How many bytes of data are available for sponsorship.
+	/// * Default - [`CUSTOM_DATA_LIMIT`].
+	/// * Limit - [`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
+	// FIXME should we delete this or repurpose it?
+	/// Times in how many blocks we sponsor data.
+	///
+	/// If is `Some(v)` then **setVariableMetadata** is sponsored if there is `v` block between transactions.
+	///
+	/// * Default - [`SponsoringDisabled`](SponsoringRateLimit::SponsoringDisabled).
+	/// * Limit - [`MAX_SPONSOR_TIMEOUT`].
 	///
 	/// 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`]
+
+	/// How many tokens can be mined into this collection.
+	///
+	/// * Default - [`COLLECTION_TOKEN_LIMIT`].
+	/// * Limit - [`COLLECTION_TOKEN_LIMIT`].
 	pub token_limit: Option<u32>,
 
-	/// 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.
+	/// Timeouts for transfer sponsoring.
+	///
+	/// * Default
+	///   - **Fungible** - [`FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`]
+	///   - **NFT** - [`NFT_SPONSOR_TRANSFER_TIMEOUT`]
+	///   - **Refungible** - [`REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`]
+	/// * Limit - [`MAX_SPONSOR_TIMEOUT`].
 	pub sponsor_transfer_timeout: Option<u32>,
-	/// Timeout for sponsoring an approval in passed blocks. Chain default: [`SPONSOR_APPROVE_TIMEOUT`]
+
+	/// Timeout for sponsoring an approval in passed blocks.
+	///
+	/// * Default - [`SPONSOR_APPROVE_TIMEOUT`].
+	/// * Limit - [`MAX_SPONSOR_TIMEOUT`].
 	pub sponsor_approve_timeout: Option<u32>,
-	/// Can a token be transferred by the owner. Chain default: `false`
+
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
+	///
+	/// * Default - **false**.
 	pub owner_can_transfer: Option<bool>,
-	/// Can a token be burned by the owner. Chain default: `true`
+
+	/// Can the collection owner burn other people's tokens.
+	///
+	/// * Default - **true**.
 	pub owner_can_destroy: Option<bool>,
-	/// Can a token be transferred at all. Chain default: `true`
+
+	/// Is it possible to send tokens from this collection between users.
+	///
+	/// * Default - **true**.
 	pub transfers_enabled: Option<bool>,
 }
 
 impl CollectionLimits {
+	/// Get effective value for [`account_token_ownership_limit`](self.account_token_ownership_limit).
 	pub fn account_token_ownership_limit(&self) -> u32 {
 		self.account_token_ownership_limit
 			.unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)
 			.min(MAX_TOKEN_OWNERSHIP)
 	}
+
+	/// Get effective value for [`sponsored_data_size`](self.sponsored_data_size).
 	pub fn sponsored_data_size(&self) -> u32 {
 		self.sponsored_data_size
 			.unwrap_or(CUSTOM_DATA_LIMIT)
 			.min(CUSTOM_DATA_LIMIT)
 	}
+
+	/// Get effective value for [`token_limit`](self.token_limit).
 	pub fn token_limit(&self) -> u32 {
 		self.token_limit
 			.unwrap_or(COLLECTION_TOKEN_LIMIT)
 			.min(COLLECTION_TOKEN_LIMIT)
 	}
+
+	// TODO: may be replace u32 to mode?
+	/// Get effective value for [`sponsor_transfer_timeout`](self.sponsor_transfer_timeout).
 	pub fn sponsor_transfer_timeout(&self, default: u32) -> u32 {
 		self.sponsor_transfer_timeout
 			.unwrap_or(default)
 			.min(MAX_SPONSOR_TIMEOUT)
 	}
+
+	/// Get effective value for [`sponsor_approve_timeout`](self.sponsor_approve_timeout).
 	pub fn sponsor_approve_timeout(&self) -> u32 {
 		self.sponsor_approve_timeout
 			.unwrap_or(SPONSOR_APPROVE_TIMEOUT)
 			.min(MAX_SPONSOR_TIMEOUT)
 	}
+
+	/// Get effective value for [`owner_can_transfer`](self.owner_can_transfer).
 	pub fn owner_can_transfer(&self) -> bool {
 		self.owner_can_transfer.unwrap_or(false)
 	}
+
+	/// Get effective value for [`owner_can_transfer_instaled`](self.owner_can_transfer_instaled).
 	pub fn owner_can_transfer_instaled(&self) -> bool {
 		self.owner_can_transfer.is_some()
 	}
+
+	/// Get effective value for [`owner_can_destroy`](self.owner_can_destroy).
 	pub fn owner_can_destroy(&self) -> bool {
 		self.owner_can_destroy.unwrap_or(true)
 	}
+
+	/// Get effective value for [`transfers_enabled`](self.transfers_enabled).
 	pub fn transfers_enabled(&self) -> bool {
 		self.transfers_enabled.unwrap_or(true)
 	}
+
+	/// Get effective value for [`sponsored_data_rate_limit`](self.sponsored_data_rate_limit).
 	pub fn sponsored_data_rate_limit(&self) -> Option<u32> {
 		match self
 			.sponsored_data_rate_limit
@@ -457,24 +643,46 @@
 }
 
 /// 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.
+///
+/// Some fields are wrapped in [`Option`], where `None` means chain default.
+///
+/// Update with `pallet_common::Pallet::clamp_permissions`.
 #[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+// When adding/removing fields from this struct - don't forget to also update `pallet_common::Pallet::clamp_permissions`.
+// TODO: move `pallet_common::Pallet::clamp_permissions` into `impl CollectionPermissions`.
 pub struct CollectionPermissions {
+	/// Access mode.
+	///
+	/// * Default - [`AccessMode::Normal`].
 	pub access: Option<AccessMode>,
+
+	/// Minting allowance.
+	///
+	/// * Default - **false**.
 	pub mint_mode: Option<bool>,
+
+	/// Permissions for nesting.
+	///
+	/// * Default
+	///   - `token_owner` - **false**
+	///   - `collection_admin` - **false**
+	///   - `restricted` - **None**
 	pub nesting: Option<NestingPermissions>,
 }
 
 impl CollectionPermissions {
+	/// Get effective value for [`access`](self.access).
 	pub fn access(&self) -> AccessMode {
 		self.access.unwrap_or(AccessMode::Normal)
 	}
+
+	/// Get effective value for [`mint_mode`](self.mint_mode).
 	pub fn mint_mode(&self) -> bool {
 		self.mint_mode.unwrap_or(false)
 	}
+
+	/// Get effective value for [`nesting`](self.nesting).
 	pub fn nesting(&self) -> &NestingPermissions {
 		static DEFAULT: NestingPermissions = NestingPermissions {
 			token_owner: false,
@@ -487,8 +695,10 @@
 	}
 }
 
+/// Inner set for collections allowed to nest.
 type OwnerRestrictedSetInner = BoundedBTreeSet<CollectionId, ConstU32<16>>;
 
+/// Wraper for collections set allowing nest.
 #[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
@@ -497,7 +707,9 @@
 	#[derivative(Debug(format_with = "bounded::set_debug"))]
 	pub OwnerRestrictedSetInner,
 );
+
 impl OwnerRestrictedSet {
+	/// Create new set.
 	pub fn new() -> Self {
 		Self(Default::default())
 	}
@@ -519,19 +731,21 @@
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 #[derivative(Debug)]
 pub struct NestingPermissions {
-	/// Owner of token can nest tokens under it
+	/// Owner of token can nest tokens under it.
 	pub token_owner: bool,
-	/// Admin of token collection can nest tokens under token
+	/// Admin of token collection can nest tokens under token.
 	pub collection_admin: bool,
-	/// If set - only tokens from specified collections can be nested
+	/// If set - only tokens from specified collections can be nested.
 	pub restricted: Option<OwnerRestrictedSet>,
 
 	#[cfg(feature = "runtime-benchmarks")]
-	/// Anyone can nest tokens, mutually exclusive with `token_owner`, `admin`
+	/// Anyone can nest tokens, mutually exclusive with `token_owner`, `admin`.
 	pub permissive: bool,
 }
 
 /// Enum denominating how often can sponsoring occur if it is enabled.
+///
+/// Used for [`collection limits`](CollectionLimits).
 #[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum SponsoringRateLimit {
@@ -549,6 +763,7 @@
 	/// 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"))]
+	/// Properties that wil be assignet to created item.
 	pub properties: CollectionPropertiesVec,
 }
 
@@ -570,7 +785,7 @@
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
 
-	/// Number of pieces the RFT is split into
+	/// Pieces of created token.
 	pub pieces: u128,
 
 	/// Key-value pairs used to describe the token as metadata
@@ -579,6 +794,7 @@
 	pub properties: CollectionPropertiesVec,
 }
 
+// TODO: remove this.
 #[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum MetaUpdatePermission {
@@ -588,57 +804,75 @@
 }
 
 /// Enum holding data used for creation of all three item types.
+/// Unified data for create item.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CreateItemData {
+	/// Data for create NFT.
 	NFT(CreateNftData),
+	/// Data for create Fungible item.
 	Fungible(CreateFungibleData),
+	/// Data for create ReFungible item.
 	ReFungible(CreateReFungibleData),
 }
 
-/// Explicit NFT creation data with meta parameters.
+/// Extended data for create NFT.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
 #[derivative(Debug)]
 pub struct CreateNftExData<CrossAccountId> {
+	/// Properties that wil be assignet to created item.
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub properties: CollectionPropertiesVec,
+
+	/// Owner of creating item.
 	pub owner: CrossAccountId,
 }
 
-/// Explicit RFT creation data with meta parameters.
+/// Extended data for create ReFungible item.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
 #[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
 pub struct CreateRefungibleExData<CrossAccountId> {
+	/// Custom data stored in token.
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
+
+	/// Users who will be assigned the specified number of token parts.
 	#[derivative(Debug(format_with = "bounded::map_debug"))]
 	pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub properties: CollectionPropertiesVec,
 }
 
-/// Explicit item creation data with meta parameters, namely the owner.
+/// Unified extended data for creating item.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
 #[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
 pub enum CreateItemExData<CrossAccountId> {
+	/// Extended data for create NFT.
 	NFT(
 		#[derivative(Debug(format_with = "bounded::vec_debug"))]
 		BoundedVec<CreateNftExData<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,
 	),
+
+	/// Extended data for create Fungible item.
 	Fungible(
 		#[derivative(Debug(format_with = "bounded::map_debug"))]
 		BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
 	),
-	/// Many tokens, each may have only one owner
+
+	/// Extended data for create ReFungible item in case of
+	/// many tokens, each may have only one owner
 	RefungibleMultipleItems(
 		#[derivative(Debug(format_with = "bounded::vec_debug"))]
 		BoundedVec<CreateRefungibleExData<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,
 	),
-	/// Single token, which may have many owners
+
+	/// Extended data for create ReFungible item in case of
+	/// single token, which may have many owners
 	RefungibleMultipleOwners(CreateRefungibleExData<CrossAccountId>),
 }
 
 impl CreateItemData {
+	/// Get size of custom data.
 	pub fn data_size(&self) -> usize {
 		match self {
 			CreateItemData::ReFungible(data) => data.const_data.len(),
@@ -670,18 +904,28 @@
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 // todo possibly rename to be used generally as an address pair
 pub struct TokenChild {
+	/// Token id.
 	pub token: TokenId,
+
+	/// Collection id.
 	pub collection: CollectionId,
 }
 
+/// Collection statistics.
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct CollectionStats {
+	/// Number of created items.
 	pub created: u32,
+
+	/// Number of burned items.
 	pub destroyed: u32,
+
+	/// Number of current items.
 	pub alive: u32,
 }
 
+/// This type works like [`PhantomData`] but supports generating _scale-info_ descriptions to generate node metadata.
 #[derive(Encode, Decode, Clone, Debug)]
 #[cfg_attr(feature = "std", derive(PartialEq))]
 pub struct PhantomType<T>(core::marker::PhantomData<T>);
@@ -707,22 +951,36 @@
 	}
 }
 
+/// Bounded vector of bytes.
 pub type BoundedBytes<S> = BoundedVec<u8, S>;
 
+/// Extra properties for external collections.
 pub type AuxPropertyValue = BoundedBytes<ConstU32<MAX_AUX_PROPERTY_VALUE_LENGTH>>;
 
+/// Property key.
 pub type PropertyKey = BoundedBytes<ConstU32<MAX_PROPERTY_KEY_LENGTH>>;
+
+/// Property value.
 pub type PropertyValue = BoundedBytes<ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;
 
+/// Property permission.
 #[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct PropertyPermission {
+	/// Permission to change the property and property permission.
+	///
+	/// If it **false** then you can not change corresponding property even if [`collection_admin`] and [`token_owner`] are **true**.
 	pub mutable: bool,
+
+	/// Change permission for the collection administrator.
 	pub collection_admin: bool,
+
+	/// Permission to change the property for the owner of the token.
 	pub token_owner: bool,
 }
 
 impl PropertyPermission {
+	/// Creates mutable property permission but changes restricted for collection admin and token owner.
 	pub fn none() -> Self {
 		Self {
 			mutable: true,
@@ -732,12 +990,15 @@
 	}
 }
 
+/// Property is simpl key-value record.
 #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct Property {
+	/// Property key.
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	pub key: PropertyKey,
 
+	/// Property value.
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	pub value: PropertyValue,
 }
@@ -748,12 +1009,15 @@
 	}
 }
 
+/// Record for proprty key permission.
 #[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct PropertyKeyPermission {
+	/// Key.
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	pub key: PropertyKey,
 
+	/// Permission.
 	pub permission: PropertyPermission,
 }
 
@@ -763,15 +1027,35 @@
 	}
 }
 
+/// Errors for properties actions.
 #[derive(Debug)]
 pub enum PropertiesError {
+	/// The space allocated for properties has run out.
+	///
+	/// * Limit for colection - [`MAX_COLLECTION_PROPERTIES_SIZE`].
+	/// * Limit for token - [`MAX_TOKEN_PROPERTIES_SIZE`].
 	NoSpaceForProperty,
+
+	/// The property limit has been reached.
+	///
+	/// * Limit - [`MAX_PROPERTIES_PER_ITEM`].
 	PropertyLimitReached,
+
+	/// Property key contains not allowed character.
 	InvalidCharacterInPropertyKey,
+
+	/// Property key length is too long.
+	///
+	/// * Limit - [`MAX_PROPERTY_KEY_LENGTH`].
 	PropertyKeyIsTooLong,
+
+	/// Property key is empty.
 	EmptyPropertyKey,
 }
 
+/// Marker for scope of property.
+///
+/// Scoped property can't be changed by user. Used for external collections.
 #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Clone, Copy)]
 pub enum PropertyScope {
 	None,
@@ -779,6 +1063,7 @@
 }
 
 impl PropertyScope {
+	/// Apply scope to property key.
 	pub fn apply(self, key: PropertyKey) -> Result<PropertyKey, PropertiesError> {
 		let scope_str: &[u8] = match self {
 			Self::None => return Ok(key),
@@ -792,9 +1077,11 @@
 	}
 }
 
+/// Trait for operate with properties.
 pub trait TrySetProperty: Sized {
 	type Value;
 
+	/// Try to set property with scope.
 	fn try_scoped_set(
 		&mut self,
 		scope: PropertyScope,
@@ -802,6 +1089,7 @@
 		value: Self::Value,
 	) -> Result<(), PropertiesError>;
 
+	/// Try to set property with scope from iterator.
 	fn try_scoped_set_from_iter<I, KV>(
 		&mut self,
 		scope: PropertyScope,
@@ -819,10 +1107,12 @@
 		Ok(())
 	}
 
+	/// Try to set property.
 	fn try_set(&mut self, key: PropertyKey, value: Self::Value) -> Result<(), PropertiesError> {
 		self.try_scoped_set(PropertyScope::None, key, value)
 	}
 
+	/// Try to set property from iterator.
 	fn try_set_from_iter<I, KV>(&mut self, iter: I) -> Result<(), PropertiesError>
 	where
 		I: Iterator<Item = KV>,
@@ -832,6 +1122,7 @@
 	}
 }
 
+/// Wrapped map for storing properties.
 #[derive(Encode, Decode, TypeInfo, Derivative, Clone, PartialEq, MaxEncodedLen)]
 #[derivative(Default(bound = ""))]
 pub struct PropertiesMap<Value>(
@@ -839,24 +1130,29 @@
 );
 
 impl<Value> PropertiesMap<Value> {
+	/// Create new property map.
 	pub fn new() -> Self {
 		Self(BoundedBTreeMap::new())
 	}
 
+	/// Remove property from map.
 	pub fn remove(&mut self, key: &PropertyKey) -> Result<Option<Value>, PropertiesError> {
 		Self::check_property_key(key)?;
 
 		Ok(self.0.remove(key))
 	}
 
+	/// Get property with appropriate key from map.
 	pub fn get(&self, key: &PropertyKey) -> Option<&Value> {
 		self.0.get(key)
 	}
 
+	/// Check if map contains key.
 	pub fn contains_key(&self, key: &PropertyKey) -> bool {
 		self.0.contains_key(key)
 	}
 
+	/// Check if map contains key with key validation.
 	fn check_property_key(key: &PropertyKey) -> Result<(), PropertiesError> {
 		if key.is_empty() {
 			return Err(PropertiesError::EmptyPropertyKey);
@@ -909,8 +1205,10 @@
 	}
 }
 
+/// Alias for property permissions map.
 pub type PropertiesPermissionMap = PropertiesMap<PropertyPermission>;
 
+/// Wrapper for properties map with consumed space control.
 #[derive(Encode, Decode, TypeInfo, Clone, PartialEq, MaxEncodedLen)]
 pub struct Properties {
 	map: PropertiesMap<PropertyValue>,
@@ -919,6 +1217,7 @@
 }
 
 impl Properties {
+	/// Create new properies container.
 	pub fn new(space_limit: u32) -> Self {
 		Self {
 			map: PropertiesMap::new(),
@@ -927,6 +1226,7 @@
 		}
 	}
 
+	/// Remove propery with appropiate key.
 	pub fn remove(&mut self, key: &PropertyKey) -> Result<Option<PropertyValue>, PropertiesError> {
 		let value = self.map.remove(key)?;
 
@@ -938,6 +1238,7 @@
 		Ok(value)
 	}
 
+	/// Get property with appropriate key.
 	pub fn get(&self, key: &PropertyKey) -> Option<&PropertyValue> {
 		self.map.get(key)
 	}
@@ -977,6 +1278,7 @@
 	}
 }
 
+/// Utility struct for using in `StorageMap`.
 pub struct CollectionProperties;
 
 impl Get<Properties> for CollectionProperties {
@@ -985,6 +1287,7 @@
 	}
 }
 
+/// Utility struct for using in `StorageMap`.
 pub struct TokenProperties;
 
 impl Get<Properties> for TokenProperties {
modifiedprimitives/data-structs/src/mapping.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/mapping.rs
+++ b/primitives/data-structs/src/mapping.rs
@@ -1,3 +1,21 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+//! This module contains mapping between different addresses.
+
 use core::marker::PhantomData;
 
 use sp_core::H160;
@@ -5,12 +23,19 @@
 use crate::{CollectionId, TokenId};
 use pallet_evm::account::CrossAccountId;
 
+/// Trait for mapping between token id and some `Address`.
 pub trait TokenAddressMapping<Address> {
+	/// Map token id to `Address`.
 	fn token_to_address(collection: CollectionId, token: TokenId) -> Address;
+
+	/// Map `Address` to token id.
 	fn address_to_token(address: &Address) -> Option<(CollectionId, TokenId)>;
+
+	/// Check is address for token.
 	fn is_token_address(address: &Address) -> bool;
 }
 
+/// Unit struct for mapping token id to/from *Evm address* represented by [`H160`].
 pub struct EvmTokenAddressMapping;
 
 /// 0xf8238ccfff8ed887463fd5e00000000100000002  - collection 1, token 2
@@ -46,6 +71,7 @@
 	}
 }
 
+/// Unit struct for mapping token id to/from [`CrossAccountId`].
 pub struct CrossTokenAddressMapping<A>(PhantomData<A>);
 
 impl<A, C: CrossAccountId<A>> TokenAddressMapping<C> for CrossTokenAddressMapping<A> {
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
2828
29sp_api::decl_runtime_apis! {29sp_api::decl_runtime_apis! {
30 #[api_version(2)]30 #[api_version(2)]
31 /// Trait for generate rpc.
31 pub trait UniqueApi<CrossAccountId, AccountId> where32 pub trait UniqueApi<CrossAccountId, AccountId> where
32 AccountId: Decode,33 AccountId: Decode,
33 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,34 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,
34 {35 {
35 #[changed_in(2)]36 #[changed_in(2)]
36 fn token_owner(collection: CollectionId, token: TokenId) -> Result<CrossAccountId>;37 fn token_owner(collection: CollectionId, token: TokenId) -> Result<CrossAccountId>;
3738
39 /// Get number of tokens in collection owned by account.
38 fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>>;40 fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>>;
41
42 /// Number of existing tokens in collection.
39 fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>>;43 fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>>;
44
45 /// Check token exist.
40 fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool>;46 fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool>;
4147
48 /// Get token owner.
42 fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;49 fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;
50
51 /// Get real owner of nested token.
43 fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;52 fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;
53
54 /// Get nested tokens for the specified item.
44 fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>>;55 fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>>;
4556
57 /// Get collection properties.
46 fn collection_properties(collection: CollectionId, properties: Option<Vec<Vec<u8>>>) -> Result<Vec<Property>>;58 fn collection_properties(collection: CollectionId, properties: Option<Vec<Vec<u8>>>) -> Result<Vec<Property>>;
4759
60 /// Get token properties.
48 fn token_properties(61 fn token_properties(
49 collection: CollectionId,62 collection: CollectionId,
50 token_id: TokenId,63 token_id: TokenId,
51 properties: Option<Vec<Vec<u8>>>64 properties: Option<Vec<Vec<u8>>>
52 ) -> Result<Vec<Property>>;65 ) -> Result<Vec<Property>>;
5366
67 /// Get permissions for token properties.
54 fn property_permissions(68 fn property_permissions(
55 collection: CollectionId,69 collection: CollectionId,
56 properties: Option<Vec<Vec<u8>>>70 properties: Option<Vec<Vec<u8>>>
57 ) -> Result<Vec<PropertyKeyPermission>>;71 ) -> Result<Vec<PropertyKeyPermission>>;
5872
73 /// Get token data.
59 fn token_data(74 fn token_data(
60 collection: CollectionId,75 collection: CollectionId,
61 token_id: TokenId,76 token_id: TokenId,
62 keys: Option<Vec<Vec<u8>>>77 keys: Option<Vec<Vec<u8>>>
63 ) -> Result<TokenData<CrossAccountId>>;78 ) -> Result<TokenData<CrossAccountId>>;
6479
80 /// Total number of tokens in collection.
65 fn total_supply(collection: CollectionId) -> Result<u32>;81 fn total_supply(collection: CollectionId) -> Result<u32>;
82
83 /// Get account balance for collection (sum of tokens pieces).
66 fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;84 fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;
85
86 /// Get account balance for specified token.
67 fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128>;87 fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128>;
88
89 /// Amount of token pieces allowed to spend from granded account.
68 fn allowance(90 fn allowance(
69 collection: CollectionId,91 collection: CollectionId,
70 sender: CrossAccountId,92 sender: CrossAccountId,
71 spender: CrossAccountId,93 spender: CrossAccountId,
72 token: TokenId,94 token: TokenId,
73 ) -> Result<u128>;95 ) -> Result<u128>;
7496
97 /// Get list of collection admins.
75 fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;98 fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;
99
100 /// Get list of users that allowet to mint tikens in collection.
76 fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;101 fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;
102
103 /// Check that user is in allowed list (see [`allowlist`]).
77 fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool>;104 fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool>;
105
106 /// Last minted token id.
78 fn last_token_id(collection: CollectionId) -> Result<TokenId>;107 fn last_token_id(collection: CollectionId) -> Result<TokenId>;
108
109 /// Get collection by id.
79 fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>>;110 fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>>;
111
112 /// Get collection stats.
80 fn collection_stats() -> Result<CollectionStats>;113 fn collection_stats() -> Result<CollectionStats>;
114
115 /// Get the number of blocks through which sponsorship will be available.
81 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>>;116 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>>;
117
118 /// Get effective colletion limits.
82 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;119 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;
120
121 /// Get total pieces of token.
83 fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;122 fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;
84 fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;123 fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;
85 }124 }