git.delta.rocks / unique-network / refs/commits / 081dbb6ae4fb

difftreelog

feat Separate rpc calls to own group

Trubnikov Sergey2022-09-01parent: #33ed679.patch.diff
in: master

31 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -113,6 +113,20 @@
 checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8"
 
 [[package]]
+name = "app-promotion-rpc"
+version = "0.1.0"
+dependencies = [
+ "pallet-common",
+ "pallet-evm",
+ "parity-scale-codec 3.1.5",
+ "sp-api",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+ "up-data-structs",
+]
+
+[[package]]
 name = "approx"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5127,6 +5141,7 @@
 name = "opal-runtime"
 version = "0.9.27"
 dependencies = [
+ "app-promotion-rpc",
  "cumulus-pallet-aura-ext",
  "cumulus-pallet-dmp-queue",
  "cumulus-pallet-parachain-system",
@@ -8358,6 +8373,7 @@
 name = "quartz-runtime"
 version = "0.9.27"
 dependencies = [
+ "app-promotion-rpc",
  "cumulus-pallet-aura-ext",
  "cumulus-pallet-dmp-queue",
  "cumulus-pallet-parachain-system",
@@ -8381,6 +8397,7 @@
  "hex-literal",
  "log",
  "orml-vesting",
+ "pallet-app-promotion",
  "pallet-aura",
  "pallet-balances",
  "pallet-base-fee",
@@ -12132,6 +12149,7 @@
 version = "0.1.3"
 dependencies = [
  "anyhow",
+ "app-promotion-rpc",
  "jsonrpsee",
  "pallet-common",
  "pallet-evm",
@@ -12210,6 +12228,7 @@
 name = "unique-node"
 version = "0.9.27"
 dependencies = [
+ "app-promotion-rpc",
  "clap",
  "cumulus-client-cli",
  "cumulus-client-collator",
@@ -12298,6 +12317,7 @@
 name = "unique-rpc"
 version = "0.1.1"
 dependencies = [
+ "app-promotion-rpc",
  "fc-db",
  "fc-mapping-sync",
  "fc-rpc",
@@ -12347,6 +12367,7 @@
 name = "unique-runtime"
 version = "0.9.27"
 dependencies = [
+ "app-promotion-rpc",
  "cumulus-pallet-aura-ext",
  "cumulus-pallet-dmp-queue",
  "cumulus-pallet-parachain-system",
@@ -12370,6 +12391,7 @@
  "hex-literal",
  "log",
  "orml-vesting",
+ "pallet-app-promotion",
  "pallet-aura",
  "pallet-balances",
  "pallet-base-fee",
modifiedclient/rpc/Cargo.tomldiffbeforeafterboth
--- a/client/rpc/Cargo.toml
+++ b/client/rpc/Cargo.toml
@@ -8,6 +8,7 @@
 pallet-common = { default-features = false, path = '../../pallets/common' }
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
 up-rpc = { path = "../../primitives/rpc" }
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc"}
 rmrk-rpc = { path = "../../primitives/rmrk-rpc" }
 codec = { package = "parity-scale-codec", version = "3.1.2" }
 jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -31,6 +31,7 @@
 use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};
 use sp_blockchain::HeaderBackend;
 use up_rpc::UniqueApi as UniqueRuntimeApi;
+use app_promotion_rpc::AppPromotionApi as AppPromotionRuntimeApi;
 
 // RMRK
 use rmrk_rpc::RmrkApi as RmrkRuntimeApi;
@@ -38,6 +39,7 @@
 	RmrkCollectionId, RmrkNftId, RmrkBaseId, RmrkNftChild, RmrkThemeName, RmrkResourceId,
 };
 
+pub use app_promotion_unique_rpc::AppPromotionApiServer;
 pub use rmrk_unique_rpc::RmrkApiServer;
 
 #[rpc(server)]
@@ -244,39 +246,48 @@
 		token_id: TokenId,
 		at: Option<BlockHash>,
 	) -> Result<Option<String>>;
+}
+
+mod app_promotion_unique_rpc {
+	use super::*;
+	
+	#[rpc(server)]
+	#[async_trait]
+	pub trait AppPromotionApi<BlockHash, BlockNumber, CrossAccountId, AccountId> {
+		/// Returns the total amount of staked tokens.
+		#[method(name = "appPromotion_totalStaked")]
+		fn total_staked(&self, staker: Option<CrossAccountId>, at: Option<BlockHash>)
+			-> Result<String>;
 
-	/// Returns the total amount of staked tokens.
-	#[method(name = "unique_totalStaked")]
-	fn total_staked(&self, staker: Option<CrossAccountId>, at: Option<BlockHash>)
-		-> Result<String>;
+		///Returns the total amount of staked tokens per block when staked.
+		#[method(name = "appPromotion_totalStakedPerBlock")]
+		fn total_staked_per_block(
+			&self,
+			staker: CrossAccountId,
+			at: Option<BlockHash>,
+		) -> Result<Vec<(BlockNumber, String)>>;
 
-	///Returns the total amount of staked tokens per block when staked.
-	#[method(name = "unique_totalStakedPerBlock")]
-	fn total_staked_per_block(
-		&self,
-		staker: CrossAccountId,
-		at: Option<BlockHash>,
-	) -> Result<Vec<(BlockNumber, String)>>;
+		/// Returns the total amount locked by staking tokens.
+		#[method(name = "appPromotion_totalStakingLocked")]
+		fn total_staking_locked(&self, staker: CrossAccountId, at: Option<BlockHash>)
+			-> Result<String>;
 
-	/// Returns the total amount locked by staking tokens.
-	#[method(name = "unique_totalStakingLocked")]
-	fn total_staking_locked(&self, staker: CrossAccountId, at: Option<BlockHash>)
-		-> Result<String>;
+		/// Returns the total amount of tokens pending withdrawal from staking.
+		#[method(name = "appPromotion_pendingUnstake")]
+		fn pending_unstake(
+			&self,
+			staker: Option<CrossAccountId>,
+			at: Option<BlockHash>,
+		) -> Result<String>;
 
-	/// Returns the total amount of tokens pending withdrawal from staking.
-	#[method(name = "unique_pendingUnstake")]
-	fn pending_unstake(
-		&self,
-		staker: Option<CrossAccountId>,
-		at: Option<BlockHash>,
-	) -> Result<String>;
-	/// Returns the total amount of tokens pending withdrawal from staking per block.
-	#[method(name = "unique_pendingUnstakePerBlock")]
-	fn pending_unstake_per_block(
-		&self,
-		staker: CrossAccountId,
-		at: Option<BlockHash>,
-	) -> Result<Vec<(BlockNumber, String)>>;
+		/// Returns the total amount of tokens pending withdrawal from staking per block.
+		#[method(name = "appPromotion_pendingUnstakePerBlock")]
+		fn pending_unstake_per_block(
+			&self,
+			staker: CrossAccountId,
+			at: Option<BlockHash>,
+		) -> Result<Vec<(BlockNumber, String)>>;
+	}
 }
 
 mod rmrk_unique_rpc {
@@ -415,6 +426,20 @@
 	}
 }
 
+pub struct AppPromotion<C, P> {
+	client: Arc<C>,
+	_marker: std::marker::PhantomData<P>,
+}
+
+impl<C, P> AppPromotion<C, P> {
+	pub fn new(client: Arc<C>) -> Self {
+		Self {
+			client,
+			_marker: Default::default(),
+		}
+	}
+}
+
 pub struct Rmrk<C, P> {
 	client: Arc<C>,
 	_marker: std::marker::PhantomData<P>,
@@ -474,6 +499,12 @@
 	};
 }
 
+macro_rules! app_promotion_api {
+	() => {
+		dyn AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>
+	};
+}
+
 macro_rules! rmrk_api {
 	() => {
 		dyn RmrkRuntimeApi<Block, AccountId, CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme>
@@ -556,7 +587,20 @@
 	pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);
 	pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<String> => |o| o.map(|number| number.to_string()) , unique_api);
 	pass_method!(token_owners(collection: CollectionId, token: TokenId) -> Vec<CrossAccountId>, unique_api);
-	pass_method!(total_staked(staker: Option<CrossAccountId>) -> String => |v| v.to_string(), unique_api);
+}
+
+impl<C, Block, BlockNumber, CrossAccountId, AccountId>
+ 	app_promotion_unique_rpc::AppPromotionApiServer<<Block as BlockT>::Hash, BlockNumber, CrossAccountId, AccountId>
+	for AppPromotion<C, Block>
+where
+	Block: BlockT,
+	BlockNumber: Decode + Member + AtLeast32BitUnsigned,
+	AccountId: Decode,
+	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
+	C::Api: AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>,
+	CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,
+{
+	pass_method!(total_staked(staker: Option<CrossAccountId>) -> String => |v| v.to_string(), app_promotion_api);
 	pass_method!(total_staked_per_block(staker: CrossAccountId) -> Vec<(BlockNumber, String)> =>
 		|v| v
 		.into_iter()
modifiednode/cli/Cargo.tomldiffbeforeafterboth
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -318,6 +318,7 @@
 pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }
 
 unique-rpc = { default-features = false, path = "../rpc" }
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
 rmrk-rpc = { path = "../../primitives/rmrk-rpc" }
 
 [features]
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -364,6 +364,7 @@
 		+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
 		+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
 		+ up_rpc::UniqueApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
+		+ app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
 		+ rmrk_rpc::RmrkApi<
 			Block,
 			AccountId,
@@ -665,6 +666,7 @@
 		+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
 		+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
 		+ up_rpc::UniqueApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
+		+ app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
 		+ rmrk_rpc::RmrkApi<
 			Block,
 			AccountId,
@@ -809,6 +811,7 @@
 		+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
 		+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
 		+ up_rpc::UniqueApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
+		+ app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
 		+ rmrk_rpc::RmrkApi<
 			Block,
 			AccountId,
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -53,6 +53,7 @@
 pallet-unique = { path = "../../pallets/unique" }
 uc-rpc = { path = "../../client/rpc" }
 up-rpc = { path = "../../primitives/rpc" }
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc"}
 rmrk-rpc = { path = "../../primitives/rmrk-rpc" }
 up-data-structs = { default-features = false, path = "../../primitives/data-structs" }
 
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -38,6 +38,7 @@
 use sp_block_builder::BlockBuilder;
 use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
 use sc_service::TransactionPool;
+use uc_rpc::AppPromotion;
 use std::{collections::BTreeMap, sync::Arc};
 
 use up_common::types::opaque::{Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance};
@@ -147,6 +148,7 @@
 	C::Api: fp_rpc::ConvertTransactionRuntimeApi<Block>,
 	C::Api:
 		up_rpc::UniqueApi<Block, BlockNumber, <R as RuntimeInstance>::CrossAccountId, AccountId>,
+	C::Api: app_promotion_rpc::AppPromotionApi<Block, BlockNumber, <R as RuntimeInstance>::CrossAccountId, AccountId>,
 	C::Api: rmrk_rpc::RmrkApi<
 		Block,
 		AccountId,
@@ -171,6 +173,7 @@
 		EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, Web3ApiServer,
 	};
 	use uc_rpc::{UniqueApiServer, Unique};
+	use uc_rpc::{AppPromotionApiServer, AppPromotion};
 
 	#[cfg(not(feature = "unique-runtime"))]
 	use uc_rpc::{RmrkApiServer, Rmrk};
@@ -229,6 +232,9 @@
 
 	io.merge(Unique::new(client.clone()).into_rpc())?;
 
+	// #[cfg(not(feature = "unique-runtime"))]
+	io.merge(AppPromotion::new(client.clone()).into_rpc())?;
+
 	#[cfg(not(feature = "unique-runtime"))]
 	io.merge(Rmrk::new(client.clone()).into_rpc())?;
 
addedprimitives/app_promotion_rpc/CHANGELOG.mddiffbeforeafterboth
--- /dev/null
+++ b/primitives/app_promotion_rpc/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+<!-- bureaucrate goes here -->
addedprimitives/app_promotion_rpc/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/primitives/app_promotion_rpc/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "app-promotion-rpc"
+version = "0.1.0"
+license = "GPLv3"
+edition = "2021"
+
+[dependencies]
+pallet-common = { default-features = false, path = '../../pallets/common' }
+up-data-structs = { default-features = false, path = '../data-structs' }
+codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false, features = [
+	"derive",
+] }
+sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
+sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
+sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
+sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }
+
+[features]
+default = ["std"]
+std = [
+	"codec/std",
+	"sp-core/std",
+	"sp-std/std",
+	"sp-api/std",
+	"sp-runtime/std",
+	"pallet-common/std",
+	"up-data-structs/std",
+]
addedprimitives/app_promotion_rpc/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/primitives/app_promotion_rpc/src/lib.rs
@@ -0,0 +1,47 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use up_data_structs::{
+	CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits, Property,
+	PropertyKeyPermission, TokenData, TokenChild,
+};
+
+use sp_std::vec::Vec;
+use codec::Decode;
+use sp_runtime::{
+	DispatchError,
+	traits::{AtLeast32BitUnsigned, Member},
+};
+
+type Result<T> = core::result::Result<T, DispatchError>;
+
+sp_api::decl_runtime_apis! {
+	#[api_version(2)]
+	/// Trait for generate rpc.
+	pub trait AppPromotionApi<BlockNumber ,CrossAccountId, AccountId> where
+		BlockNumber: Decode + Member + AtLeast32BitUnsigned,
+		AccountId: Decode,
+		CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,
+	{
+		fn total_staked(staker: Option<CrossAccountId>) -> Result<u128>;
+		fn total_staked_per_block(staker: CrossAccountId) -> Result<Vec<(BlockNumber, u128)>>;
+		fn total_staking_locked(staker: CrossAccountId) -> Result<u128>;
+		fn pending_unstake(staker: Option<CrossAccountId>) -> Result<u128>;
+		fn pending_unstake_per_block(staker: CrossAccountId) -> Result<Vec<(BlockNumber, u128)>>;
+	}
+}
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -127,11 +127,5 @@
 		fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;
 
 		fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;
-		fn total_staked(staker: Option<CrossAccountId>) -> Result<u128>;
-		fn total_staked_per_block(staker: CrossAccountId) -> Result<Vec<(BlockNumber, u128)>>;
-		fn total_staking_locked(staker: CrossAccountId) -> Result<u128>;
-		fn pending_unstake(staker: Option<CrossAccountId>) -> Result<u128>;
-		fn pending_unstake_per_block(staker: CrossAccountId) -> Result<Vec<(BlockNumber, u128)>>;
-
 	}
 }
modifiedruntime/common/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -187,25 +187,47 @@
                 fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
                     dispatch_unique_runtime!(collection.total_pieces(token_id))
                 }
+            }
 
+            impl app_promotion_rpc::AppPromotionApi<Block, BlockNumber, CrossAccountId, AccountId> for Runtime {
                 fn total_staked(staker: Option<CrossAccountId>) -> Result<u128, DispatchError> {
-                    Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_total_staked(staker).unwrap_or_default())
-                }
+                    #[cfg(not(feature = "app-promotion"))]
+                    return unsupported!();
 
+                    #[cfg(feature = "app-promotion")]
+                    return Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_total_staked(staker).unwrap_or_default());
+                }
+                
                 fn total_staked_per_block(staker: CrossAccountId) -> Result<Vec<(BlockNumber, u128)>, DispatchError> {
-                    Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_total_staked_per_block(staker))
+                    #[cfg(not(feature = "app-promotion"))]
+                    return unsupported!();
+                    
+                    #[cfg(feature = "app-promotion")]
+                    return Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_total_staked_per_block(staker));
                 }
 
                 fn total_staking_locked(staker: CrossAccountId) -> Result<u128, DispatchError> {
-                    Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_locked_balance(staker))
+                    #[cfg(not(feature = "app-promotion"))]
+                    return unsupported!();
+                    
+                    #[cfg(feature = "app-promotion")]
+                    return Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_locked_balance(staker));
                 }
 
                 fn pending_unstake(staker: Option<CrossAccountId>) -> Result<u128, DispatchError> {
-                    Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_pending_unstake(staker))
+                    #[cfg(not(feature = "app-promotion"))]
+                    return unsupported!();
+                    
+                    #[cfg(feature = "app-promotion")]
+                    return Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_pending_unstake(staker));
                 }
 
                 fn pending_unstake_per_block(staker: CrossAccountId) -> Result<Vec<(BlockNumber, u128)>, DispatchError> {
-                    Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_pending_unstake_per_block(staker))
+                    #[cfg(not(feature = "app-promotion"))]
+                    return unsupported!();
+                    
+                    #[cfg(feature = "app-promotion")]
+                    return Ok(<pallet_app_promotion::Pallet<Runtime>>::cross_id_pending_unstake_per_block(staker))
                 }
             }
 
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -83,6 +83,7 @@
     'pallet-base-fee/std',
     'fp-rpc/std',
     'up-rpc/std',
+    'app-promotion-rpc/std',
     'fp-evm-mapping/std',
     'fp-self-contained/std',
     'parachain-info/std',
@@ -414,6 +415,7 @@
 derivative = "2.2.0"
 pallet-unique = { path = '../../pallets/unique', default-features = false }
 up-rpc = { path = "../../primitives/rpc", default-features = false }
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
 rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }
 fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }
 pallet-inflation = { path = '../../pallets/inflation', default-features = false }
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -82,6 +82,7 @@
     'pallet-base-fee/std',
     'fp-rpc/std',
     'up-rpc/std',
+    'app-promotion-rpc/std',
     'fp-evm-mapping/std',
     'fp-self-contained/std',
     'parachain-info/std',
@@ -416,8 +417,10 @@
 derivative = "2.2.0"
 pallet-unique = { path = '../../pallets/unique', default-features = false }
 up-rpc = { path = "../../primitives/rpc", default-features = false }
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
 fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }
 pallet-inflation = { path = '../../pallets/inflation', default-features = false }
+pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
 up-data-structs = { path = '../../primitives/data-structs', default-features = false }
 pallet-configuration = { default-features = false, path = "../../pallets/configuration" }
 pallet-common = { default-features = false, path = "../../pallets/common" }
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -83,6 +83,7 @@
     'pallet-base-fee/std',
     'fp-rpc/std',
     'up-rpc/std',
+    'app-promotion-rpc/std',
     'fp-evm-mapping/std',
     'fp-self-contained/std',
     'parachain-info/std',
@@ -409,8 +410,10 @@
 derivative = "2.2.0"
 pallet-unique = { path = '../../pallets/unique', default-features = false }
 up-rpc = { path = "../../primitives/rpc", default-features = false }
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
 rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }
 pallet-inflation = { path = '../../pallets/inflation', default-features = false }
+pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
 up-data-structs = { path = '../../primitives/data-structs', default-features = false }
 pallet-configuration = { default-features = false, path = "../../pallets/configuration" }
 pallet-common = { default-features = false, path = "../../pallets/common" }
addedtests/src/interfaces/appPromotion/definitions.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/interfaces/appPromotion/definitions.ts
@@ -0,0 +1,66 @@
+// 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/>.
+
+type RpcParam = {
+  name: string;
+  type: string;
+  isOptional?: true;
+};
+
+const CROSS_ACCOUNT_ID_TYPE = 'PalletEvmAccountBasicCrossAccountIdRepr';
+
+const collectionParam = {name: 'collection', type: 'u32'};
+const tokenParam = {name: 'tokenId', type: 'u32'};
+const propertyKeysParam = {name: 'propertyKeys', type: 'Vec<String>', isOptional: true};
+const crossAccountParam = (name = 'account') => ({name, type: CROSS_ACCOUNT_ID_TYPE});
+const atParam = {name: 'at', type: 'Hash', isOptional: true};
+
+const fun = (description: string, params: RpcParam[], type: string) => ({
+  description,
+  params: [...params, atParam],
+  type,
+});
+
+export default {
+  types: {},
+  rpc: {
+    totalStaked: fun(
+      'Returns the total amount of staked tokens',
+      [{name: 'staker', type: CROSS_ACCOUNT_ID_TYPE, isOptional: true}],
+      'u128',
+    ),
+    totalStakedPerBlock: fun(
+      'Returns the total amount of staked tokens per block when staked',
+      [crossAccountParam('staker')],
+      'Vec<(u32, u128)>',
+    ),
+    totalStakingLocked: fun(
+      'Return the total amount locked by staking tokens',
+      [crossAccountParam('staker')],
+      'u128',
+    ),
+    pendingUnstake: fun(
+      'Returns the total amount of unstaked tokens',
+      [{name: 'staker', type: CROSS_ACCOUNT_ID_TYPE, isOptional: true}],
+      'u128',
+    ),
+    pendingUnstakePerBlock: fun(
+      'Returns the total amount of unstaked tokens per block',
+      [crossAccountParam('staker')],
+      'Vec<(u32, u128)>',
+    ),
+  },
+};
addedtests/src/interfaces/appPromotion/index.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/interfaces/appPromotion/index.ts
@@ -0,0 +1,4 @@
+// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
+/* eslint-disable */
+
+export * from './types';
addedtests/src/interfaces/appPromotion/types.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/interfaces/appPromotion/types.ts
@@ -0,0 +1,4 @@
+// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
+/* eslint-disable */
+
+export type PHANTOM_APPPROMOTION = 'appPromotion';
modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
before · tests/src/interfaces/augment-api-errors.ts
1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */34// import type lookup before we augment - in some environments5// this is required to allow for ambient/previous definitions6import '@polkadot/api-base/types/errors';78import type { ApiTypes, AugmentedError } from '@polkadot/api-base/types';910export type __AugmentedError<ApiType extends ApiTypes> = AugmentedError<ApiType>;1112declare module '@polkadot/api-base/types/errors' {13  interface AugmentedErrors<ApiType extends ApiTypes> {14    balances: {15      /**16       * Beneficiary account must pre-exist17       **/18      DeadAccount: AugmentedError<ApiType>;19      /**20       * Value too low to create account due to existential deposit21       **/22      ExistentialDeposit: AugmentedError<ApiType>;23      /**24       * A vesting schedule already exists for this account25       **/26      ExistingVestingSchedule: AugmentedError<ApiType>;27      /**28       * Balance too low to send value29       **/30      InsufficientBalance: AugmentedError<ApiType>;31      /**32       * Transfer/payment would kill account33       **/34      KeepAlive: AugmentedError<ApiType>;35      /**36       * Account liquidity restrictions prevent withdrawal37       **/38      LiquidityRestrictions: AugmentedError<ApiType>;39      /**40       * Number of named reserves exceed MaxReserves41       **/42      TooManyReserves: AugmentedError<ApiType>;43      /**44       * Vesting balance too high to send value45       **/46      VestingBalance: AugmentedError<ApiType>;47      /**48       * Generic error49       **/50      [key: string]: AugmentedError<ApiType>;51    };52    common: {53      /**54       * Account token limit exceeded per collection55       **/56      AccountTokenLimitExceeded: AugmentedError<ApiType>;57      /**58       * Can't transfer tokens to ethereum zero address59       **/60      AddressIsZero: AugmentedError<ApiType>;61      /**62       * Address is not in allow list.63       **/64      AddressNotInAllowlist: AugmentedError<ApiType>;65      /**66       * Requested value is more than the approved67       **/68      ApprovedValueTooLow: AugmentedError<ApiType>;69      /**70       * Tried to approve more than owned71       **/72      CantApproveMoreThanOwned: AugmentedError<ApiType>;73      /**74       * Destroying only empty collections is allowed75       **/76      CantDestroyNotEmptyCollection: AugmentedError<ApiType>;77      /**78       * Exceeded max admin count79       **/80      CollectionAdminCountExceeded: AugmentedError<ApiType>;81      /**82       * Collection description can not be longer than 255 char.83       **/84      CollectionDescriptionLimitExceeded: AugmentedError<ApiType>;85      /**86       * Tried to store more data than allowed in collection field87       **/88      CollectionFieldSizeExceeded: AugmentedError<ApiType>;89      /**90       * Tried to access an external collection with an internal API91       **/92      CollectionIsExternal: AugmentedError<ApiType>;93      /**94       * Tried to access an internal collection with an external API95       **/96      CollectionIsInternal: AugmentedError<ApiType>;97      /**98       * Collection limit bounds per collection exceeded99       **/100      CollectionLimitBoundsExceeded: AugmentedError<ApiType>;101      /**102       * Collection name can not be longer than 63 char.103       **/104      CollectionNameLimitExceeded: AugmentedError<ApiType>;105      /**106       * This collection does not exist.107       **/108      CollectionNotFound: AugmentedError<ApiType>;109      /**110       * Collection token limit exceeded111       **/112      CollectionTokenLimitExceeded: AugmentedError<ApiType>;113      /**114       * Token prefix can not be longer than 15 char.115       **/116      CollectionTokenPrefixLimitExceeded: AugmentedError<ApiType>;117      /**118       * Empty property keys are forbidden119       **/120      EmptyPropertyKey: AugmentedError<ApiType>;121      /**122       * Only ASCII letters, digits, and symbols `_`, `-`, and `.` are allowed123       **/124      InvalidCharacterInPropertyKey: AugmentedError<ApiType>;125      /**126       * Metadata flag frozen127       **/128      MetadataFlagFrozen: AugmentedError<ApiType>;129      /**130       * Sender parameter and item owner must be equal.131       **/132      MustBeTokenOwner: AugmentedError<ApiType>;133      /**134       * No permission to perform action135       **/136      NoPermission: AugmentedError<ApiType>;137      /**138       * Tried to store more property data than allowed139       **/140      NoSpaceForProperty: AugmentedError<ApiType>;141      /**142       * Insufficient funds to perform an action143       **/144      NotSufficientFounds: AugmentedError<ApiType>;145      /**146       * Tried to enable permissions which are only permitted to be disabled147       **/148      OwnerPermissionsCantBeReverted: AugmentedError<ApiType>;149      /**150       * Property key is too long151       **/152      PropertyKeyIsTooLong: AugmentedError<ApiType>;153      /**154       * Tried to store more property keys than allowed155       **/156      PropertyLimitReached: AugmentedError<ApiType>;157      /**158       * Collection is not in mint mode.159       **/160      PublicMintingNotAllowed: AugmentedError<ApiType>;161      /**162       * Only tokens from specific collections may nest tokens under this one163       **/164      SourceCollectionIsNotAllowedToNest: AugmentedError<ApiType>;165      /**166       * Item does not exist167       **/168      TokenNotFound: AugmentedError<ApiType>;169      /**170       * Item is balance not enough171       **/172      TokenValueTooLow: AugmentedError<ApiType>;173      /**174       * Total collections bound exceeded.175       **/176      TotalCollectionsLimitExceeded: AugmentedError<ApiType>;177      /**178       * Collection settings not allowing items transferring179       **/180      TransferNotAllowed: AugmentedError<ApiType>;181      /**182       * The operation is not supported183       **/184      UnsupportedOperation: AugmentedError<ApiType>;185      /**186       * User does not satisfy the nesting rule187       **/188      UserIsNotAllowedToNest: AugmentedError<ApiType>;189      /**190       * Generic error191       **/192      [key: string]: AugmentedError<ApiType>;193    };194    cumulusXcm: {195      /**196       * Generic error197       **/198      [key: string]: AugmentedError<ApiType>;199    };200    dmpQueue: {201      /**202       * The amount of weight given is possibly not enough for executing the message.203       **/204      OverLimit: AugmentedError<ApiType>;205      /**206       * The message index given is unknown.207       **/208      Unknown: AugmentedError<ApiType>;209      /**210       * Generic error211       **/212      [key: string]: AugmentedError<ApiType>;213    };214    ethereum: {215      /**216       * Signature is invalid.217       **/218      InvalidSignature: AugmentedError<ApiType>;219      /**220       * Pre-log is present, therefore transact is not allowed.221       **/222      PreLogExists: AugmentedError<ApiType>;223      /**224       * Generic error225       **/226      [key: string]: AugmentedError<ApiType>;227    };228    evm: {229      /**230       * Not enough balance to perform action231       **/232      BalanceLow: AugmentedError<ApiType>;233      /**234       * Calculating total fee overflowed235       **/236      FeeOverflow: AugmentedError<ApiType>;237      /**238       * Gas price is too low.239       **/240      GasPriceTooLow: AugmentedError<ApiType>;241      /**242       * Nonce is invalid243       **/244      InvalidNonce: AugmentedError<ApiType>;245      /**246       * Calculating total payment overflowed247       **/248      PaymentOverflow: AugmentedError<ApiType>;249      /**250       * Withdraw fee failed251       **/252      WithdrawFailed: AugmentedError<ApiType>;253      /**254       * Generic error255       **/256      [key: string]: AugmentedError<ApiType>;257    };258    evmCoderSubstrate: {259      OutOfFund: AugmentedError<ApiType>;260      OutOfGas: AugmentedError<ApiType>;261      /**262       * Generic error263       **/264      [key: string]: AugmentedError<ApiType>;265    };266    evmContractHelpers: {267      /**268       * No pending sponsor for contract.269       **/270      NoPendingSponsor: AugmentedError<ApiType>;271      /**272       * This method is only executable by owner.273       **/274      NoPermission: AugmentedError<ApiType>;275      /**276       * Generic error277       **/278      [key: string]: AugmentedError<ApiType>;279    };280    evmMigration: {281      AccountIsNotMigrating: AugmentedError<ApiType>;282      AccountNotEmpty: AugmentedError<ApiType>;283      /**284       * Generic error285       **/286      [key: string]: AugmentedError<ApiType>;287    };288    fungible: {289      /**290       * Fungible token does not support nesting.291       **/292      FungibleDisallowsNesting: AugmentedError<ApiType>;293      /**294       * Tried to set data for fungible item.295       **/296      FungibleItemsDontHaveData: AugmentedError<ApiType>;297      /**298       * Fungible tokens hold no ID, and the default value of TokenId for Fungible collection is 0.299       **/300      FungibleItemsHaveNoId: AugmentedError<ApiType>;301      /**302       * Not Fungible item data used to mint in Fungible collection.303       **/304      NotFungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;305      /**306       * Setting item properties is not allowed.307       **/308      SettingPropertiesNotAllowed: AugmentedError<ApiType>;309      /**310       * Generic error311       **/312      [key: string]: AugmentedError<ApiType>;313    };314    nonfungible: {315      /**316       * Unable to burn NFT with children317       **/318      CantBurnNftWithChildren: AugmentedError<ApiType>;319      /**320       * Used amount > 1 with NFT321       **/322      NonfungibleItemsHaveNoAmount: AugmentedError<ApiType>;323      /**324       * Not Nonfungible item data used to mint in Nonfungible collection.325       **/326      NotNonfungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;327      /**328       * Generic error329       **/330      [key: string]: AugmentedError<ApiType>;331    };332    parachainSystem: {333      /**334       * The inherent which supplies the host configuration did not run this block335       **/336      HostConfigurationNotAvailable: AugmentedError<ApiType>;337      /**338       * No code upgrade has been authorized.339       **/340      NothingAuthorized: AugmentedError<ApiType>;341      /**342       * No validation function upgrade is currently scheduled.343       **/344      NotScheduled: AugmentedError<ApiType>;345      /**346       * Attempt to upgrade validation function while existing upgrade pending347       **/348      OverlappingUpgrades: AugmentedError<ApiType>;349      /**350       * Polkadot currently prohibits this parachain from upgrading its validation function351       **/352      ProhibitedByPolkadot: AugmentedError<ApiType>;353      /**354       * The supplied validation function has compiled into a blob larger than Polkadot is355       * willing to run356       **/357      TooBig: AugmentedError<ApiType>;358      /**359       * The given code upgrade has not been authorized.360       **/361      Unauthorized: AugmentedError<ApiType>;362      /**363       * The inherent which supplies the validation data did not run this block364       **/365      ValidationDataNotAvailable: AugmentedError<ApiType>;366      /**367       * Generic error368       **/369      [key: string]: AugmentedError<ApiType>;370    };371    polkadotXcm: {372      /**373       * The location is invalid since it already has a subscription from us.374       **/375      AlreadySubscribed: AugmentedError<ApiType>;376      /**377       * The given location could not be used (e.g. because it cannot be expressed in the378       * desired version of XCM).379       **/380      BadLocation: AugmentedError<ApiType>;381      /**382       * The version of the `Versioned` value used is not able to be interpreted.383       **/384      BadVersion: AugmentedError<ApiType>;385      /**386       * Could not re-anchor the assets to declare the fees for the destination chain.387       **/388      CannotReanchor: AugmentedError<ApiType>;389      /**390       * The destination `MultiLocation` provided cannot be inverted.391       **/392      DestinationNotInvertible: AugmentedError<ApiType>;393      /**394       * The assets to be sent are empty.395       **/396      Empty: AugmentedError<ApiType>;397      /**398       * The message execution fails the filter.399       **/400      Filtered: AugmentedError<ApiType>;401      /**402       * Origin is invalid for sending.403       **/404      InvalidOrigin: AugmentedError<ApiType>;405      /**406       * The referenced subscription could not be found.407       **/408      NoSubscription: AugmentedError<ApiType>;409      /**410       * There was some other issue (i.e. not to do with routing) in sending the message. Perhaps411       * a lack of space for buffering the message.412       **/413      SendFailure: AugmentedError<ApiType>;414      /**415       * Too many assets have been attempted for transfer.416       **/417      TooManyAssets: AugmentedError<ApiType>;418      /**419       * The desired destination was unreachable, generally because there is a no way of routing420       * to it.421       **/422      Unreachable: AugmentedError<ApiType>;423      /**424       * The message's weight could not be determined.425       **/426      UnweighableMessage: AugmentedError<ApiType>;427      /**428       * Generic error429       **/430      [key: string]: AugmentedError<ApiType>;431    };432    promotion: {433      /**434       * Error due to action requiring admin to be set435       **/436      AdminNotSet: AugmentedError<ApiType>;437      /**438       * An error related to the fact that an invalid argument was passed to perform an action439       **/440      InvalidArgument: AugmentedError<ApiType>;441      /**442       * No permission to perform an action443       **/444      NoPermission: AugmentedError<ApiType>;445      /**446       * Insufficient funds to perform an action447       **/448      NotSufficientFounds: AugmentedError<ApiType>;449      /**450       * Generic error451       **/452      [key: string]: AugmentedError<ApiType>;453    };454    refungible: {455      /**456       * Not Refungible item data used to mint in Refungible collection.457       **/458      NotRefungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;459      /**460       * Refungible token can't nest other tokens.461       **/462      RefungibleDisallowsNesting: AugmentedError<ApiType>;463      /**464       * Refungible token can't be repartitioned by user who isn't owns all pieces.465       **/466      RepartitionWhileNotOwningAllPieces: AugmentedError<ApiType>;467      /**468       * Setting item properties is not allowed.469       **/470      SettingPropertiesNotAllowed: AugmentedError<ApiType>;471      /**472       * Maximum refungibility exceeded.473       **/474      WrongRefungiblePieces: AugmentedError<ApiType>;475      /**476       * Generic error477       **/478      [key: string]: AugmentedError<ApiType>;479    };480    rmrkCore: {481      /**482       * Not the target owner of the sent NFT.483       **/484      CannotAcceptNonOwnedNft: AugmentedError<ApiType>;485      /**486       * Not the target owner of the sent NFT.487       **/488      CannotRejectNonOwnedNft: AugmentedError<ApiType>;489      /**490       * NFT was not sent and is not pending.491       **/492      CannotRejectNonPendingNft: AugmentedError<ApiType>;493      /**494       * If an NFT is sent to a descendant, that would form a nesting loop, an ouroboros.495       * Sending to self is redundant.496       **/497      CannotSendToDescendentOrSelf: AugmentedError<ApiType>;498      /**499       * Too many tokens created in the collection, no new ones are allowed.500       **/501      CollectionFullOrLocked: AugmentedError<ApiType>;502      /**503       * Only destroying collections without tokens is allowed.504       **/505      CollectionNotEmpty: AugmentedError<ApiType>;506      /**507       * Collection does not exist, has a wrong type, or does not map to a Unique ID.508       **/509      CollectionUnknown: AugmentedError<ApiType>;510      /**511       * Property of the type of RMRK collection could not be read successfully.512       **/513      CorruptedCollectionType: AugmentedError<ApiType>;514      /**515       * Could not find an ID for a collection. It is likely there were too many collections created on the chain, causing an overflow.516       **/517      NoAvailableCollectionId: AugmentedError<ApiType>;518      /**519       * Token does not exist, or there is no suitable ID for it, likely too many tokens were created in a collection, causing an overflow.520       **/521      NoAvailableNftId: AugmentedError<ApiType>;522      /**523       * Could not find an ID for the resource. It is likely there were too many resources created on an NFT, causing an overflow.524       **/525      NoAvailableResourceId: AugmentedError<ApiType>;526      /**527       * Token is marked as non-transferable, and thus cannot be transferred.528       **/529      NonTransferable: AugmentedError<ApiType>;530      /**531       * No permission to perform action.532       **/533      NoPermission: AugmentedError<ApiType>;534      /**535       * No such resource found.536       **/537      ResourceDoesntExist: AugmentedError<ApiType>;538      /**539       * Resource is not pending for the operation.540       **/541      ResourceNotPending: AugmentedError<ApiType>;542      /**543       * Could not find a property by the supplied key.544       **/545      RmrkPropertyIsNotFound: AugmentedError<ApiType>;546      /**547       * Too many symbols supplied as the property key. The maximum is [256](up_data_structs::MAX_PROPERTY_KEY_LENGTH).548       **/549      RmrkPropertyKeyIsTooLong: AugmentedError<ApiType>;550      /**551       * Too many bytes supplied as the property value. The maximum is [32768](up_data_structs::MAX_PROPERTY_VALUE_LENGTH).552       **/553      RmrkPropertyValueIsTooLong: AugmentedError<ApiType>;554      /**555       * Something went wrong when decoding encoded data from the storage.556       * Perhaps, there was a wrong key supplied for the type, or the data was improperly stored.557       **/558      UnableToDecodeRmrkData: AugmentedError<ApiType>;559      /**560       * Generic error561       **/562      [key: string]: AugmentedError<ApiType>;563    };564    rmrkEquip: {565      /**566       * Base collection linked to this ID does not exist.567       **/568      BaseDoesntExist: AugmentedError<ApiType>;569      /**570       * No Theme named "default" is associated with the Base.571       **/572      NeedsDefaultThemeFirst: AugmentedError<ApiType>;573      /**574       * Could not find an ID for a Base collection. It is likely there were too many collections created on the chain, causing an overflow.575       **/576      NoAvailableBaseId: AugmentedError<ApiType>;577      /**578       * Could not find a suitable ID for a Part, likely too many Part tokens were created in the Base, causing an overflow579       **/580      NoAvailablePartId: AugmentedError<ApiType>;581      /**582       * Cannot assign equippables to a fixed Part.583       **/584      NoEquippableOnFixedPart: AugmentedError<ApiType>;585      /**586       * Part linked to this ID does not exist.587       **/588      PartDoesntExist: AugmentedError<ApiType>;589      /**590       * No permission to perform action.591       **/592      PermissionError: AugmentedError<ApiType>;593      /**594       * Generic error595       **/596      [key: string]: AugmentedError<ApiType>;597    };598    scheduler: {599      /**600       * Failed to schedule a call601       **/602      FailedToSchedule: AugmentedError<ApiType>;603      /**604       * Cannot find the scheduled call.605       **/606      NotFound: AugmentedError<ApiType>;607      /**608       * Reschedule failed because it does not change scheduled time.609       **/610      RescheduleNoChange: AugmentedError<ApiType>;611      /**612       * Given target block number is in the past.613       **/614      TargetBlockNumberInPast: AugmentedError<ApiType>;615      /**616       * Generic error617       **/618      [key: string]: AugmentedError<ApiType>;619    };620    structure: {621      /**622       * While nesting, reached the breadth limit of nesting, exceeding the provided budget.623       **/624      BreadthLimit: AugmentedError<ApiType>;625      /**626       * While nesting, reached the depth limit of nesting, exceeding the provided budget.627       **/628      DepthLimit: AugmentedError<ApiType>;629      /**630       * While nesting, encountered an already checked account, detecting a loop.631       **/632      OuroborosDetected: AugmentedError<ApiType>;633      /**634       * Couldn't find the token owner that is itself a token.635       **/636      TokenNotFound: AugmentedError<ApiType>;637      /**638       * Generic error639       **/640      [key: string]: AugmentedError<ApiType>;641    };642    sudo: {643      /**644       * Sender must be the Sudo account645       **/646      RequireSudo: AugmentedError<ApiType>;647      /**648       * Generic error649       **/650      [key: string]: AugmentedError<ApiType>;651    };652    system: {653      /**654       * The origin filter prevent the call to be dispatched.655       **/656      CallFiltered: AugmentedError<ApiType>;657      /**658       * Failed to extract the runtime version from the new runtime.659       * 660       * Either calling `Core_version` or decoding `RuntimeVersion` failed.661       **/662      FailedToExtractRuntimeVersion: AugmentedError<ApiType>;663      /**664       * The name of specification does not match between the current runtime665       * and the new runtime.666       **/667      InvalidSpecName: AugmentedError<ApiType>;668      /**669       * Suicide called when the account has non-default composite data.670       **/671      NonDefaultComposite: AugmentedError<ApiType>;672      /**673       * There is a non-zero reference count preventing the account from being purged.674       **/675      NonZeroRefCount: AugmentedError<ApiType>;676      /**677       * The specification version is not allowed to decrease between the current runtime678       * and the new runtime.679       **/680      SpecVersionNeedsToIncrease: AugmentedError<ApiType>;681      /**682       * Generic error683       **/684      [key: string]: AugmentedError<ApiType>;685    };686    treasury: {687      /**688       * The spend origin is valid but the amount it is allowed to spend is lower than the689       * amount to be spent.690       **/691      InsufficientPermission: AugmentedError<ApiType>;692      /**693       * Proposer's balance is too low.694       **/695      InsufficientProposersBalance: AugmentedError<ApiType>;696      /**697       * No proposal or bounty at that index.698       **/699      InvalidIndex: AugmentedError<ApiType>;700      /**701       * Proposal has not been approved.702       **/703      ProposalNotApproved: AugmentedError<ApiType>;704      /**705       * Too many approvals in the queue.706       **/707      TooManyApprovals: AugmentedError<ApiType>;708      /**709       * Generic error710       **/711      [key: string]: AugmentedError<ApiType>;712    };713    unique: {714      /**715       * Decimal_points parameter must be lower than [`up_data_structs::MAX_DECIMAL_POINTS`].716       **/717      CollectionDecimalPointLimitExceeded: AugmentedError<ApiType>;718      /**719       * This address is not set as sponsor, use setCollectionSponsor first.720       **/721      ConfirmUnsetSponsorFail: AugmentedError<ApiType>;722      /**723       * Length of items properties must be greater than 0.724       **/725      EmptyArgument: AugmentedError<ApiType>;726      /**727       * Repertition is only supported by refungible collection.728       **/729      RepartitionCalledOnNonRefungibleCollection: AugmentedError<ApiType>;730      /**731       * Generic error732       **/733      [key: string]: AugmentedError<ApiType>;734    };735    vesting: {736      /**737       * The vested transfer amount is too low738       **/739      AmountLow: AugmentedError<ApiType>;740      /**741       * Insufficient amount of balance to lock742       **/743      InsufficientBalanceToLock: AugmentedError<ApiType>;744      /**745       * Failed because the maximum vesting schedules was exceeded746       **/747      MaxVestingSchedulesExceeded: AugmentedError<ApiType>;748      /**749       * This account have too many vesting schedules750       **/751      TooManyVestingSchedules: AugmentedError<ApiType>;752      /**753       * Vesting period is zero754       **/755      ZeroVestingPeriod: AugmentedError<ApiType>;756      /**757       * Number of vests is zero758       **/759      ZeroVestingPeriodCount: AugmentedError<ApiType>;760      /**761       * Generic error762       **/763      [key: string]: AugmentedError<ApiType>;764    };765    xcmpQueue: {766      /**767       * Bad overweight index.768       **/769      BadOverweightIndex: AugmentedError<ApiType>;770      /**771       * Bad XCM data.772       **/773      BadXcm: AugmentedError<ApiType>;774      /**775       * Bad XCM origin.776       **/777      BadXcmOrigin: AugmentedError<ApiType>;778      /**779       * Failed to send XCM message.780       **/781      FailedToSend: AugmentedError<ApiType>;782      /**783       * Provided weight is possibly not enough to execute the message.784       **/785      WeightOverLimit: AugmentedError<ApiType>;786      /**787       * Generic error788       **/789      [key: string]: AugmentedError<ApiType>;790    };791  } // AugmentedErrors792} // declare module
after · tests/src/interfaces/augment-api-errors.ts
1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */34// import type lookup before we augment - in some environments5// this is required to allow for ambient/previous definitions6import '@polkadot/api-base/types/errors';78import type { ApiTypes, AugmentedError } from '@polkadot/api-base/types';910export type __AugmentedError<ApiType extends ApiTypes> = AugmentedError<ApiType>;1112declare module '@polkadot/api-base/types/errors' {13  interface AugmentedErrors<ApiType extends ApiTypes> {14    balances: {15      /**16       * Beneficiary account must pre-exist17       **/18      DeadAccount: AugmentedError<ApiType>;19      /**20       * Value too low to create account due to existential deposit21       **/22      ExistentialDeposit: AugmentedError<ApiType>;23      /**24       * A vesting schedule already exists for this account25       **/26      ExistingVestingSchedule: AugmentedError<ApiType>;27      /**28       * Balance too low to send value29       **/30      InsufficientBalance: AugmentedError<ApiType>;31      /**32       * Transfer/payment would kill account33       **/34      KeepAlive: AugmentedError<ApiType>;35      /**36       * Account liquidity restrictions prevent withdrawal37       **/38      LiquidityRestrictions: AugmentedError<ApiType>;39      /**40       * Number of named reserves exceed MaxReserves41       **/42      TooManyReserves: AugmentedError<ApiType>;43      /**44       * Vesting balance too high to send value45       **/46      VestingBalance: AugmentedError<ApiType>;47      /**48       * Generic error49       **/50      [key: string]: AugmentedError<ApiType>;51    };52    common: {53      /**54       * Account token limit exceeded per collection55       **/56      AccountTokenLimitExceeded: AugmentedError<ApiType>;57      /**58       * Can't transfer tokens to ethereum zero address59       **/60      AddressIsZero: AugmentedError<ApiType>;61      /**62       * Address is not in allow list.63       **/64      AddressNotInAllowlist: AugmentedError<ApiType>;65      /**66       * Requested value is more than the approved67       **/68      ApprovedValueTooLow: AugmentedError<ApiType>;69      /**70       * Tried to approve more than owned71       **/72      CantApproveMoreThanOwned: AugmentedError<ApiType>;73      /**74       * Destroying only empty collections is allowed75       **/76      CantDestroyNotEmptyCollection: AugmentedError<ApiType>;77      /**78       * Exceeded max admin count79       **/80      CollectionAdminCountExceeded: AugmentedError<ApiType>;81      /**82       * Collection description can not be longer than 255 char.83       **/84      CollectionDescriptionLimitExceeded: AugmentedError<ApiType>;85      /**86       * Tried to store more data than allowed in collection field87       **/88      CollectionFieldSizeExceeded: AugmentedError<ApiType>;89      /**90       * Tried to access an external collection with an internal API91       **/92      CollectionIsExternal: AugmentedError<ApiType>;93      /**94       * Tried to access an internal collection with an external API95       **/96      CollectionIsInternal: AugmentedError<ApiType>;97      /**98       * Collection limit bounds per collection exceeded99       **/100      CollectionLimitBoundsExceeded: AugmentedError<ApiType>;101      /**102       * Collection name can not be longer than 63 char.103       **/104      CollectionNameLimitExceeded: AugmentedError<ApiType>;105      /**106       * This collection does not exist.107       **/108      CollectionNotFound: AugmentedError<ApiType>;109      /**110       * Collection token limit exceeded111       **/112      CollectionTokenLimitExceeded: AugmentedError<ApiType>;113      /**114       * Token prefix can not be longer than 15 char.115       **/116      CollectionTokenPrefixLimitExceeded: AugmentedError<ApiType>;117      /**118       * Empty property keys are forbidden119       **/120      EmptyPropertyKey: AugmentedError<ApiType>;121      /**122       * Only ASCII letters, digits, and symbols `_`, `-`, and `.` are allowed123       **/124      InvalidCharacterInPropertyKey: AugmentedError<ApiType>;125      /**126       * Metadata flag frozen127       **/128      MetadataFlagFrozen: AugmentedError<ApiType>;129      /**130       * Sender parameter and item owner must be equal.131       **/132      MustBeTokenOwner: AugmentedError<ApiType>;133      /**134       * No permission to perform action135       **/136      NoPermission: AugmentedError<ApiType>;137      /**138       * Tried to store more property data than allowed139       **/140      NoSpaceForProperty: AugmentedError<ApiType>;141      /**142       * Insufficient funds to perform an action143       **/144      NotSufficientFounds: AugmentedError<ApiType>;145      /**146       * Tried to enable permissions which are only permitted to be disabled147       **/148      OwnerPermissionsCantBeReverted: AugmentedError<ApiType>;149      /**150       * Property key is too long151       **/152      PropertyKeyIsTooLong: AugmentedError<ApiType>;153      /**154       * Tried to store more property keys than allowed155       **/156      PropertyLimitReached: AugmentedError<ApiType>;157      /**158       * Collection is not in mint mode.159       **/160      PublicMintingNotAllowed: AugmentedError<ApiType>;161      /**162       * Only tokens from specific collections may nest tokens under this one163       **/164      SourceCollectionIsNotAllowedToNest: AugmentedError<ApiType>;165      /**166       * Item does not exist167       **/168      TokenNotFound: AugmentedError<ApiType>;169      /**170       * Item is balance not enough171       **/172      TokenValueTooLow: AugmentedError<ApiType>;173      /**174       * Total collections bound exceeded.175       **/176      TotalCollectionsLimitExceeded: AugmentedError<ApiType>;177      /**178       * Collection settings not allowing items transferring179       **/180      TransferNotAllowed: AugmentedError<ApiType>;181      /**182       * The operation is not supported183       **/184      UnsupportedOperation: AugmentedError<ApiType>;185      /**186       * User does not satisfy the nesting rule187       **/188      UserIsNotAllowedToNest: AugmentedError<ApiType>;189      /**190       * Generic error191       **/192      [key: string]: AugmentedError<ApiType>;193    };194    cumulusXcm: {195      /**196       * Generic error197       **/198      [key: string]: AugmentedError<ApiType>;199    };200    dmpQueue: {201      /**202       * The amount of weight given is possibly not enough for executing the message.203       **/204      OverLimit: AugmentedError<ApiType>;205      /**206       * The message index given is unknown.207       **/208      Unknown: AugmentedError<ApiType>;209      /**210       * Generic error211       **/212      [key: string]: AugmentedError<ApiType>;213    };214    ethereum: {215      /**216       * Signature is invalid.217       **/218      InvalidSignature: AugmentedError<ApiType>;219      /**220       * Pre-log is present, therefore transact is not allowed.221       **/222      PreLogExists: AugmentedError<ApiType>;223      /**224       * Generic error225       **/226      [key: string]: AugmentedError<ApiType>;227    };228    evm: {229      /**230       * Not enough balance to perform action231       **/232      BalanceLow: AugmentedError<ApiType>;233      /**234       * Calculating total fee overflowed235       **/236      FeeOverflow: AugmentedError<ApiType>;237      /**238       * Gas price is too low.239       **/240      GasPriceTooLow: AugmentedError<ApiType>;241      /**242       * Nonce is invalid243       **/244      InvalidNonce: AugmentedError<ApiType>;245      /**246       * Calculating total payment overflowed247       **/248      PaymentOverflow: AugmentedError<ApiType>;249      /**250       * Withdraw fee failed251       **/252      WithdrawFailed: AugmentedError<ApiType>;253      /**254       * Generic error255       **/256      [key: string]: AugmentedError<ApiType>;257    };258    evmCoderSubstrate: {259      OutOfFund: AugmentedError<ApiType>;260      OutOfGas: AugmentedError<ApiType>;261      /**262       * Generic error263       **/264      [key: string]: AugmentedError<ApiType>;265    };266    evmContractHelpers: {267      /**268       * No pending sponsor for contract.269       **/270      NoPendingSponsor: AugmentedError<ApiType>;271      /**272       * This method is only executable by contract owner273       **/274      NoPermission: AugmentedError<ApiType>;275      /**276       * Generic error277       **/278      [key: string]: AugmentedError<ApiType>;279    };280    evmMigration: {281      /**282       * Migration of this account is not yet started, or already finished.283       **/284      AccountIsNotMigrating: AugmentedError<ApiType>;285      /**286       * Can only migrate to empty address.287       **/288      AccountNotEmpty: AugmentedError<ApiType>;289      /**290       * Generic error291       **/292      [key: string]: AugmentedError<ApiType>;293    };294    fungible: {295      /**296       * Fungible token does not support nesting.297       **/298      FungibleDisallowsNesting: AugmentedError<ApiType>;299      /**300       * Tried to set data for fungible item.301       **/302      FungibleItemsDontHaveData: AugmentedError<ApiType>;303      /**304       * Fungible tokens hold no ID, and the default value of TokenId for Fungible collection is 0.305       **/306      FungibleItemsHaveNoId: AugmentedError<ApiType>;307      /**308       * Not Fungible item data used to mint in Fungible collection.309       **/310      NotFungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;311      /**312       * Setting item properties is not allowed.313       **/314      SettingPropertiesNotAllowed: AugmentedError<ApiType>;315      /**316       * Generic error317       **/318      [key: string]: AugmentedError<ApiType>;319    };320    nonfungible: {321      /**322       * Unable to burn NFT with children323       **/324      CantBurnNftWithChildren: AugmentedError<ApiType>;325      /**326       * Used amount > 1 with NFT327       **/328      NonfungibleItemsHaveNoAmount: AugmentedError<ApiType>;329      /**330       * Not Nonfungible item data used to mint in Nonfungible collection.331       **/332      NotNonfungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;333      /**334       * Generic error335       **/336      [key: string]: AugmentedError<ApiType>;337    };338    parachainSystem: {339      /**340       * The inherent which supplies the host configuration did not run this block341       **/342      HostConfigurationNotAvailable: AugmentedError<ApiType>;343      /**344       * No code upgrade has been authorized.345       **/346      NothingAuthorized: AugmentedError<ApiType>;347      /**348       * No validation function upgrade is currently scheduled.349       **/350      NotScheduled: AugmentedError<ApiType>;351      /**352       * Attempt to upgrade validation function while existing upgrade pending353       **/354      OverlappingUpgrades: AugmentedError<ApiType>;355      /**356       * Polkadot currently prohibits this parachain from upgrading its validation function357       **/358      ProhibitedByPolkadot: AugmentedError<ApiType>;359      /**360       * The supplied validation function has compiled into a blob larger than Polkadot is361       * willing to run362       **/363      TooBig: AugmentedError<ApiType>;364      /**365       * The given code upgrade has not been authorized.366       **/367      Unauthorized: AugmentedError<ApiType>;368      /**369       * The inherent which supplies the validation data did not run this block370       **/371      ValidationDataNotAvailable: AugmentedError<ApiType>;372      /**373       * Generic error374       **/375      [key: string]: AugmentedError<ApiType>;376    };377    polkadotXcm: {378      /**379       * The location is invalid since it already has a subscription from us.380       **/381      AlreadySubscribed: AugmentedError<ApiType>;382      /**383       * The given location could not be used (e.g. because it cannot be expressed in the384       * desired version of XCM).385       **/386      BadLocation: AugmentedError<ApiType>;387      /**388       * The version of the `Versioned` value used is not able to be interpreted.389       **/390      BadVersion: AugmentedError<ApiType>;391      /**392       * Could not re-anchor the assets to declare the fees for the destination chain.393       **/394      CannotReanchor: AugmentedError<ApiType>;395      /**396       * The destination `MultiLocation` provided cannot be inverted.397       **/398      DestinationNotInvertible: AugmentedError<ApiType>;399      /**400       * The assets to be sent are empty.401       **/402      Empty: AugmentedError<ApiType>;403      /**404       * The message execution fails the filter.405       **/406      Filtered: AugmentedError<ApiType>;407      /**408       * Origin is invalid for sending.409       **/410      InvalidOrigin: AugmentedError<ApiType>;411      /**412       * The referenced subscription could not be found.413       **/414      NoSubscription: AugmentedError<ApiType>;415      /**416       * There was some other issue (i.e. not to do with routing) in sending the message. Perhaps417       * a lack of space for buffering the message.418       **/419      SendFailure: AugmentedError<ApiType>;420      /**421       * Too many assets have been attempted for transfer.422       **/423      TooManyAssets: AugmentedError<ApiType>;424      /**425       * The desired destination was unreachable, generally because there is a no way of routing426       * to it.427       **/428      Unreachable: AugmentedError<ApiType>;429      /**430       * The message's weight could not be determined.431       **/432      UnweighableMessage: AugmentedError<ApiType>;433      /**434       * Generic error435       **/436      [key: string]: AugmentedError<ApiType>;437    };438    promotion: {439      /**440       * Error due to action requiring admin to be set441       **/442      AdminNotSet: AugmentedError<ApiType>;443      /**444       * An error related to the fact that an invalid argument was passed to perform an action445       **/446      InvalidArgument: AugmentedError<ApiType>;447      /**448       * No permission to perform an action449       **/450      NoPermission: AugmentedError<ApiType>;451      /**452       * Insufficient funds to perform an action453       **/454      NotSufficientFounds: AugmentedError<ApiType>;455      /**456       * Generic error457       **/458      [key: string]: AugmentedError<ApiType>;459    };460    refungible: {461      /**462       * Not Refungible item data used to mint in Refungible collection.463       **/464      NotRefungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;465      /**466       * Refungible token can't nest other tokens.467       **/468      RefungibleDisallowsNesting: AugmentedError<ApiType>;469      /**470       * Refungible token can't be repartitioned by user who isn't owns all pieces.471       **/472      RepartitionWhileNotOwningAllPieces: AugmentedError<ApiType>;473      /**474       * Setting item properties is not allowed.475       **/476      SettingPropertiesNotAllowed: AugmentedError<ApiType>;477      /**478       * Maximum refungibility exceeded.479       **/480      WrongRefungiblePieces: AugmentedError<ApiType>;481      /**482       * Generic error483       **/484      [key: string]: AugmentedError<ApiType>;485    };486    rmrkCore: {487      /**488       * Not the target owner of the sent NFT.489       **/490      CannotAcceptNonOwnedNft: AugmentedError<ApiType>;491      /**492       * Not the target owner of the sent NFT.493       **/494      CannotRejectNonOwnedNft: AugmentedError<ApiType>;495      /**496       * NFT was not sent and is not pending.497       **/498      CannotRejectNonPendingNft: AugmentedError<ApiType>;499      /**500       * If an NFT is sent to a descendant, that would form a nesting loop, an ouroboros.501       * Sending to self is redundant.502       **/503      CannotSendToDescendentOrSelf: AugmentedError<ApiType>;504      /**505       * Too many tokens created in the collection, no new ones are allowed.506       **/507      CollectionFullOrLocked: AugmentedError<ApiType>;508      /**509       * Only destroying collections without tokens is allowed.510       **/511      CollectionNotEmpty: AugmentedError<ApiType>;512      /**513       * Collection does not exist, has a wrong type, or does not map to a Unique ID.514       **/515      CollectionUnknown: AugmentedError<ApiType>;516      /**517       * Property of the type of RMRK collection could not be read successfully.518       **/519      CorruptedCollectionType: AugmentedError<ApiType>;520      /**521       * Could not find an ID for a collection. It is likely there were too many collections created on the chain, causing an overflow.522       **/523      NoAvailableCollectionId: AugmentedError<ApiType>;524      /**525       * Token does not exist, or there is no suitable ID for it, likely too many tokens were created in a collection, causing an overflow.526       **/527      NoAvailableNftId: AugmentedError<ApiType>;528      /**529       * Could not find an ID for the resource. It is likely there were too many resources created on an NFT, causing an overflow.530       **/531      NoAvailableResourceId: AugmentedError<ApiType>;532      /**533       * Token is marked as non-transferable, and thus cannot be transferred.534       **/535      NonTransferable: AugmentedError<ApiType>;536      /**537       * No permission to perform action.538       **/539      NoPermission: AugmentedError<ApiType>;540      /**541       * No such resource found.542       **/543      ResourceDoesntExist: AugmentedError<ApiType>;544      /**545       * Resource is not pending for the operation.546       **/547      ResourceNotPending: AugmentedError<ApiType>;548      /**549       * Could not find a property by the supplied key.550       **/551      RmrkPropertyIsNotFound: AugmentedError<ApiType>;552      /**553       * Too many symbols supplied as the property key. The maximum is [256](up_data_structs::MAX_PROPERTY_KEY_LENGTH).554       **/555      RmrkPropertyKeyIsTooLong: AugmentedError<ApiType>;556      /**557       * Too many bytes supplied as the property value. The maximum is [32768](up_data_structs::MAX_PROPERTY_VALUE_LENGTH).558       **/559      RmrkPropertyValueIsTooLong: AugmentedError<ApiType>;560      /**561       * Something went wrong when decoding encoded data from the storage.562       * Perhaps, there was a wrong key supplied for the type, or the data was improperly stored.563       **/564      UnableToDecodeRmrkData: AugmentedError<ApiType>;565      /**566       * Generic error567       **/568      [key: string]: AugmentedError<ApiType>;569    };570    rmrkEquip: {571      /**572       * Base collection linked to this ID does not exist.573       **/574      BaseDoesntExist: AugmentedError<ApiType>;575      /**576       * No Theme named "default" is associated with the Base.577       **/578      NeedsDefaultThemeFirst: AugmentedError<ApiType>;579      /**580       * Could not find an ID for a Base collection. It is likely there were too many collections created on the chain, causing an overflow.581       **/582      NoAvailableBaseId: AugmentedError<ApiType>;583      /**584       * Could not find a suitable ID for a Part, likely too many Part tokens were created in the Base, causing an overflow585       **/586      NoAvailablePartId: AugmentedError<ApiType>;587      /**588       * Cannot assign equippables to a fixed Part.589       **/590      NoEquippableOnFixedPart: AugmentedError<ApiType>;591      /**592       * Part linked to this ID does not exist.593       **/594      PartDoesntExist: AugmentedError<ApiType>;595      /**596       * No permission to perform action.597       **/598      PermissionError: AugmentedError<ApiType>;599      /**600       * Generic error601       **/602      [key: string]: AugmentedError<ApiType>;603    };604    scheduler: {605      /**606       * Failed to schedule a call607       **/608      FailedToSchedule: AugmentedError<ApiType>;609      /**610       * Cannot find the scheduled call.611       **/612      NotFound: AugmentedError<ApiType>;613      /**614       * Reschedule failed because it does not change scheduled time.615       **/616      RescheduleNoChange: AugmentedError<ApiType>;617      /**618       * Given target block number is in the past.619       **/620      TargetBlockNumberInPast: AugmentedError<ApiType>;621      /**622       * Generic error623       **/624      [key: string]: AugmentedError<ApiType>;625    };626    structure: {627      /**628       * While nesting, reached the breadth limit of nesting, exceeding the provided budget.629       **/630      BreadthLimit: AugmentedError<ApiType>;631      /**632       * While nesting, reached the depth limit of nesting, exceeding the provided budget.633       **/634      DepthLimit: AugmentedError<ApiType>;635      /**636       * While nesting, encountered an already checked account, detecting a loop.637       **/638      OuroborosDetected: AugmentedError<ApiType>;639      /**640       * Couldn't find the token owner that is itself a token.641       **/642      TokenNotFound: AugmentedError<ApiType>;643      /**644       * Generic error645       **/646      [key: string]: AugmentedError<ApiType>;647    };648    sudo: {649      /**650       * Sender must be the Sudo account651       **/652      RequireSudo: AugmentedError<ApiType>;653      /**654       * Generic error655       **/656      [key: string]: AugmentedError<ApiType>;657    };658    system: {659      /**660       * The origin filter prevent the call to be dispatched.661       **/662      CallFiltered: AugmentedError<ApiType>;663      /**664       * Failed to extract the runtime version from the new runtime.665       * 666       * Either calling `Core_version` or decoding `RuntimeVersion` failed.667       **/668      FailedToExtractRuntimeVersion: AugmentedError<ApiType>;669      /**670       * The name of specification does not match between the current runtime671       * and the new runtime.672       **/673      InvalidSpecName: AugmentedError<ApiType>;674      /**675       * Suicide called when the account has non-default composite data.676       **/677      NonDefaultComposite: AugmentedError<ApiType>;678      /**679       * There is a non-zero reference count preventing the account from being purged.680       **/681      NonZeroRefCount: AugmentedError<ApiType>;682      /**683       * The specification version is not allowed to decrease between the current runtime684       * and the new runtime.685       **/686      SpecVersionNeedsToIncrease: AugmentedError<ApiType>;687      /**688       * Generic error689       **/690      [key: string]: AugmentedError<ApiType>;691    };692    treasury: {693      /**694       * The spend origin is valid but the amount it is allowed to spend is lower than the695       * amount to be spent.696       **/697      InsufficientPermission: AugmentedError<ApiType>;698      /**699       * Proposer's balance is too low.700       **/701      InsufficientProposersBalance: AugmentedError<ApiType>;702      /**703       * No proposal or bounty at that index.704       **/705      InvalidIndex: AugmentedError<ApiType>;706      /**707       * Proposal has not been approved.708       **/709      ProposalNotApproved: AugmentedError<ApiType>;710      /**711       * Too many approvals in the queue.712       **/713      TooManyApprovals: AugmentedError<ApiType>;714      /**715       * Generic error716       **/717      [key: string]: AugmentedError<ApiType>;718    };719    unique: {720      /**721       * Decimal_points parameter must be lower than [`up_data_structs::MAX_DECIMAL_POINTS`].722       **/723      CollectionDecimalPointLimitExceeded: AugmentedError<ApiType>;724      /**725       * This address is not set as sponsor, use setCollectionSponsor first.726       **/727      ConfirmUnsetSponsorFail: AugmentedError<ApiType>;728      /**729       * Length of items properties must be greater than 0.730       **/731      EmptyArgument: AugmentedError<ApiType>;732      /**733       * Repertition is only supported by refungible collection.734       **/735      RepartitionCalledOnNonRefungibleCollection: AugmentedError<ApiType>;736      /**737       * Generic error738       **/739      [key: string]: AugmentedError<ApiType>;740    };741    vesting: {742      /**743       * The vested transfer amount is too low744       **/745      AmountLow: AugmentedError<ApiType>;746      /**747       * Insufficient amount of balance to lock748       **/749      InsufficientBalanceToLock: AugmentedError<ApiType>;750      /**751       * Failed because the maximum vesting schedules was exceeded752       **/753      MaxVestingSchedulesExceeded: AugmentedError<ApiType>;754      /**755       * This account have too many vesting schedules756       **/757      TooManyVestingSchedules: AugmentedError<ApiType>;758      /**759       * Vesting period is zero760       **/761      ZeroVestingPeriod: AugmentedError<ApiType>;762      /**763       * Number of vests is zero764       **/765      ZeroVestingPeriodCount: AugmentedError<ApiType>;766      /**767       * Generic error768       **/769      [key: string]: AugmentedError<ApiType>;770    };771    xcmpQueue: {772      /**773       * Bad overweight index.774       **/775      BadOverweightIndex: AugmentedError<ApiType>;776      /**777       * Bad XCM data.778       **/779      BadXcm: AugmentedError<ApiType>;780      /**781       * Bad XCM origin.782       **/783      BadXcmOrigin: AugmentedError<ApiType>;784      /**785       * Failed to send XCM message.786       **/787      FailedToSend: AugmentedError<ApiType>;788      /**789       * Provided weight is possibly not enough to execute the message.790       **/791      WeightOverLimit: AugmentedError<ApiType>;792      /**793       * Generic error794       **/795      [key: string]: AugmentedError<ApiType>;796    };797  } // AugmentedErrors798} // declare module
modifiedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -335,7 +335,7 @@
        * 
        * Currently used to store RMRK data.
        **/
-      tokenAuxProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: UpDataStructsPropertyScope | 'None' | 'Rmrk' | 'Eth' | number | Uint8Array, arg4: Bytes | string | Uint8Array) => Observable<Option<Bytes>>, [u32, u32, UpDataStructsPropertyScope, Bytes]> & QueryableStorageEntry<ApiType, [u32, u32, UpDataStructsPropertyScope, Bytes]>;
+      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]>;
       /**
        * Used to enumerate token's children.
        **/
modifiedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -35,6 +35,28 @@
 
 declare module '@polkadot/rpc-core/types/jsonrpc' {
   interface RpcInterface {
+    appPromotion: {
+      /**
+       * Returns the total amount of unstaked tokens
+       **/
+      pendingUnstake: AugmentedRpc<(staker?: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
+      /**
+       * Returns the total amount of unstaked tokens per block
+       **/
+      pendingUnstakePerBlock: AugmentedRpc<(staker: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<ITuple<[u32, u128]>>>>;
+      /**
+       * Returns the total amount of staked tokens
+       **/
+      totalStaked: AugmentedRpc<(staker?: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
+      /**
+       * Returns the total amount of staked tokens per block when staked
+       **/
+      totalStakedPerBlock: AugmentedRpc<(staker: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<ITuple<[u32, u128]>>>>;
+      /**
+       * Return the total amount locked by staking tokens
+       **/
+      totalStakingLocked: AugmentedRpc<(staker: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
+    };
     author: {
       /**
        * Returns true if the keystore has private keys for the given public key and key type.
@@ -702,15 +724,7 @@
        * 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>>>;
-      /**
-       * Returns the total amount of unstaked tokens
-       **/
-      pendingUnstake: AugmentedRpc<(staker?: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
       /**
-       * Returns the total amount of unstaked tokens per block
-       **/
-      pendingUnstakePerBlock: AugmentedRpc<(staker: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<ITuple<[u32, u128]>>>>;
-      /**
        * 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>>>;
@@ -746,18 +760,6 @@
        * 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>>>;
-      /**
-       * Returns the total amount of staked tokens
-       **/
-      totalStaked: AugmentedRpc<(staker?: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
-      /**
-       * Returns the total amount of staked tokens per block when staked
-       **/
-      totalStakedPerBlock: AugmentedRpc<(staker: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<ITuple<[u32, u128]>>>>;
-      /**
-       * Return the total amount locked by staking tokens
-       **/
-      totalStakingLocked: AugmentedRpc<(staker: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u128>>;
       /**
        * Get the amount of distinctive tokens present in a collection
        **/
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -181,8 +181,21 @@
       [key: string]: SubmittableExtrinsicFunction<ApiType>;
     };
     evmMigration: {
+      /**
+       * Start contract migration, inserts contract stub at target address,
+       * and marks account as pending, allowing to insert storage
+       **/
       begin: AugmentedSubmittable<(address: H160 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [H160]>;
+      /**
+       * Finish contract migration, allows it to be called.
+       * It is not possible to alter contract storage via [`Self::set_data`]
+       * after this call.
+       **/
       finish: AugmentedSubmittable<(address: H160 | string | Uint8Array, code: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [H160, Bytes]>;
+      /**
+       * Insert items into contract storage, this method can be called
+       * multiple times
+       **/
       setData: AugmentedSubmittable<(address: H160 | string | Uint8Array, data: Vec<ITuple<[H256, H256]>> | ([H256 | string | Uint8Array, H256 | string | Uint8Array])[]) => SubmittableExtrinsic<ApiType>, [H160, Vec<ITuple<[H256, H256]>>]>;
       /**
        * Generic tx
@@ -372,7 +385,7 @@
       stopAppPromotion: AugmentedSubmittable<() => SubmittableExtrinsic<ApiType>, []>;
       stopSponsoringCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
       stopSponsoringContract: AugmentedSubmittable<(contractId: H160 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [H160]>;
-      unstake: AugmentedSubmittable<(amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u128]>;
+      unstake: AugmentedSubmittable<() => SubmittableExtrinsic<ApiType>, []>;
       /**
        * Generic tx
        **/
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -822,9 +822,6 @@
     readonly amount: u128;
   } & Struct;
   readonly isUnstake: boolean;
-  readonly asUnstake: {
-    readonly amount: u128;
-  } & Struct;
   readonly isSponsorCollection: boolean;
   readonly asSponsorCollection: {
     readonly collectionId: u32;
@@ -2639,8 +2636,7 @@
 export interface UpDataStructsPropertyScope extends Enum {
   readonly isNone: boolean;
   readonly isRmrk: boolean;
-  readonly isEth: boolean;
-  readonly type: 'None' | 'Rmrk' | 'Eth';
+  readonly type: 'None' | 'Rmrk';
 }
 
 /** @name UpDataStructsRpcCollection */
modifiedtests/src/interfaces/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/definitions.ts
+++ b/tests/src/interfaces/definitions.ts
@@ -15,5 +15,6 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 export {default as unique} from './unique/definitions';
+export {default as appPromotion} from './appPromotion/definitions';
 export {default as rmrk} from './rmrk/definitions';
 export {default as default} from './default/definitions';
\ No newline at end of file
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -2467,9 +2467,7 @@
       stake: {
         amount: 'u128',
       },
-      unstake: {
-        amount: 'u128',
-      },
+      unstake: 'Null',
       sponsor_collection: {
         collectionId: 'u32',
       },
@@ -3078,7 +3076,7 @@
    * Lookup403: up_data_structs::PropertyScope
    **/
   UpDataStructsPropertyScope: {
-    _enum: ['None', 'Rmrk', 'Eth']
+    _enum: ['None', 'Rmrk']
   },
   /**
    * Lookup405: pallet_nonfungible::pallet::Error<T>
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -2675,9 +2675,6 @@
       readonly amount: u128;
     } & Struct;
     readonly isUnstake: boolean;
-    readonly asUnstake: {
-      readonly amount: u128;
-    } & Struct;
     readonly isSponsorCollection: boolean;
     readonly asSponsorCollection: {
       readonly collectionId: u32;
@@ -3238,8 +3235,7 @@
   interface UpDataStructsPropertyScope extends Enum {
     readonly isNone: boolean;
     readonly isRmrk: boolean;
-    readonly isEth: boolean;
-    readonly type: 'None' | 'Rmrk' | 'Eth';
+    readonly type: 'None' | 'Rmrk';
   }
 
   /** @name PalletNonfungibleError (405) */
modifiedtests/src/interfaces/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types.ts
+++ b/tests/src/interfaces/types.ts
@@ -2,5 +2,6 @@
 /* eslint-disable */
 
 export * from './unique/types';
+export * from './appPromotion/types';
 export * from './rmrk/types';
 export * from './default/types';
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/definitions.ts
+++ b/tests/src/interfaces/unique/definitions.ts
@@ -175,30 +175,5 @@
       [collectionParam, tokenParam], 
       'Option<u128>',
     ),
-    totalStaked: fun(
-      'Returns the total amount of staked tokens',
-      [{name: 'staker', type: CROSS_ACCOUNT_ID_TYPE, isOptional: true}],
-      'u128',
-    ),
-    totalStakedPerBlock: fun(
-      'Returns the total amount of staked tokens per block when staked',
-      [crossAccountParam('staker')],
-      'Vec<(u32, u128)>',
-    ),
-    totalStakingLocked: fun(
-      'Return the total amount locked by staking tokens',
-      [crossAccountParam('staker')],
-      'u128',
-    ),
-    pendingUnstake: fun(
-      'Returns the total amount of unstaked tokens',
-      [{name: 'staker', type: CROSS_ACCOUNT_ID_TYPE, isOptional: true}],
-      'u128',
-    ),
-    pendingUnstakePerBlock: fun(
-      'Returns the total amount of unstaked tokens per block',
-      [crossAccountParam('staker')],
-      'Vec<(u32, u128)>',
-    ),
   },
 };
modifiedtests/src/substrate/substrate-api.tsdiffbeforeafterboth
--- a/tests/src/substrate/substrate-api.ts
+++ b/tests/src/substrate/substrate-api.ts
@@ -42,6 +42,7 @@
     },
     rpc: {
       unique: defs.unique.rpc,
+      appPromotion: defs.appPromotion.rpc,
       rmrk: defs.rmrk.rpc,
       eth: {
         feeHistory: {
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -35,6 +35,7 @@
       },
       rpc: {
         unique: defs.unique.rpc,
+        appPromotion: defs.appPromotion.rpc,
         rmrk: defs.rmrk.rpc,
         eth: {
           feeHistory: {
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -2027,24 +2027,24 @@
   }
 
   async getTotalStaked(address?: ICrossAccountId): Promise<bigint> {
-    if (address) return (await this.helper.callRpc('api.rpc.unique.totalStaked', [address])).toBigInt();
-    return (await this.helper.callRpc('api.rpc.unique.totalStaked')).toBigInt();
+    if (address) return (await this.helper.callRpc('api.rpc.appPromotion.totalStaked', [address])).toBigInt();
+    return (await this.helper.callRpc('api.rpc.appPromotion.totalStaked')).toBigInt();
   }
 
   async getTotalStakingLocked(address: ICrossAccountId): Promise<bigint> {
-    return (await this.helper.callRpc('api.rpc.unique.totalStakingLocked', [address])).toBigInt();
+    return (await this.helper.callRpc('api.rpc.appPromotion.totalStakingLocked', [address])).toBigInt();
   }
 
   async getTotalStakedPerBlock(address: ICrossAccountId): Promise<bigint[][]> {
-    return (await this.helper.callRpc('api.rpc.unique.totalStakedPerBlock', [address])).map(([block, amount]: any[]) => [block.toBigInt(), amount.toBigInt()]);
+    return (await this.helper.callRpc('api.rpc.appPromotion.totalStakedPerBlock', [address])).map(([block, amount]: any[]) => [block.toBigInt(), amount.toBigInt()]);
   }
 
   async getPendingUnstake(address: ICrossAccountId): Promise<bigint> {
-    return (await this.helper.callRpc('api.rpc.unique.pendingUnstake', [address])).toBigInt();
+    return (await this.helper.callRpc('api.rpc.appPromotion.pendingUnstake', [address])).toBigInt();
   }
   
   async getPendingUnstakePerBlock(address: ICrossAccountId): Promise<bigint[][]> {
-    return (await this.helper.callRpc('api.rpc.unique.pendingUnstakePerBlock', [address])).map(([block, amount]: any[]) => [block.toBigInt(), amount.toBigInt()]);
+    return (await this.helper.callRpc('api.rpc.appPromotion.pendingUnstakePerBlock', [address])).map(([block, amount]: any[]) => [block.toBigInt(), amount.toBigInt()]);
   }
 }