difftreelog
refactor drop rmrk compatibility layer
in: master
85 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5543,8 +5543,6 @@
"pallet-nonfungible",
"pallet-randomness-collective-flip",
"pallet-refungible",
- "pallet-rmrk-core",
- "pallet-rmrk-equip",
"pallet-session",
"pallet-structure",
"pallet-sudo",
@@ -5561,7 +5559,6 @@
"parity-scale-codec",
"polkadot-parachain",
"precompile-utils-macro",
- "rmrk-rpc",
"scale-info",
"serde",
"smallvec",
@@ -6772,43 +6769,6 @@
"parity-scale-codec",
"scale-info",
"sp-core",
- "sp-runtime",
- "sp-std",
- "up-data-structs",
-]
-
-[[package]]
-name = "pallet-rmrk-core"
-version = "0.1.2"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-common",
- "pallet-evm",
- "pallet-nonfungible",
- "pallet-structure",
- "parity-scale-codec",
- "rmrk-traits",
- "scale-info",
- "sp-runtime",
- "sp-std",
- "up-data-structs",
-]
-
-[[package]]
-name = "pallet-rmrk-equip"
-version = "0.1.2"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-common",
- "pallet-evm",
- "pallet-nonfungible",
- "pallet-rmrk-core",
- "parity-scale-codec",
- "scale-info",
"sp-runtime",
"sp-std",
"up-data-structs",
@@ -9009,8 +8969,6 @@
"pallet-nonfungible",
"pallet-randomness-collective-flip",
"pallet-refungible",
- "pallet-rmrk-core",
- "pallet-rmrk-equip",
"pallet-session",
"pallet-structure",
"pallet-sudo",
@@ -9026,7 +8984,6 @@
"parity-scale-codec",
"polkadot-parachain",
"precompile-utils-macro",
- "rmrk-rpc",
"scale-info",
"serde",
"smallvec",
@@ -9415,26 +9372,6 @@
]
[[package]]
-name = "rmrk-rpc"
-version = "0.0.2"
-dependencies = [
- "parity-scale-codec",
- "rmrk-traits",
- "sp-api",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "rmrk-traits"
-version = "0.1.0"
-dependencies = [
- "parity-scale-codec",
- "scale-info",
- "serde",
-]
-
-[[package]]
name = "rocksdb"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -13026,7 +12963,6 @@
"pallet-evm",
"parity-scale-codec",
"quartz-runtime",
- "rmrk-rpc",
"sc-client-api",
"sc-executor",
"sc-rpc-api",
@@ -13132,7 +13068,6 @@
"polkadot-primitives",
"polkadot-service",
"quartz-runtime",
- "rmrk-rpc",
"sc-basic-authorship",
"sc-chain-spec",
"sc-cli",
@@ -13186,7 +13121,6 @@
"fp-storage",
"jsonrpsee",
"pallet-transaction-payment-rpc",
- "rmrk-rpc",
"sc-client-api",
"sc-finality-grandpa",
"sc-network",
@@ -13265,8 +13199,6 @@
"pallet-nonfungible",
"pallet-randomness-collective-flip",
"pallet-refungible",
- "pallet-rmrk-core",
- "pallet-rmrk-equip",
"pallet-session",
"pallet-structure",
"pallet-sudo",
@@ -13282,7 +13214,6 @@
"parity-scale-codec",
"polkadot-parachain",
"precompile-utils-macro",
- "rmrk-rpc",
"scale-info",
"serde",
"smallvec",
@@ -13361,7 +13292,6 @@
"frame-support",
"pallet-evm",
"parity-scale-codec",
- "rmrk-traits",
"scale-info",
"serde",
"sp-core",
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -43,9 +43,6 @@
pallet-inflation = { path = "pallets/inflation", default-features = false }
pallet-maintenance = { default-features = false, path = "pallets/maintenance" }
pallet-nonfungible = { default-features = false, path = "pallets/nonfungible" }
-pallet-proxy-rmrk-core = { default-features = false, path = "pallets/proxy-rmrk-core", package = "pallet-rmrk-core" }
-pallet-proxy-rmrk-equip = { default-features = false, path = "pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }
-rmrk-traits = { default-features = false, path = "primitives/rmrk-traits" }
pallet-refungible = { default-features = false, path = "pallets/refungible" }
pallet-structure = { default-features = false, path = "pallets/structure" }
pallet-unique = { path = "pallets/unique", default-features = false }
@@ -53,7 +50,6 @@
pallet-test-utils = { default-features = false, path = "test-pallets/utils" }
pallet-app-promotion = { path = "pallets/app-promotion", default-features = false }
app-promotion-rpc = { path = "primitives/app_promotion_rpc", default-features = false }
-rmrk-rpc = { path = "primitives/rmrk-rpc", default-features = false }
# Unique: Runtimes
unique-runtime = { path = "runtime/unique" }
Makefilediffbeforeafterboth--- a/Makefile
+++ b/Makefile
@@ -121,14 +121,6 @@
bench-scheduler:
make _bench PALLET=unique-scheduler-v2 PALLET_DIR=scheduler-v2
-.PHONY: bench-rmrk-core
-bench-rmrk-core:
- make _bench PALLET=proxy-rmrk-core
-
-.PHONY: bench-rmrk-equip
-bench-rmrk-equip:
- make _bench PALLET=proxy-rmrk-equip
-
.PHONY: bench-foreign-assets
bench-foreign-assets:
make _bench PALLET=foreign-assets
@@ -146,7 +138,7 @@
make _bench PALLET=app-promotion PALLET_DIR=app-promotion
.PHONY: bench
-# Disabled: bench-scheduler, bench-collator-selection, bench-identity, bench-rmrk-core, bench-rmrk-equip
+# Disabled: bench-scheduler, bench-collator-selection, bench-identity
bench: bench-common bench-evm-migration bench-unique bench-structure bench-fungible bench-refungible bench-nonfungible bench-configuration bench-foreign-assets
.PHONY: check
client/rpc/Cargo.tomldiffbeforeafterboth--- a/client/rpc/Cargo.toml
+++ b/client/rpc/Cargo.toml
@@ -14,7 +14,6 @@
codec = { workspace = true, package = "parity-scale-codec" }
app-promotion-rpc = { workspace = true }
-rmrk-rpc = { workspace = true }
up-common = { workspace = true }
up-data-structs = { workspace = true }
up-pov-estimate-rpc = { workspace = true, optional = true }
client/rpc/src/lib.rsdiffbeforeafterboth--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -17,7 +17,7 @@
// Original License
use std::sync::Arc;
-use codec::{Decode, Encode};
+use codec::Decode;
use jsonrpsee::{
core::{RpcResult as Result},
proc_macros::rpc,
@@ -32,15 +32,8 @@
use sp_blockchain::HeaderBackend;
use up_rpc::UniqueApi as UniqueRuntimeApi;
use app_promotion_rpc::AppPromotionApi as AppPromotionRuntimeApi;
-
-// RMRK
-use rmrk_rpc::RmrkApi as RmrkRuntimeApi;
-use up_data_structs::{
- RmrkCollectionId, RmrkNftId, RmrkBaseId, RmrkNftChild, RmrkThemeName, RmrkResourceId,
-};
pub use app_promotion_unique_rpc::AppPromotionApiServer;
-pub use rmrk_unique_rpc::RmrkApiServer;
#[cfg(feature = "pov-estimate")]
pub mod pov_estimate;
@@ -300,129 +293,7 @@
) -> Result<Vec<(BlockNumber, String)>>;
}
}
-
-mod rmrk_unique_rpc {
- use super::*;
-
- #[rpc(server)]
- #[async_trait]
- pub trait RmrkApi<
- BlockHash,
- AccountId,
- CollectionInfo,
- NftInfo,
- ResourceInfo,
- PropertyInfo,
- BaseInfo,
- PartType,
- Theme,
- >
- {
- /// Get the latest created collection ID.
- #[method(name = "rmrk_lastCollectionIdx")]
- fn last_collection_idx(&self, at: Option<BlockHash>) -> Result<RmrkCollectionId>;
-
- /// Get collection info by ID.
- #[method(name = "rmrk_collectionById")]
- fn collection_by_id(
- &self,
- id: RmrkCollectionId,
- at: Option<BlockHash>,
- ) -> Result<Option<CollectionInfo>>;
-
- /// Get NFT info by collection and NFT IDs.
- #[method(name = "rmrk_nftById")]
- fn nft_by_id(
- &self,
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- at: Option<BlockHash>,
- ) -> Result<Option<NftInfo>>;
-
- /// Get tokens owned by an account in a collection.
- #[method(name = "rmrk_accountTokens")]
- fn account_tokens(
- &self,
- account_id: AccountId,
- collection_id: RmrkCollectionId,
- at: Option<BlockHash>,
- ) -> Result<Vec<RmrkNftId>>;
-
- /// Get tokens nested in an NFT - its direct children (not the children's children).
- #[method(name = "rmrk_nftChildren")]
- fn nft_children(
- &self,
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- at: Option<BlockHash>,
- ) -> Result<Vec<RmrkNftChild>>;
-
- /// Get collection properties, created by the user - not the proxy-specific properties.
- #[method(name = "rmrk_collectionProperties")]
- fn collection_properties(
- &self,
- collection_id: RmrkCollectionId,
- filter_keys: Option<Vec<String>>,
- at: Option<BlockHash>,
- ) -> Result<Vec<PropertyInfo>>;
-
- /// Get NFT properties, created by the user - not the proxy-specific properties.
- #[method(name = "rmrk_nftProperties")]
- fn nft_properties(
- &self,
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- filter_keys: Option<Vec<String>>,
- at: Option<BlockHash>,
- ) -> Result<Vec<PropertyInfo>>;
-
- /// Get data of resources of an NFT.
- #[method(name = "rmrk_nftResources")]
- fn nft_resources(
- &self,
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- at: Option<BlockHash>,
- ) -> Result<Vec<ResourceInfo>>;
- /// Get the priority of a resource in an NFT.
- #[method(name = "rmrk_nftResourcePriority")]
- fn nft_resource_priority(
- &self,
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- resource_id: RmrkResourceId,
- at: Option<BlockHash>,
- ) -> Result<Option<u32>>;
-
- /// Get base info by its ID.
- #[method(name = "rmrk_base")]
- fn base(&self, base_id: RmrkBaseId, at: Option<BlockHash>) -> Result<Option<BaseInfo>>;
-
- /// Get all parts of a base.
- #[method(name = "rmrk_baseParts")]
- fn base_parts(&self, base_id: RmrkBaseId, at: Option<BlockHash>) -> Result<Vec<PartType>>;
-
- /// Get the theme names belonging to a base.
- #[method(name = "rmrk_themeNames")]
- fn theme_names(
- &self,
- base_id: RmrkBaseId,
- at: Option<BlockHash>,
- ) -> Result<Vec<RmrkThemeName>>;
-
- /// Get theme info, including properties, optionally limited to the provided keys.
- #[method(name = "rmrk_themes")]
- fn theme(
- &self,
- base_id: RmrkBaseId,
- theme_name: String,
- filter_keys: Option<Vec<String>>,
- at: Option<BlockHash>,
- ) -> Result<Option<Theme>>;
- }
-}
-
#[macro_export]
macro_rules! define_struct_for_server_api {
($name:ident { $($arg:ident: $arg_ty:ty),+ $(,)? }) => {
@@ -454,12 +325,6 @@
}
}
-define_struct_for_server_api! {
- Rmrk {
- client: Arc<Client>
- }
-}
-
macro_rules! pass_method {
(
$method_name:ident(
@@ -508,12 +373,6 @@
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>
};
}
@@ -627,94 +486,6 @@
.into_iter()
.map(|(b, a)| (b, a.to_string()))
.collect::<Vec<_>>(), app_promotion_api);
-}
-
-#[allow(deprecated)]
-impl<
- C,
- Block,
- AccountId,
- CollectionInfo,
- NftInfo,
- ResourceInfo,
- PropertyInfo,
- BaseInfo,
- PartType,
- Theme,
- >
- rmrk_unique_rpc::RmrkApiServer<
- <Block as BlockT>::Hash,
- AccountId,
- CollectionInfo,
- NftInfo,
- ResourceInfo,
- PropertyInfo,
- BaseInfo,
- PartType,
- Theme,
- > for Rmrk<C, Block>
-where
- C: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
- C::Api: RmrkRuntimeApi<
- Block,
- AccountId,
- CollectionInfo,
- NftInfo,
- ResourceInfo,
- PropertyInfo,
- BaseInfo,
- PartType,
- Theme,
- >,
- AccountId: Decode + Encode,
- CollectionInfo: Decode,
- NftInfo: Decode,
- ResourceInfo: Decode,
- PropertyInfo: Decode,
- BaseInfo: Decode,
- PartType: Decode,
- Theme: Decode,
- Block: BlockT,
-{
- pass_method!(last_collection_idx() -> RmrkCollectionId, rmrk_api);
- pass_method!(collection_by_id(id: RmrkCollectionId) -> Option<CollectionInfo>, rmrk_api);
- pass_method!(nft_by_id(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Option<NftInfo>, rmrk_api);
- pass_method!(account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Vec<RmrkNftId>, rmrk_api);
- pass_method!(nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Vec<RmrkNftChild>, rmrk_api);
- pass_method!(
- collection_properties(
- collection_id: RmrkCollectionId,
-
- #[map(|keys| string_keys_to_bytes_keys(keys))]
- filter_keys: Option<Vec<String>>
- ) -> Vec<PropertyInfo>,
- rmrk_api
- );
- pass_method!(
- nft_properties(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
-
- #[map(|keys| string_keys_to_bytes_keys(keys))]
- filter_keys: Option<Vec<String>>
- ) -> Vec<PropertyInfo>,
- rmrk_api
- );
- pass_method!(nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Vec<ResourceInfo>, rmrk_api);
- pass_method!(nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Option<u32>, rmrk_api);
- pass_method!(base(base_id: RmrkBaseId) -> Option<BaseInfo>, rmrk_api);
- pass_method!(base_parts(base_id: RmrkBaseId) -> Vec<PartType>, rmrk_api);
- pass_method!(theme_names(base_id: RmrkBaseId) -> Vec<RmrkThemeName>, rmrk_api);
- pass_method!(
- theme(
- base_id: RmrkBaseId,
-
- #[map(|n| n.into_bytes())]
- theme_name: String,
-
- #[map(|keys| string_keys_to_bytes_keys(keys))]
- filter_keys: Option<Vec<String>>
- ) -> Option<Theme>, rmrk_api);
}
fn string_keys_to_bytes_keys(keys: Option<Vec<String>>) -> Option<Vec<Vec<u8>>> {
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -89,7 +89,6 @@
fp-rpc = { workspace = true }
app-promotion-rpc = { workspace = true }
-rmrk-rpc = { workspace = true }
uc-rpc = { workspace = true }
unique-rpc = { workspace = true }
up-pov-estimate-rpc = { workspace = true }
node/cli/src/service.rsdiffbeforeafterboth--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -71,12 +71,6 @@
#[cfg(feature = "pov-estimate")]
use crate::chain_spec::RuntimeIdentification;
-// RMRK
-use up_data_structs::{
- RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
- RmrkPartType, RmrkTheme,
-};
-
/// Unique native executor instance.
#[cfg(feature = "unique-runtime")]
pub struct UniqueRuntimeExecutor;
@@ -403,17 +397,7 @@
+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
+ up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
+ app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
- + rmrk_rpc::RmrkApi<
- Block,
- AccountId,
- RmrkCollectionInfo<AccountId>,
- RmrkInstanceInfo<AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<AccountId>,
- RmrkPartType,
- RmrkTheme,
- > + up_pov_estimate_rpc::PovEstimateApi<Block>
+ + up_pov_estimate_rpc::PovEstimateApi<Block>
+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+ sp_api::Metadata<Block>
+ sp_offchain::OffchainWorkerApi<Block>
@@ -732,17 +716,7 @@
+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
+ up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
+ app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
- + rmrk_rpc::RmrkApi<
- Block,
- AccountId,
- RmrkCollectionInfo<AccountId>,
- RmrkInstanceInfo<AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<AccountId>,
- RmrkPartType,
- RmrkTheme,
- > + up_pov_estimate_rpc::PovEstimateApi<Block>
+ + up_pov_estimate_rpc::PovEstimateApi<Block>
+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+ sp_api::Metadata<Block>
+ sp_offchain::OffchainWorkerApi<Block>
@@ -882,17 +856,7 @@
+ sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
+ up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
+ app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>
- + rmrk_rpc::RmrkApi<
- Block,
- AccountId,
- RmrkCollectionInfo<AccountId>,
- RmrkInstanceInfo<AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<AccountId>,
- RmrkPartType,
- RmrkTheme,
- > + up_pov_estimate_rpc::PovEstimateApi<Block>
+ + up_pov_estimate_rpc::PovEstimateApi<Block>
+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+ sp_api::Metadata<Block>
+ sp_offchain::OffchainWorkerApi<Block>
node/rpc/Cargo.tomldiffbeforeafterboth--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -33,7 +33,6 @@
fp-storage = { workspace = true }
app-promotion-rpc = { workspace = true }
-rmrk-rpc = { workspace = true }
serde = { workspace = true }
uc-rpc = { workspace = true }
up-common = { workspace = true }
node/rpc/src/lib.rsdiffbeforeafterboth--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -42,12 +42,6 @@
use up_common::types::opaque::*;
-// RMRK
-use up_data_structs::{
- RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
- RmrkPartType, RmrkTheme,
-};
-
#[cfg(feature = "pov-estimate")]
type FullBackend = sc_service::TFullBackend<Block>;
@@ -164,17 +158,6 @@
<R as RuntimeInstance>::CrossAccountId,
AccountId,
>,
- C::Api: rmrk_rpc::RmrkApi<
- Block,
- AccountId,
- RmrkCollectionInfo<AccountId>,
- RmrkInstanceInfo<AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<AccountId>,
- RmrkPartType,
- RmrkTheme,
- >,
C::Api: up_pov_estimate_rpc::PovEstimateApi<Block>,
B: sc_client_api::Backend<Block> + Send + Sync + 'static,
B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
@@ -193,9 +176,6 @@
#[cfg(not(feature = "unique-runtime"))]
use uc_rpc::{AppPromotionApiServer, AppPromotion};
- #[cfg(not(feature = "unique-runtime"))]
- use uc_rpc::{RmrkApiServer, Rmrk};
-
#[cfg(feature = "pov-estimate")]
use uc_rpc::pov_estimate::{PovEstimateApiServer, PovEstimate};
@@ -267,9 +247,6 @@
#[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())?;
#[cfg(feature = "pov-estimate")]
io.merge(
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -33,7 +33,7 @@
};
use crate::{
- Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf, eth, weights::WeightInfo,
+ Pallet, CollectionHandle, Config, CollectionProperties, eth, SelfWeightOf, weights::WeightInfo,
};
frontier_contract! {
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -109,15 +109,6 @@
TokenData,
TrySetProperty,
PropertyScope,
- // RMRK
- RmrkCollectionInfo,
- RmrkInstanceInfo,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo,
- RmrkPartType,
- RmrkBoundedTheme,
- RmrkNftChild,
CollectionPermissions,
};
use up_pov_estimate_rpc::PovInfo;
@@ -898,15 +889,6 @@
PhantomType<(
TokenData<T::CrossAccountId>,
RpcCollection<T::AccountId>,
- // RMRK
- RmrkCollectionInfo<T::AccountId>,
- RmrkInstanceInfo<T::AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<T::AccountId>,
- RmrkPartType,
- RmrkBoundedTheme,
- RmrkNftChild,
// PoV Estimate Info
PovInfo,
)>,
pallets/fungible/src/erc.rsdiffbeforeafterboth--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -38,8 +38,8 @@
use sp_core::{U256, Get};
use crate::{
- Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,
- weights::WeightInfo,
+ Allowance, Balance, Config, FungibleHandle, Pallet, TotalSupply,
+ SelfWeightOf, weights::WeightInfo,
};
frontier_contract! {
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -47,7 +47,7 @@
use crate::{
AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,
- SelfWeightOf, weights::WeightInfo, TokenProperties,
+ TokenProperties, SelfWeightOf, weights::WeightInfo,
};
frontier_contract! {
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -214,7 +214,7 @@
/// usual [`TokenProperties`] due to an unlimited number
/// and separately stored and written-to key-value pairs.
///
- /// Currently used to store RMRK data.
+ /// Currently unused.
#[pallet::storage]
#[pallet::getter(fn token_aux_property)]
pub type TokenAuxProperties<T: Config> = StorageNMap<
pallets/proxy-rmrk-core/CHANGELOG.mddiffbeforeafterboth--- a/pallets/proxy-rmrk-core/CHANGELOG.md
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- bureaucrate goes here -->
-## [v0.1.2] 2022-08-16
-
-### Other changes
-
-- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
-
-- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
-
-- refactor: Remove `#[transactional]` from extrinsics 7fd36cea2f6e00c02c67ccc1de9649ae404efd31
-
-Every extrinsic now runs in transaction implicitly, and
-`#[transactional]` on pallet dispatchable is now meaningless
-
-Upstream-Change: https://github.com/paritytech/substrate/issues/10806
-
-- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
\ No newline at end of file
pallets/proxy-rmrk-core/Cargo.tomldiffbeforeafterboth--- a/pallets/proxy-rmrk-core/Cargo.toml
+++ /dev/null
@@ -1,41 +0,0 @@
-[package]
-edition = "2021"
-license = "GPLv3"
-name = "pallet-rmrk-core"
-version = "0.1.2"
-
-[dependencies]
-# Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
-codec = { workspace = true, package = "parity-scale-codec" }
-
-scale-info = { workspace = true }
-
-frame-benchmarking = { workspace = true, optional = true }
-frame-support = { workspace = true }
-frame-system = { workspace = true }
-pallet-common = { workspace = true }
-pallet-evm = { workspace = true }
-pallet-nonfungible = { workspace = true }
-pallet-structure = { workspace = true }
-rmrk-traits = { workspace = true }
-sp-runtime = { workspace = true }
-sp-std = { workspace = true }
-up-data-structs = { workspace = true }
-
-[features]
-default = ["std"]
-runtime-benchmarks = ['frame-benchmarking', 'frame-support/runtime-benchmarks', 'frame-system/runtime-benchmarks']
-std = [
- "frame-support/std",
- "frame-system/std",
- "pallet-common/std",
- "pallet-evm/std",
- "pallet-nonfungible/std",
- "pallet-structure/std",
- "rmrk-traits/std",
- "sp-runtime/std",
- "sp-std/std",
- "up-data-structs/std",
- 'frame-benchmarking/std',
-]
-try-runtime = ["frame-support/try-runtime"]
pallets/proxy-rmrk-core/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/benchmarking.rs
+++ /dev/null
@@ -1,544 +0,0 @@
-// 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/>.
-
-use sp_std::vec;
-
-use frame_benchmarking::{benchmarks, account};
-use frame_system::RawOrigin;
-use frame_support::{
- traits::{Currency, Get},
- BoundedVec,
-};
-use sp_runtime::Permill;
-
-use up_data_structs::*;
-
-use super::*;
-
-const SEED: u32 = 1;
-
-fn create_data<S: Get<u32>>() -> BoundedVec<u8, S> {
- vec![b'A'; S::get() as usize].try_into().expect("size == S")
-}
-
-fn create_u32_array<S: Get<u32>>() -> BoundedVec<u32, S> {
- vec![0; S::get() as usize].try_into().expect("size == S")
-}
-
-fn create_basic_resource() -> RmrkBasicResource {
- RmrkBasicResource {
- src: Some(create_data()),
- metadata: Some(create_data()),
- license: Some(create_data()),
- thumb: Some(create_data()),
- }
-}
-
-fn create_composable_resource() -> RmrkComposableResource {
- RmrkComposableResource {
- parts: create_u32_array(),
- base: 100,
- src: Some(create_data()),
- metadata: Some(create_data()),
- license: Some(create_data()),
- thumb: Some(create_data()),
- }
-}
-
-fn create_slot_resource() -> RmrkSlotResource {
- RmrkSlotResource {
- base: 100,
- slot: 200,
- src: Some(create_data()),
- metadata: Some(create_data()),
- license: Some(create_data()),
- thumb: Some(create_data()),
- }
-}
-
-fn create_max_resource_types_array<S: Get<u32>>(num: usize) -> BoundedVec<RmrkResourceTypes, S> {
- vec![RmrkResourceTypes::Composable(create_composable_resource()); num]
- .try_into()
- .expect("num <= S")
-}
-
-fn create_max_collection<T: Config>(owner: &T::AccountId) -> DispatchResult {
- <T as pallet_common::Config>::Currency::deposit_creating(
- owner,
- T::CollectionCreationPrice::get(),
- );
-
- let metadata = create_data();
- let max = None;
- let symbol = create_data();
-
- <Pallet<T>>::create_collection(
- RawOrigin::Signed(owner.clone()).into(),
- metadata,
- max,
- symbol,
- )
-}
-
-fn create_nft<T: Config>(owner: &T::AccountId, collection_id: RmrkCollectionId) -> DispatchResult {
- let royalty_recipient = Some(owner.clone());
- let royalty_amount = Some(Permill::from_percent(25));
- let metadata = create_data();
- let transferable = true;
-
- <Pallet<T>>::mint_nft(
- RawOrigin::Signed(owner.clone()).into(),
- None,
- collection_id,
- royalty_recipient,
- royalty_amount,
- metadata,
- transferable,
- None,
- )
-}
-
-struct NftBuilder {
- collection_id: RmrkCollectionId,
- current_nft_id: RmrkNftId,
-}
-
-impl NftBuilder {
- fn new(collection_id: RmrkCollectionId) -> Self {
- Self {
- collection_id,
- current_nft_id: 0,
- }
- }
-
- fn build<T: Config>(&mut self, owner: &T::AccountId) -> Result<RmrkNftId, DispatchError> {
- create_nft::<T>(owner, self.collection_id)?;
- self.current_nft_id += 1;
-
- Ok(self.current_nft_id)
- }
-
- fn build_tower<T: Config>(
- &mut self,
- owner: &T::AccountId,
- height: u32,
- ) -> Result<(RmrkNftId, RmrkNftId), DispatchError> {
- self.build::<T>(owner)?;
-
- let root_nft_id = self.current_nft_id;
- let mut prev_nft_id = root_nft_id;
-
- for _ in 0..height {
- self.build::<T>(owner)?;
-
- let new_owner =
- <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
- self.collection_id,
- prev_nft_id,
- );
-
- <Pallet<T>>::send(
- RawOrigin::Signed(owner.clone()).into(),
- self.collection_id,
- self.current_nft_id,
- new_owner,
- )?;
-
- prev_nft_id = self.current_nft_id;
- }
-
- let deepest_nft_id = self.current_nft_id;
-
- Ok((root_nft_id, deepest_nft_id))
- }
-
- fn build_wide_tree<T: Config>(
- &mut self,
- owner: &T::AccountId,
- width: u32,
- ) -> Result<RmrkNftId, DispatchError> {
- self.build::<T>(owner)?;
-
- let root_nft_id = self.current_nft_id;
-
- let root_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
- self.collection_id,
- root_nft_id,
- );
-
- for _ in 0..width {
- self.build::<T>(owner)?;
-
- <Pallet<T>>::send(
- RawOrigin::Signed(owner.clone()).into(),
- self.collection_id,
- self.current_nft_id,
- root_owner.clone(),
- )?;
- }
-
- Ok(root_nft_id)
- }
-}
-
-benchmarks! {
- create_collection {
- let caller = account("caller", 0, SEED);
- <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
- let metadata = create_data();
- let max = None;
- let symbol = create_data();
- }: _(RawOrigin::Signed(caller), metadata, max, symbol)
-
- destroy_collection {
- let caller = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
- }: _(RawOrigin::Signed(caller), collection_id)
-
- change_collection_issuer {
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let new_owner: T::AccountId = account("new_owner", 0, SEED);
-
- let new_owner_source = T::Lookup::unlookup(new_owner);
- }: _(RawOrigin::Signed(caller), collection_id, new_owner_source)
-
- lock_collection {
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
- }: _(RawOrigin::Signed(caller), collection_id)
-
- mint_nft {
- let b in 0..100;
-
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
- let owner = caller.clone();
-
- let royalty_recipient = Some(caller.clone());
- let royalty_amount = Some(Permill::from_percent(25));
- let metadata = create_data();
- let transferable = true;
- }: _(
- RawOrigin::Signed(caller),
- None,
- collection_id,
- royalty_recipient,
- royalty_amount,
- metadata,
- transferable,
- Some(create_max_resource_types_array(b as usize))
- )
-
- burn_nft {
- let b in 0..200;
-
- let caller: T::AccountId = account("caller", 0, SEED);
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let root_nft_id = nft_builder.build_wide_tree::<T>(&caller, b)?;
- let max_burns = b + 1;
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- root_nft_id,
- max_burns
- )
-
- send {
- let caller: T::AccountId = account("caller", 0, SEED);
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let src_nft_id = nft_builder.build::<T>(&caller)?;
- let (_, target_nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 2)?;
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- src_nft_id,
- <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(collection_id, target_nft_id)
- )
-
- accept_nft {
- let caller: T::AccountId = account("caller", 0, SEED);
- let sender: T::AccountId = account("sender", 0, SEED);
-
- create_max_collection::<T>(&sender)?;
- let src_collection_id = 0;
-
- create_max_collection::<T>(&caller)?;
- let target_collection_id = 1;
-
- let mut src_nft_builder = NftBuilder::new(src_collection_id);
- let src_nft_id = src_nft_builder.build::<T>(&sender)?;
-
- let mut target_nft_builder = NftBuilder::new(target_collection_id);
- let fake_target_nft_id = target_nft_builder.build::<T>(&caller)?;
- let (_, target_nft_id) = target_nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
-
- let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
- target_collection_id,
- fake_target_nft_id
- );
-
- let actual_new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
- target_collection_id,
- target_nft_id
- );
-
- <Pallet<T>>::send(
- RawOrigin::Signed(sender.clone()).into(),
- src_collection_id,
- src_nft_id,
- new_owner,
- )?;
- }: _(
- RawOrigin::Signed(caller),
- src_collection_id,
- src_nft_id,
- actual_new_owner
- )
-
- reject_nft {
- let caller: T::AccountId = account("caller", 0, SEED);
- let sender: T::AccountId = account("sender", 0, SEED);
-
- create_max_collection::<T>(&sender)?;
- let src_collection_id = 0;
-
- create_max_collection::<T>(&caller)?;
- let target_collection_id = 1;
-
- let mut src_nft_builder = NftBuilder::new(src_collection_id);
- let (src_root_nft_id, _) = src_nft_builder.build_tower::<T>(&sender, NESTING_BUDGET - 1)?;
-
- let mut target_nft_builder = NftBuilder::new(target_collection_id);
- let target_nft_id = target_nft_builder.build::<T>(&caller)?;
-
- let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
- target_collection_id,
- target_nft_id
- );
-
- <Pallet<T>>::send(
- RawOrigin::Signed(sender.clone()).into(),
- src_collection_id,
- src_root_nft_id,
- new_owner,
- )?;
- }: _(
- RawOrigin::Signed(caller),
- src_collection_id,
- src_root_nft_id
- )
-
- set_property {
- let caller: T::AccountId = account("caller", 0, SEED);
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
-
- let key = create_data();
- let value = create_data();
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- Some(nft_id),
- key,
- value
- )
-
- set_priority {
- let caller: T::AccountId = account("caller", 0, SEED);
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
- let priorities = create_u32_array();
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nft_id,
- priorities
- )
-
- add_basic_resource {
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
- let resource = create_basic_resource();
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nft_id,
- resource
- )
-
- add_composable_resource {
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
- let resource = create_composable_resource();
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nft_id,
- resource
- )
-
- add_slot_resource {
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
- let resource = create_slot_resource();
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nft_id,
- resource
- )
-
- remove_resource {
- let caller: T::AccountId = account("caller", 0, SEED);
-
- create_max_collection::<T>(&caller)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
- let resource = create_basic_resource();
-
- <Pallet<T>>::add_basic_resource(
- RawOrigin::Signed(caller.clone()).into(),
- collection_id,
- nft_id,
- resource
- )?;
-
- let resource_id = 0;
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nft_id,
- resource_id
- )
-
- accept_resource {
- let caller: T::AccountId = account("caller", 0, SEED);
- let admin: T::AccountId = account("admin", 0, SEED);
-
- create_max_collection::<T>(&admin)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let root_nft_id = 1;
- let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;
- let resource = create_basic_resource();
-
- let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());
-
- <Pallet<T>>::send(
- RawOrigin::Signed(admin.clone()).into(),
- collection_id,
- root_nft_id,
- new_owner,
- )?;
-
- <Pallet<T>>::add_basic_resource(
- RawOrigin::Signed(admin.clone()).into(),
- collection_id,
- nested_nft_id,
- resource
- )?;
-
- let resource_id = 0;
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nested_nft_id,
- resource_id
- )
-
- accept_resource_removal {
- let caller: T::AccountId = account("caller", 0, SEED);
- let admin: T::AccountId = account("admin", 0, SEED);
-
- create_max_collection::<T>(&admin)?;
- let collection_id = 0;
-
- let mut nft_builder = NftBuilder::new(collection_id);
- let root_nft_id = 1;
- let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;
- let resource = create_basic_resource();
-
- <Pallet<T>>::add_basic_resource(
- RawOrigin::Signed(admin.clone()).into(),
- collection_id,
- nested_nft_id,
- resource
- )?;
-
- let resource_id = 0;
-
- let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());
-
- <Pallet<T>>::send(
- RawOrigin::Signed(admin.clone()).into(),
- collection_id,
- root_nft_id,
- new_owner,
- )?;
-
- <Pallet<T>>::remove_resource(
- RawOrigin::Signed(admin).into(),
- collection_id,
- nested_nft_id,
- resource_id
- )?;
- }: _(
- RawOrigin::Signed(caller),
- collection_id,
- nested_nft_id,
- resource_id
- )
-}
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! # RMRK Core Proxy Pallet18//!19//! A pallet used as proxy for RMRK Core (<https://rmrk-team.github.io/rmrk-substrate/#/pallets/rmrk-core>).20//!21//! - [`Config`]22//! - [`Call`]23//! - [`Pallet`]24//!25//! ## Overview26//!27//! The RMRK Core Proxy pallet mirrors the functionality of RMRK Core,28//! binding its externalities to Unique's own underlying structure.29//! It is purposed to mimic RMRK Core exactly, allowing seamless integrations30//! of solutions based on RMRK.31//!32//! RMRK Core itself contains essential functionality for RMRK's nested and33//! multi-resourced NFTs.34//!35//! *Note*, that while RMRK itself is subject to active development and restructuring,36//! the proxy may be caught temporarily out of date.37//!38//! ### What is RMRK?39//!40//! RMRK is a set of NFT standards which compose several "NFT 2.0 lego" primitives.41//! Putting these legos together allows a user to create NFT systems of arbitrary complexity.42//!43//! Meaning, RMRK NFTs are dynamic, able to nest into each other and form a hierarchy,44//! make use of specific changeable and partially shared metadata in the form of resources,45//! and more.46//!47//! Visit RMRK documentation and repositories to learn more:48//! - Docs: <https://docs.rmrk.app/getting-started/>49//! - FAQ: <https://coda.io/@rmrk/faq>50//! - Substrate code repository: <https://github.com/rmrk-team/rmrk-substrate>51//! - RMRK specification repository: <https://github.com/rmrk-team/rmrk-spec>52//!53//! ## Terminology54//!55//! For more information on RMRK, see RMRK's own documentation.56//!57//! ### Intro to RMRK58//!59//! - **Resource:** Additional piece of metadata of an NFT usually serving to add60//! a piece of media on top of the root metadata (NFT's own), be it a different wing61//! on the root template bird or something entirely unrelated.62//!63//! - **Base:** A list of possible "components" - Parts, a combination of which can64//! be appended/equipped to/on an NFT.65//!66//! - **Part:** Something that, together with other Parts, can constitute an NFT.67//! Parts are defined in the Base to which they belong. Parts can be either68//! of the `slot` type or `fixed` type. Slots are intended for equippables.69//! Note that "part of something" and "Part of a Base" can be easily confused,70//! and so in this documentation these words are distinguished by the capital letter.71//!72//! - **Theme:** Named objects of variable => value pairs which get interpolated into73//! the Base's `themable` Parts. Themes can hold any value, but are often represented74//! in RMRK's examples as colors applied to visible Parts.75//!76//! ### Peculiarities in Unique77//!78//! - **Scoped properties:** Properties that are normally obscured from users.79//! Their purpose is to contain structured metadata that was not included in the Unique standard80//! for collections and tokens, meant to be operated on by proxies and other outliers.81//! Scoped property keys are prefixed with `some-scope:`, where `some-scope` is82//! an arbitrary keyword, like "rmrk". `:` is considered an unacceptable symbol in user-defined83//! properties, which, along with other safeguards, makes scoped ones impossible to tamper with.84//!85//! - **Auxiliary properties:** A slightly different structure of properties,86//! trading universality of use for more convenient storage, writes and access.87//! Meant to be inaccessible to end users.88//!89//! ## Proxy Implementation90//!91//! An external user is supposed to be able to utilize this proxy as they would92//! utilize RMRK, and get exactly the same results. Normally, Unique transactions93//! are off-limits to RMRK collections and tokens, and vice versa. However,94//! the information stored on chain can be freely interpreted by storage reads and Unique RPCs.95//!96//! ### ID Mapping97//!98//! RMRK's collections' IDs are counted independently of Unique's and start at 0.99//! Note that tokens' IDs still start at 1.100//! The collections themselves, as well as tokens, are stored as Unique collections,101//! and thus RMRK IDs are mapped to Unique IDs (but not vice versa).102//!103//! ### External/Internal Collection Insulation104//!105//! A Unique transaction cannot target collections purposed for RMRK,106//! and they are flagged as `external` to specify that. On the other hand,107//! due to the mapping, RMRK transactions and RPCs simply cannot reach Unique collections.108//!109//! ### Native Properties110//!111//! Many of RMRK's native parameters are stored as scoped properties of a collection112//! or an NFT on the chain. Scoped properties are prefixed with `rmrk:`, where `:`113//! is an unacceptable symbol in user-defined properties, which, along with other safeguards,114//! makes them impossible to tamper with.115//!116//! ### Collection and NFT Types, or Base, Parts and Themes Handling117//!118//! RMRK introduces the concept of a Base, which is a catalogue of Parts,119//! possible components of an NFT. Due to its similarity with the functionality120//! of a token collection, a Base is stored and handled as one, and the Base's Parts and Themes121//! are this collection's NFTs. See [`CollectionType`] and [`NftType`].122//!123//! ## Interface124//!125//! ### Dispatchables126//!127//! - `create_collection` - Create a new collection of NFTs.128//! - `destroy_collection` - Destroy a collection.129//! - `change_collection_issuer` - Change the issuer of a collection.130//! Analogous to Unique's collection's [`owner`](up_data_structs::Collection).131//! - `lock_collection` - "Lock" the collection and prevent new token creation. **Cannot be undone.**132//! - `mint_nft` - Mint an NFT in a specified collection.133//! - `burn_nft` - Burn an NFT, destroying it and its nested tokens.134//! - `send` - Transfer an NFT from an account/NFT A to another account/NFT B.135//! - `accept_nft` - Accept an NFT sent from another account to self or an owned NFT.136//! - `reject_nft` - Reject an NFT sent from another account to self or owned NFT and **burn it**.137//! - `accept_resource` - Accept the addition of a newly created pending resource to an existing NFT.138//! - `accept_resource_removal` - Accept the removal of a removal-pending resource from an NFT.139//! - `set_property` - Add or edit a custom user property of a token or a collection.140//! - `set_priority` - Set a different order of resource priorities for an NFT.141//! - `add_basic_resource` - Create and set/propose a basic resource for an NFT.142//! - `add_composable_resource` - Create and set/propose a composable resource for an NFT.143//! - `add_slot_resource` - Create and set/propose a slot resource for an NFT.144//! - `remove_resource` - Remove and erase a resource from an NFT.145146#![cfg_attr(not(feature = "std"), no_std)]147148use frame_support::{pallet_prelude::*, BoundedVec, dispatch::DispatchResult};149use frame_system::{pallet_prelude::*, ensure_signed};150use sp_runtime::{DispatchError, Permill, traits::StaticLookup};151use sp_std::{152 vec::Vec,153 collections::{btree_set::BTreeSet, btree_map::BTreeMap},154};155use up_data_structs::{*, mapping::TokenAddressMapping};156use pallet_common::{157 Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,158};159use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};160use pallet_structure::{Pallet as PalletStructure, Error as StructureError};161use pallet_evm::account::CrossAccountId;162use core::convert::AsRef;163164pub use pallet::*;165166#[cfg(feature = "runtime-benchmarks")]167pub mod benchmarking;168pub mod misc;169pub mod property;170pub mod rpc;171pub mod weights;172173pub type SelfWeightOf<T> = <T as Config>::WeightInfo;174175use weights::WeightInfo;176use misc::*;177pub use property::*;178179use RmrkProperty::*;180181/// A maximum number of levels of depth in the token nesting tree.182pub const NESTING_BUDGET: u32 = 5;183184type PendingTarget = (CollectionId, TokenId);185type PendingChild = (RmrkCollectionId, RmrkNftId);186type PendingChildrenSet = BTreeSet<PendingChild>;187188type BasesMap = BTreeMap<RmrkBaseId, u32>;189190#[frame_support::pallet]191pub mod pallet {192 use super::*;193194 #[pallet::config]195 pub trait Config:196 frame_system::Config197 + pallet_common::Config198 + pallet_nonfungible::Config199 + pallet_evm::Config200 {201 /// Overarching event type.202 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;203204 /// The weight information of this pallet.205 type WeightInfo: WeightInfo;206 }207208 /// Latest yet-unused collection ID.209 #[pallet::storage]210 #[pallet::getter(fn collection_index)]211 pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;212213 /// Mapping from RMRK collection ID to Unique's.214 #[pallet::storage]215 pub type UniqueCollectionId<T: Config> =216 StorageMap<_, Twox64Concat, RmrkCollectionId, CollectionId, ValueQuery>;217218 #[pallet::pallet]219 #[pallet::generate_store(pub(super) trait Store)]220 pub struct Pallet<T>(_);221222 #[pallet::event]223 #[pallet::generate_deposit(pub(super) fn deposit_event)]224 pub enum Event<T: Config> {225 CollectionCreated {226 issuer: T::AccountId,227 collection_id: RmrkCollectionId,228 },229 CollectionDestroyed {230 issuer: T::AccountId,231 collection_id: RmrkCollectionId,232 },233 IssuerChanged {234 old_issuer: T::AccountId,235 new_issuer: T::AccountId,236 collection_id: RmrkCollectionId,237 },238 CollectionLocked {239 issuer: T::AccountId,240 collection_id: RmrkCollectionId,241 },242 NftMinted {243 owner: T::AccountId,244 collection_id: RmrkCollectionId,245 nft_id: RmrkNftId,246 },247 NFTBurned {248 owner: T::AccountId,249 nft_id: RmrkNftId,250 },251 NFTSent {252 sender: T::AccountId,253 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,254 collection_id: RmrkCollectionId,255 nft_id: RmrkNftId,256 approval_required: bool,257 },258 NFTAccepted {259 sender: T::AccountId,260 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,261 collection_id: RmrkCollectionId,262 nft_id: RmrkNftId,263 },264 NFTRejected {265 sender: T::AccountId,266 collection_id: RmrkCollectionId,267 nft_id: RmrkNftId,268 },269 PropertySet {270 collection_id: RmrkCollectionId,271 maybe_nft_id: Option<RmrkNftId>,272 key: RmrkKeyString,273 value: RmrkValueString,274 },275 ResourceAdded {276 nft_id: RmrkNftId,277 resource_id: RmrkResourceId,278 },279 ResourceRemoval {280 nft_id: RmrkNftId,281 resource_id: RmrkResourceId,282 },283 ResourceAccepted {284 nft_id: RmrkNftId,285 resource_id: RmrkResourceId,286 },287 ResourceRemovalAccepted {288 nft_id: RmrkNftId,289 resource_id: RmrkResourceId,290 },291 PrioritySet {292 collection_id: RmrkCollectionId,293 nft_id: RmrkNftId,294 },295 }296297 #[pallet::error]298 pub enum Error<T> {299 /* Unique proxy-specific events */300 /// Property of the type of RMRK collection could not be read successfully.301 CorruptedCollectionType,302 // NftTypeEncodeError,303 /// Too many symbols supplied as the property key. The maximum is [256](up_data_structs::MAX_PROPERTY_KEY_LENGTH).304 RmrkPropertyKeyIsTooLong,305 /// Too many bytes supplied as the property value. The maximum is [32768](up_data_structs::MAX_PROPERTY_VALUE_LENGTH).306 RmrkPropertyValueIsTooLong,307 /// Could not find a property by the supplied key.308 RmrkPropertyIsNotFound,309 /// Something went wrong when decoding encoded data from the storage.310 /// Perhaps, there was a wrong key supplied for the type, or the data was improperly stored.311 UnableToDecodeRmrkData,312313 /* RMRK compatible events */314 /// Only destroying collections without tokens is allowed.315 CollectionNotEmpty,316 /// Could not find an ID for a collection. It is likely there were too many collections created on the chain, causing an overflow.317 NoAvailableCollectionId,318 /// Token does not exist, or there is no suitable ID for it, likely too many tokens were created in a collection, causing an overflow.319 NoAvailableNftId,320 /// Collection does not exist, has a wrong type, or does not map to a Unique ID.321 CollectionUnknown,322 /// No permission to perform action.323 NoPermission,324 /// Token is marked as non-transferable, and thus cannot be transferred.325 NonTransferable,326 /// Too many tokens created in the collection, no new ones are allowed.327 CollectionFullOrLocked,328 /// No such resource found.329 ResourceDoesntExist,330 /// If an NFT is sent to a descendant, that would form a nesting loop, an ouroboros.331 /// Sending to self is redundant.332 CannotSendToDescendentOrSelf,333 /// Not the target owner of the sent NFT.334 CannotAcceptNonOwnedNft,335 /// Not the target owner of the sent NFT.336 CannotRejectNonOwnedNft,337 /// NFT was not sent and is not pending.338 CannotRejectNonPendingNft,339 /// Resource is not pending for the operation.340 ResourceNotPending,341 /// Could not find an ID for the resource. It is likely there were too many resources created on an NFT, causing an overflow.342 NoAvailableResourceId,343 }344345 #[pallet::call]346 impl<T: Config> Pallet<T> {347 // todo :refactor replace every collection_id with rmrk_collection_id (and nft_id) in arguments for uniformity?348349 /// Create a new collection of NFTs.350 ///351 /// # Permissions:352 /// * Anyone - will be assigned as the issuer of the collection.353 ///354 /// # Arguments:355 /// - `origin`: sender of the transaction356 /// - `metadata`: Metadata describing the collection, e.g. IPFS hash. Cannot be changed.357 /// - `max`: Optional maximum number of tokens.358 /// - `symbol`: UTF-8 string with token prefix, by which to represent the token in wallets and UIs.359 /// Analogous to Unique's [`token_prefix`](up_data_structs::Collection). Cannot be changed.360 #[pallet::call_index(0)]361 #[pallet::weight(<SelfWeightOf<T>>::create_collection())]362 pub fn create_collection(363 origin: OriginFor<T>,364 metadata: RmrkString,365 max: Option<u32>,366 symbol: RmrkCollectionSymbol,367 ) -> DispatchResult {368 let sender = ensure_signed(origin)?;369370 let limits = CollectionLimits {371 owner_can_transfer: Some(false),372 token_limit: max,373 ..Default::default()374 };375376 let data = CreateCollectionData {377 limits: Some(limits),378 token_prefix: symbol379 .into_inner()380 .try_into()381 .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,382 permissions: Some(CollectionPermissions {383 nesting: Some(NestingPermissions {384 token_owner: true,385 collection_admin: false,386 restricted: None,387 #[cfg(feature = "runtime-benchmarks")]388 permissive: false,389 }),390 ..Default::default()391 }),392 ..Default::default()393 };394395 let unique_collection_id = Self::init_collection(396 T::CrossAccountId::from_sub(sender.clone()),397 data,398 [399 Self::encode_rmrk_property(Metadata, &metadata)?,400 Self::encode_rmrk_property(CollectionType, &misc::CollectionType::Regular)?,401 ]402 .into_iter(),403 )?;404 let rmrk_collection_id = <CollectionIndex<T>>::get();405406 <UniqueCollectionId<T>>::insert(rmrk_collection_id, unique_collection_id);407408 <PalletCommon<T>>::set_scoped_collection_property(409 unique_collection_id,410 RMRK_SCOPE,411 Self::encode_rmrk_property(RmrkInternalCollectionId, &rmrk_collection_id)?,412 )?;413414 <CollectionIndex<T>>::mutate(|n| *n += 1);415416 Self::deposit_event(Event::CollectionCreated {417 issuer: sender,418 collection_id: rmrk_collection_id,419 });420421 Ok(())422 }423424 /// Destroy a collection.425 ///426 /// Only empty collections can be destroyed. If it has any tokens, they must be burned first.427 ///428 /// # Permissions:429 /// * Collection issuer430 ///431 /// # Arguments:432 /// - `origin`: sender of the transaction433 /// - `collection_id`: RMRK ID of the collection to destroy.434 #[pallet::call_index(1)]435 #[pallet::weight(<SelfWeightOf<T>>::destroy_collection())]436 pub fn destroy_collection(437 origin: OriginFor<T>,438 collection_id: RmrkCollectionId,439 ) -> DispatchResult {440 let sender = ensure_signed(origin)?;441 let cross_sender = T::CrossAccountId::from_sub(sender.clone());442443 let collection = Self::get_typed_nft_collection(444 Self::unique_collection_id(collection_id)?,445 misc::CollectionType::Regular,446 )?;447 collection.check_is_external()?;448449 <PalletNft<T>>::destroy_collection(collection, &cross_sender)450 .map_err(Self::map_unique_err_to_proxy)?;451452 Self::deposit_event(Event::CollectionDestroyed {453 issuer: sender,454 collection_id,455 });456457 Ok(())458 }459460 /// Change the issuer of a collection. Analogous to Unique's collection's [`owner`](up_data_structs::Collection).461 ///462 /// # Permissions:463 /// * Collection issuer464 ///465 /// # Arguments:466 /// - `origin`: sender of the transaction467 /// - `collection_id`: RMRK collection ID to change the issuer of.468 /// - `new_issuer`: Collection's new issuer.469 #[pallet::call_index(2)]470 #[pallet::weight(<SelfWeightOf<T>>::change_collection_issuer())]471 pub fn change_collection_issuer(472 origin: OriginFor<T>,473 collection_id: RmrkCollectionId,474 new_issuer: <T::Lookup as StaticLookup>::Source,475 ) -> DispatchResult {476 let sender = ensure_signed(origin)?;477478 let collection = Self::get_nft_collection(Self::unique_collection_id(collection_id)?)?;479 collection.check_is_external()?;480481 let new_issuer = T::Lookup::lookup(new_issuer)?;482483 Self::change_collection_owner(484 Self::unique_collection_id(collection_id)?,485 misc::CollectionType::Regular,486 sender.clone(),487 new_issuer.clone(),488 )?;489490 Self::deposit_event(Event::IssuerChanged {491 old_issuer: sender,492 new_issuer,493 collection_id,494 });495496 Ok(())497 }498499 /// "Lock" the collection and prevent new token creation. Cannot be undone.500 ///501 /// # Permissions:502 /// * Collection issuer503 ///504 /// # Arguments:505 /// - `origin`: sender of the transaction506 /// - `collection_id`: RMRK ID of the collection to lock.507 #[pallet::call_index(3)]508 #[pallet::weight(<SelfWeightOf<T>>::lock_collection())]509 pub fn lock_collection(510 origin: OriginFor<T>,511 collection_id: RmrkCollectionId,512 ) -> DispatchResult {513 let sender = ensure_signed(origin)?;514 let cross_sender = T::CrossAccountId::from_sub(sender.clone());515516 let collection = Self::get_typed_nft_collection(517 Self::unique_collection_id(collection_id)?,518 misc::CollectionType::Regular,519 )?;520 collection.check_is_external()?;521522 Self::check_collection_owner(&collection, &cross_sender)?;523524 let token_count = collection.total_supply();525526 let mut collection = collection.into_inner();527 collection.limits.token_limit = Some(token_count);528 collection.save()?;529530 Self::deposit_event(Event::CollectionLocked {531 issuer: sender,532 collection_id,533 });534535 Ok(())536 }537538 /// Mint an NFT in a specified collection.539 ///540 /// # Permissions:541 /// * Collection issuer542 ///543 /// # Arguments:544 /// - `origin`: sender of the transaction545 /// - `owner`: Owner account of the NFT. If set to None, defaults to the sender (collection issuer).546 /// - `collection_id`: RMRK collection ID for the NFT to be minted within. Cannot be changed.547 /// - `recipient`: Receiver account of the royalty. Has no effect if the `royalty_amount` is not set. Cannot be changed.548 /// - `royalty_amount`: Optional permillage reward from each trade for the `recipient`. Cannot be changed.549 /// - `metadata`: Arbitrary data about an NFT, e.g. IPFS hash. Cannot be changed.550 /// - `transferable`: Can this NFT be transferred? Cannot be changed.551 /// - `resources`: Resource data to be added to the NFT immediately after minting.552 #[pallet::call_index(4)]553 #[pallet::weight(<SelfWeightOf<T>>::mint_nft(resources.as_ref().map(|r| r.len() as u32).unwrap_or(0)))]554 pub fn mint_nft(555 origin: OriginFor<T>,556 owner: Option<T::AccountId>,557 collection_id: RmrkCollectionId,558 recipient: Option<T::AccountId>,559 royalty_amount: Option<Permill>,560 metadata: RmrkString,561 transferable: bool,562 resources: Option<BoundedVec<RmrkResourceTypes, MaxResourcesOnMint>>,563 ) -> DispatchResult {564 let sender = ensure_signed(origin)?;565 let cross_sender = T::CrossAccountId::from_sub(sender.clone());566567 let owner = owner.unwrap_or(sender.clone());568 let cross_owner = T::CrossAccountId::from_sub(owner.clone());569570 let collection = Self::get_typed_nft_collection(571 Self::unique_collection_id(collection_id)?,572 misc::CollectionType::Regular,573 )?;574 collection.check_is_external()?;575576 let royalty_info = royalty_amount.map(|amount| rmrk_traits::RoyaltyInfo {577 recipient: recipient.unwrap_or_else(|| owner.clone()),578 amount,579 });580581 let nft_id = Self::create_nft(582 &cross_sender,583 &cross_owner,584 &collection,585 [586 Self::encode_rmrk_property(TokenType, &NftType::Regular)?,587 Self::encode_rmrk_property(Transferable, &transferable)?,588 Self::encode_rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,589 Self::encode_rmrk_property(RoyaltyInfo, &royalty_info)?,590 Self::encode_rmrk_property(Metadata, &metadata)?,591 Self::encode_rmrk_property(Equipped, &false)?,592 Self::encode_rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,593 Self::encode_rmrk_property(NextResourceId, &(0 as RmrkResourceId))?,594 Self::encode_rmrk_property(PendingChildren, &PendingChildrenSet::new())?,595 Self::encode_rmrk_property(AssociatedBases, &BasesMap::new())?,596 ]597 .into_iter(),598 )599 .map_err(|err| match err {600 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),601 err => Self::map_unique_err_to_proxy(err),602 })?;603604 if let Some(resources) = resources {605 for resource in resources {606 Self::resource_add(sender.clone(), collection.id, nft_id, resource)?;607 }608 }609610 Self::deposit_event(Event::NftMinted {611 owner,612 collection_id,613 nft_id: nft_id.0,614 });615616 Ok(())617 }618619 /// Burn an NFT, destroying it and its nested tokens up to the specified limit.620 /// If the burning budget is exceeded, the transaction is reverted.621 ///622 /// This is the way to burn a nested token as well.623 ///624 /// For more information, see [`burn_recursively`](pallet_nonfungible::pallet::Pallet::burn_recursively).625 ///626 /// # Permissions:627 /// * Token owner628 ///629 /// # Arguments:630 /// - `origin`: sender of the transaction631 /// - `collection_id`: RMRK ID of the collection in which the NFT to burn belongs to.632 /// - `nft_id`: ID of the NFT to be destroyed.633 /// - `max_burns`: Maximum number of tokens to burn, assuming nesting. The transaction634 /// is reverted if there are more tokens to burn in the nesting tree than this number.635 /// This is primarily a mechanism of transaction weight control.636 #[pallet::call_index(5)]637 #[pallet::weight(<SelfWeightOf<T>>::burn_nft(*max_burns))]638 pub fn burn_nft(639 origin: OriginFor<T>,640 collection_id: RmrkCollectionId,641 nft_id: RmrkNftId,642 max_burns: u32,643 ) -> DispatchResult {644 let sender = ensure_signed(origin)?;645 let cross_sender = T::CrossAccountId::from_sub(sender.clone());646647 let collection = Self::get_typed_nft_collection(648 Self::unique_collection_id(collection_id)?,649 misc::CollectionType::Regular,650 )?;651 collection.check_is_external()?;652653 Self::destroy_nft(654 cross_sender,655 Self::unique_collection_id(collection_id)?,656 nft_id.into(),657 max_burns,658 <Error<T>>::NoPermission,659 )660 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;661662 Self::deposit_event(Event::NFTBurned {663 owner: sender,664 nft_id,665 });666667 Ok(())668 }669670 /// Transfer an NFT from an account/NFT A to another account/NFT B.671 /// The token must be transferable. Nesting cannot occur deeper than the [`NESTING_BUDGET`].672 ///673 /// If the target owner is an NFT owned by another account, then the NFT will enter674 /// the pending state and will have to be accepted by the other account.675 ///676 /// # Permissions:677 /// - Token owner678 ///679 /// # Arguments:680 /// - `origin`: sender of the transaction681 /// - `rmrk_collection_id`: RMRK ID of the collection of the NFT to be transferred.682 /// - `rmrk_nft_id`: ID of the NFT to be transferred.683 /// - `new_owner`: New owner of the nft which can be either an account or a NFT.684 #[pallet::call_index(6)]685 #[pallet::weight(<SelfWeightOf<T>>::send())]686 pub fn send(687 origin: OriginFor<T>,688 rmrk_collection_id: RmrkCollectionId,689 rmrk_nft_id: RmrkNftId,690 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,691 ) -> DispatchResult {692 let sender = ensure_signed(origin.clone())?;693 let cross_sender = T::CrossAccountId::from_sub(sender.clone());694695 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;696 let nft_id = rmrk_nft_id.into();697698 let collection =699 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;700 collection.check_is_external()?;701702 let token_data =703 <TokenData<T>>::get((collection_id, nft_id)).ok_or(<Error<T>>::NoAvailableNftId)?;704705 let from = token_data.owner;706707 ensure!(708 Self::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Transferable)?,709 <Error<T>>::NonTransferable710 );711712 ensure!(713 Self::get_nft_property_decoded::<Option<PendingTarget>>(714 collection_id,715 nft_id,716 RmrkProperty::PendingNftAccept717 )?718 .is_none(),719 <Error<T>>::NoPermission720 );721722 let target_owner;723 let approval_required;724725 match new_owner {726 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {727 target_owner = T::CrossAccountId::from_sub(account_id.clone());728 approval_required = false;729 }730 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(731 target_collection_id,732 target_nft_id,733 ) => {734 let target_collection_id = Self::unique_collection_id(target_collection_id)?;735736 let target_nft_budget = budget::Value::new(NESTING_BUDGET);737738 let target_nft_owner = <PalletStructure<T>>::get_checked_topmost_owner(739 target_collection_id,740 target_nft_id.into(),741 Some((collection_id, nft_id)),742 &target_nft_budget,743 )744 .map_err(Self::map_unique_err_to_proxy)?745 .ok_or::<DispatchError>(<Error<T>>::NoPermission.into())?;746747 approval_required = cross_sender != target_nft_owner;748749 if approval_required {750 target_owner = target_nft_owner;751752 <PalletNft<T>>::set_scoped_token_property(753 collection.id,754 nft_id,755 RMRK_SCOPE,756 Self::encode_rmrk_property::<Option<PendingTarget>>(757 PendingNftAccept,758 &Some((target_collection_id, target_nft_id.into())),759 )?,760 )?;761762 Self::insert_pending_child(763 (target_collection_id, target_nft_id.into()),764 (rmrk_collection_id, rmrk_nft_id),765 )?;766 } else {767 target_owner = T::CrossTokenAddressMapping::token_to_address(768 target_collection_id,769 target_nft_id.into(),770 );771 }772 }773 }774775 let src_nft_budget = budget::Value::new(NESTING_BUDGET);776777 <PalletNft<T>>::transfer_from(778 &collection,779 &cross_sender,780 &from,781 &target_owner,782 nft_id,783 &src_nft_budget,784 )785 .map_err(Self::map_unique_err_to_proxy)?;786787 Self::deposit_event(Event::NFTSent {788 sender,789 recipient: new_owner,790 collection_id: rmrk_collection_id,791 nft_id: rmrk_nft_id,792 approval_required,793 });794795 Ok(())796 }797798 /// Accept an NFT sent from another account to self or an owned NFT.799 ///800 /// The NFT in question must be pending, and, thus, be [sent](`Pallet::send`) first.801 ///802 /// # Permissions:803 /// - Token-owner-to-be804 ///805 /// # Arguments:806 /// - `origin`: sender of the transaction807 /// - `rmrk_collection_id`: RMRK collection ID of the NFT to be accepted.808 /// - `rmrk_nft_id`: ID of the NFT to be accepted.809 /// - `new_owner`: Either the sender's account ID or a sender-owned NFT,810 /// whichever the accepted NFT was sent to.811 #[pallet::call_index(7)]812 #[pallet::weight(<SelfWeightOf<T>>::accept_nft())]813 pub fn accept_nft(814 origin: OriginFor<T>,815 rmrk_collection_id: RmrkCollectionId,816 rmrk_nft_id: RmrkNftId,817 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,818 ) -> DispatchResult {819 let sender = ensure_signed(origin.clone())?;820 let cross_sender = T::CrossAccountId::from_sub(sender.clone());821822 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;823 let nft_id = rmrk_nft_id.into();824825 let collection =826 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;827 collection.check_is_external()?;828829 let new_cross_owner = match new_owner {830 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {831 T::CrossAccountId::from_sub(account_id.clone())832 }833 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(834 target_collection_id,835 target_nft_id,836 ) => {837 let target_collection_id = Self::unique_collection_id(target_collection_id)?;838839 T::CrossTokenAddressMapping::token_to_address(840 target_collection_id,841 TokenId(target_nft_id),842 )843 }844 };845846 let budget = budget::Value::new(NESTING_BUDGET);847848 <PalletNft<T>>::transfer(849 &collection,850 &cross_sender,851 &new_cross_owner,852 nft_id,853 &budget,854 )855 .map_err(|err| {856 if err == <CommonError<T>>::UserIsNotAllowedToNest.into() {857 <Error<T>>::CannotAcceptNonOwnedNft.into()858 } else {859 Self::map_unique_err_to_proxy(err)860 }861 })?;862863 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(864 collection_id,865 nft_id,866 RmrkProperty::PendingNftAccept,867 )?;868869 if let Some(pending_target) = pending_target {870 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?;871872 <PalletNft<T>>::set_scoped_token_property(873 collection.id,874 nft_id,875 RMRK_SCOPE,876 Self::encode_rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,877 )?;878 }879880 Self::deposit_event(Event::NFTAccepted {881 sender,882 recipient: new_owner,883 collection_id: rmrk_collection_id,884 nft_id: rmrk_nft_id,885 });886887 Ok(())888 }889890 /// Reject an NFT sent from another account to self or owned NFT.891 /// The NFT in question will not be sent back and burnt instead.892 ///893 /// The NFT in question must be pending, and, thus, be [sent](`Pallet::send`) first.894 ///895 /// # Permissions:896 /// - Token-owner-to-be-not897 ///898 /// # Arguments:899 /// - `origin`: sender of the transaction900 /// - `rmrk_collection_id`: RMRK ID of the NFT to be rejected.901 /// - `rmrk_nft_id`: ID of the NFT to be rejected.902 #[pallet::call_index(8)]903 #[pallet::weight(<SelfWeightOf<T>>::reject_nft())]904 pub fn reject_nft(905 origin: OriginFor<T>,906 rmrk_collection_id: RmrkCollectionId,907 rmrk_nft_id: RmrkNftId,908 ) -> DispatchResult {909 let sender = ensure_signed(origin)?;910 let cross_sender = T::CrossAccountId::from_sub(sender.clone());911912 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;913 let nft_id = rmrk_nft_id.into();914915 let collection =916 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;917 collection.check_is_external()?;918919 ensure!(920 <TokenData<T>>::get((collection_id, nft_id)).is_some(),921 <Error<T>>::NoAvailableNftId922 );923924 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(925 collection_id,926 nft_id,927 RmrkProperty::PendingNftAccept,928 )?;929930 match pending_target {931 Some(pending_target) => {932 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?933 }934 None => return Err(<Error<T>>::CannotRejectNonPendingNft.into()),935 }936937 Self::destroy_nft(938 cross_sender,939 collection_id,940 nft_id,941 NESTING_BUDGET,942 <Error<T>>::CannotRejectNonOwnedNft,943 )944 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;945946 Self::deposit_event(Event::NFTRejected {947 sender,948 collection_id: rmrk_collection_id,949 nft_id: rmrk_nft_id,950 });951952 Ok(())953 }954955 /// Accept the addition of a newly created pending resource to an existing NFT.956 ///957 /// This transaction is needed when a resource is created and assigned to an NFT958 /// by a non-owner, i.e. the collection issuer, with one of the959 /// [`add_...` transactions](Pallet::add_basic_resource).960 ///961 /// # Permissions:962 /// - Token owner963 ///964 /// # Arguments:965 /// - `origin`: sender of the transaction966 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.967 /// - `rmrk_nft_id`: ID of the NFT with a pending resource to be accepted.968 /// - `resource_id`: ID of the newly created pending resource.969 /// accept the addition of a new resource to an existing NFT970 #[pallet::call_index(9)]971 #[pallet::weight(<SelfWeightOf<T>>::accept_resource())]972 pub fn accept_resource(973 origin: OriginFor<T>,974 rmrk_collection_id: RmrkCollectionId,975 rmrk_nft_id: RmrkNftId,976 resource_id: RmrkResourceId,977 ) -> DispatchResult {978 let sender = ensure_signed(origin)?;979 let cross_sender = T::CrossAccountId::from_sub(sender);980981 let collection_id = Self::unique_collection_id(rmrk_collection_id)982 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;983 let collection =984 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;985 collection.check_is_external()?;986987 let nft_id = rmrk_nft_id.into();988989 let budget = budget::Value::new(NESTING_BUDGET);990991 let nft_owner =992 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)993 .map_err(|_| <Error<T>>::ResourceDoesntExist)?994 .ok_or::<DispatchError>(<Error<T>>::NoPermission.into())?;995996 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {997 ensure!(res.pending, <Error<T>>::ResourceNotPending);998 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);9991000 res.pending = false;10011002 Ok(())1003 })?;10041005 Self::deposit_event(Event::<T>::ResourceAccepted {1006 nft_id: rmrk_nft_id,1007 resource_id,1008 });10091010 Ok(())1011 }10121013 /// Accept the removal of a removal-pending resource from an NFT.1014 ///1015 /// This transaction is needed when a non-owner, i.e. the collection issuer,1016 /// requests a [removal](`Pallet::remove_resource`) of a resource from an NFT.1017 ///1018 /// # Permissions:1019 /// - Token owner1020 ///1021 /// # Arguments:1022 /// - `origin`: sender of the transaction1023 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1024 /// - `rmrk_nft_id`: ID of the NFT with a resource to be removed.1025 /// - `resource_id`: ID of the removal-pending resource.1026 #[pallet::call_index(10)]1027 #[pallet::weight(<SelfWeightOf<T>>::accept_resource_removal())]1028 pub fn accept_resource_removal(1029 origin: OriginFor<T>,1030 rmrk_collection_id: RmrkCollectionId,1031 rmrk_nft_id: RmrkNftId,1032 resource_id: RmrkResourceId,1033 ) -> DispatchResult {1034 let sender = ensure_signed(origin)?;1035 let cross_sender = T::CrossAccountId::from_sub(sender);10361037 let collection_id = Self::unique_collection_id(rmrk_collection_id)1038 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;1039 let collection =1040 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1041 collection.check_is_external()?;10421043 let nft_id = rmrk_nft_id.into();10441045 let budget = budget::Value::new(NESTING_BUDGET);10461047 let nft_owner =1048 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)1049 .map_err(|_| <Error<T>>::ResourceDoesntExist)?1050 .ok_or::<DispatchError>(<Error<T>>::NoPermission.into())?;10511052 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);10531054 let resource_id_key = Self::get_scoped_property_key(ResourceId(resource_id))?;10551056 let resource_info = <PalletNft<T>>::token_aux_property((1057 collection_id,1058 nft_id,1059 RMRK_SCOPE,1060 resource_id_key.clone(),1061 ))1062 .ok_or(<Error<T>>::ResourceDoesntExist)?;10631064 let resource_info: RmrkResourceInfo = Self::decode_property_value(&resource_info)?;10651066 ensure!(1067 resource_info.pending_removal,1068 <Error<T>>::ResourceNotPending1069 );10701071 <PalletNft<T>>::remove_token_aux_property(1072 collection_id,1073 nft_id,1074 RMRK_SCOPE,1075 resource_id_key,1076 );10771078 if let RmrkResourceTypes::Composable(resource) = resource_info.resource {1079 let base_id = resource.base;10801081 Self::remove_associated_base_id(collection_id, nft_id, base_id)?;1082 }10831084 Self::deposit_event(Event::<T>::ResourceRemovalAccepted {1085 nft_id: rmrk_nft_id,1086 resource_id,1087 });10881089 Ok(())1090 }10911092 /// Add or edit a custom user property, a key-value pair, describing the metadata1093 /// of a token or a collection, on either one of these.1094 ///1095 /// Note that in this proxy implementation many details regarding RMRK are stored1096 /// as scoped properties prefixed with "rmrk:", normally inaccessible1097 /// to external transactions and RPCs.1098 ///1099 /// # Permissions:1100 /// - Collection issuer - in case of collection property1101 /// - Token owner - in case of NFT property1102 ///1103 /// # Arguments:1104 /// - `origin`: sender of the transaction1105 /// - `rmrk_collection_id`: RMRK collection ID.1106 /// - `maybe_nft_id`: Optional ID of the NFT. If left empty, then the property is set for the collection.1107 /// - `key`: Key of the custom property to be referenced by.1108 /// - `value`: Value of the custom property to be stored.1109 #[pallet::call_index(11)]1110 #[pallet::weight(<SelfWeightOf<T>>::set_property())]1111 pub fn set_property(1112 origin: OriginFor<T>,1113 #[pallet::compact] rmrk_collection_id: RmrkCollectionId,1114 maybe_nft_id: Option<RmrkNftId>,1115 key: RmrkKeyString,1116 value: RmrkValueString,1117 ) -> DispatchResult {1118 let sender = ensure_signed(origin)?;1119 let sender = T::CrossAccountId::from_sub(sender);11201121 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1122 let collection =1123 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1124 collection.check_is_external()?;11251126 let budget = budget::Value::new(NESTING_BUDGET);11271128 match maybe_nft_id {1129 Some(nft_id) => {1130 let token_id: TokenId = nft_id.into();11311132 Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;1133 Self::ensure_nft_owner(collection_id, token_id, &sender, &budget)?;11341135 <PalletNft<T>>::set_scoped_token_property(1136 collection_id,1137 token_id,1138 RMRK_SCOPE,1139 Self::encode_rmrk_property(UserProperty(key.as_slice()), &value)?,1140 )?;1141 }1142 None => {1143 let collection = Self::get_typed_nft_collection(1144 collection_id,1145 misc::CollectionType::Regular,1146 )?;11471148 Self::check_collection_owner(&collection, &sender)?;11491150 <PalletCommon<T>>::set_scoped_collection_property(1151 collection_id,1152 RMRK_SCOPE,1153 Self::encode_rmrk_property(UserProperty(key.as_slice()), &value)?,1154 )?;1155 }1156 }11571158 Self::deposit_event(Event::PropertySet {1159 collection_id: rmrk_collection_id,1160 maybe_nft_id,1161 key,1162 value,1163 });11641165 Ok(())1166 }11671168 /// Set a different order of resource priorities for an NFT. Priorities can be used,1169 /// for example, for order of rendering.1170 ///1171 /// Note that the priorities are not updated automatically, and are an empty vector1172 /// by default. There is no pre-set definition for the order to be particular,1173 /// it can be interpreted arbitrarily use-case by use-case.1174 ///1175 /// # Permissions:1176 /// - Token owner1177 ///1178 /// # Arguments:1179 /// - `origin`: sender of the transaction1180 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1181 /// - `rmrk_nft_id`: ID of the NFT to rearrange resource priorities for.1182 /// - `priorities`: Ordered vector of resource IDs.1183 #[pallet::call_index(12)]1184 #[pallet::weight(<SelfWeightOf<T>>::set_priority())]1185 pub fn set_priority(1186 origin: OriginFor<T>,1187 rmrk_collection_id: RmrkCollectionId,1188 rmrk_nft_id: RmrkNftId,1189 priorities: BoundedVec<RmrkResourceId, RmrkMaxPriorities>,1190 ) -> DispatchResult {1191 let sender = ensure_signed(origin)?;1192 let sender = T::CrossAccountId::from_sub(sender);11931194 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1195 let nft_id = rmrk_nft_id.into();11961197 let collection =1198 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1199 collection.check_is_external()?;12001201 let budget = budget::Value::new(NESTING_BUDGET);12021203 Self::ensure_nft_type(collection_id, nft_id, NftType::Regular)?;1204 Self::ensure_nft_owner(collection_id, nft_id, &sender, &budget)?;12051206 <PalletNft<T>>::set_scoped_token_property(1207 collection_id,1208 nft_id,1209 RMRK_SCOPE,1210 Self::encode_rmrk_property(ResourcePriorities, &priorities.into_inner())?,1211 )?;12121213 Self::deposit_event(Event::<T>::PrioritySet {1214 collection_id: rmrk_collection_id,1215 nft_id: rmrk_nft_id,1216 });12171218 Ok(())1219 }12201221 /// Create and set/propose a basic resource for an NFT.1222 ///1223 /// A basic resource is the simplest, lacking a Base and anything that comes with it.1224 /// See RMRK docs for more information and examples.1225 ///1226 /// # Permissions:1227 /// - Collection issuer - if not the token owner, adding the resource will warrant1228 /// the owner's [acceptance](Pallet::accept_resource).1229 ///1230 /// # Arguments:1231 /// - `origin`: sender of the transaction1232 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1233 /// - `nft_id`: ID of the NFT to assign a resource to.1234 /// - `resource`: Data of the resource to be created.1235 #[pallet::call_index(13)]1236 #[pallet::weight(<SelfWeightOf<T>>::add_basic_resource())]1237 pub fn add_basic_resource(1238 origin: OriginFor<T>,1239 rmrk_collection_id: RmrkCollectionId,1240 nft_id: RmrkNftId,1241 resource: RmrkBasicResource,1242 ) -> DispatchResult {1243 let sender = ensure_signed(origin.clone())?;12441245 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1246 let collection =1247 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1248 collection.check_is_external()?;12491250 let resource_id = Self::resource_add(1251 sender,1252 collection_id,1253 nft_id.into(),1254 RmrkResourceTypes::Basic(resource),1255 )?;12561257 Self::deposit_event(Event::ResourceAdded {1258 nft_id,1259 resource_id,1260 });1261 Ok(())1262 }12631264 /// Create and set/propose a composable resource for an NFT.1265 ///1266 /// A composable resource links to a Base and has a subset of its Parts it is composed of.1267 /// See RMRK docs for more information and examples.1268 ///1269 /// # Permissions:1270 /// - Collection issuer - if not the token owner, adding the resource will warrant1271 /// the owner's [acceptance](Pallet::accept_resource).1272 ///1273 /// # Arguments:1274 /// - `origin`: sender of the transaction1275 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1276 /// - `nft_id`: ID of the NFT to assign a resource to.1277 /// - `resource`: Data of the resource to be created.1278 #[pallet::call_index(14)]1279 #[pallet::weight(<SelfWeightOf<T>>::add_composable_resource())]1280 pub fn add_composable_resource(1281 origin: OriginFor<T>,1282 rmrk_collection_id: RmrkCollectionId,1283 nft_id: RmrkNftId,1284 resource: RmrkComposableResource,1285 ) -> DispatchResult {1286 let sender = ensure_signed(origin.clone())?;12871288 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1289 let collection =1290 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1291 collection.check_is_external()?;12921293 let base_id = resource.base;12941295 let resource_id = Self::resource_add(1296 sender,1297 collection_id,1298 nft_id.into(),1299 RmrkResourceTypes::Composable(resource),1300 )?;13011302 <PalletNft<T>>::try_mutate_token_aux_property(1303 collection_id,1304 nft_id.into(),1305 RMRK_SCOPE,1306 Self::get_scoped_property_key(AssociatedBases)?,1307 |value| -> DispatchResult {1308 let mut bases: BasesMap = match value {1309 Some(value) => Self::decode_property_value(value)?,1310 None => BasesMap::new(),1311 };13121313 *bases.entry(base_id).or_insert(0) += 1;13141315 *value = Some(Self::encode_property_value(&bases)?);1316 Ok(())1317 },1318 )?;13191320 Self::deposit_event(Event::ResourceAdded {1321 nft_id,1322 resource_id,1323 });1324 Ok(())1325 }13261327 /// Create and set/propose a slot resource for an NFT.1328 ///1329 /// A slot resource links to a Base and a slot ID in it which it can fit into.1330 /// See RMRK docs for more information and examples.1331 ///1332 /// # Permissions:1333 /// - Collection issuer - if not the token owner, adding the resource will warrant1334 /// the owner's [acceptance](Pallet::accept_resource).1335 ///1336 /// # Arguments:1337 /// - `origin`: sender of the transaction1338 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1339 /// - `nft_id`: ID of the NFT to assign a resource to.1340 /// - `resource`: Data of the resource to be created.1341 #[pallet::call_index(15)]1342 #[pallet::weight(<SelfWeightOf<T>>::add_slot_resource())]1343 pub fn add_slot_resource(1344 origin: OriginFor<T>,1345 rmrk_collection_id: RmrkCollectionId,1346 nft_id: RmrkNftId,1347 resource: RmrkSlotResource,1348 ) -> DispatchResult {1349 let sender = ensure_signed(origin.clone())?;13501351 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1352 let collection =1353 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1354 collection.check_is_external()?;13551356 let resource_id = Self::resource_add(1357 sender,1358 collection_id,1359 nft_id.into(),1360 RmrkResourceTypes::Slot(resource),1361 )?;13621363 Self::deposit_event(Event::ResourceAdded {1364 nft_id,1365 resource_id,1366 });1367 Ok(())1368 }13691370 /// Remove and erase a resource from an NFT.1371 ///1372 /// If the sender does not own the NFT, then it will be pending confirmation,1373 /// and will have to be [accepted](Pallet::accept_resource_removal) by the token owner.1374 ///1375 /// # Permissions1376 /// - Collection issuer1377 ///1378 /// # Arguments1379 /// - `origin`: sender of the transaction1380 /// - `rmrk_collection_id`: RMRK ID of a collection to which the NFT making use of the resource belongs to.1381 /// - `nft_id`: ID of the NFT with a resource to be removed.1382 /// - `resource_id`: ID of the resource to be removed.1383 #[pallet::call_index(16)]1384 #[pallet::weight(<SelfWeightOf<T>>::remove_resource())]1385 pub fn remove_resource(1386 origin: OriginFor<T>,1387 rmrk_collection_id: RmrkCollectionId,1388 nft_id: RmrkNftId,1389 resource_id: RmrkResourceId,1390 ) -> DispatchResult {1391 let sender = ensure_signed(origin.clone())?;13921393 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1394 let collection =1395 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1396 collection.check_is_external()?;13971398 Self::resource_remove(sender, collection_id, nft_id.into(), resource_id)?;13991400 Self::deposit_event(Event::ResourceRemoval {1401 nft_id,1402 resource_id,1403 });1404 Ok(())1405 }1406 }1407}14081409impl<T: Config> Pallet<T> {1410 /// Transform one of possible RMRK keys into a byte key with a RMRK scope.1411 pub fn get_scoped_property_key(rmrk_key: RmrkProperty) -> Result<PropertyKey, DispatchError> {1412 let key = rmrk_key.to_key::<T>()?;14131414 let scoped_key = RMRK_SCOPE1415 .apply(key)1416 .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)?;14171418 Ok(scoped_key)1419 }14201421 /// Form a Unique property, transforming a RMRK key into bytes (without assigning the scope yet)1422 /// and encoding the value from an arbitrary type into bytes.1423 pub fn encode_rmrk_property<E: Encode>(1424 rmrk_key: RmrkProperty,1425 value: &E,1426 ) -> Result<Property, DispatchError> {1427 let key = rmrk_key.to_key::<T>()?;14281429 let value = Self::encode_property_value(value)?;14301431 let property = Property { key, value };14321433 Ok(property)1434 }14351436 /// Encode property value from an arbitrary type into bytes for storage.1437 pub fn encode_property_value<E: Encode, S: Get<u32>>(1438 value: &E,1439 ) -> Result<BoundedBytes<S>, DispatchError> {1440 let value = value1441 .encode()1442 .try_into()1443 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;14441445 Ok(value)1446 }14471448 /// Decode property value from bytes into an arbitrary type.1449 pub fn decode_property_value<D: Decode, S: Get<u32>>(1450 vec: &BoundedBytes<S>,1451 ) -> Result<D, DispatchError> {1452 vec.decode()1453 .map_err(|_| <Error<T>>::UnableToDecodeRmrkData.into())1454 }14551456 /// Change the limit of a property value byte vector.1457 pub fn rebind<L, S>(vec: &BoundedVec<u8, L>) -> Result<BoundedVec<u8, S>, DispatchError>1458 where1459 BoundedVec<u8, S>: TryFrom<Vec<u8>>,1460 {1461 vec.rebind()1462 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())1463 }14641465 /// Initialize a new NFT collection with certain RMRK-scoped properties.1466 ///1467 /// See [`init_collection`](pallet_nonfungible::pallet::Pallet::init_collection) for more details.1468 fn init_collection(1469 sender: T::CrossAccountId,1470 data: CreateCollectionData<T::AccountId>,1471 properties: impl Iterator<Item = Property>,1472 ) -> Result<CollectionId, DispatchError> {1473 let collection_id = <PalletNft<T>>::init_collection(1474 sender.clone(),1475 sender,1476 data,1477 up_data_structs::CollectionFlags {1478 external: true,1479 ..Default::default()1480 },1481 );14821483 if let Err(DispatchError::Arithmetic(_)) = &collection_id {1484 return Err(<Error<T>>::NoAvailableCollectionId.into());1485 }14861487 <PalletCommon<T>>::set_scoped_collection_properties(1488 collection_id?,1489 RMRK_SCOPE,1490 properties,1491 )?;14921493 collection_id1494 }14951496 /// Mint a new NFT with certain RMRK-scoped properties. Sender must be the collection owner.1497 ///1498 /// See [`create_item`](pallet_nonfungible::pallet::Pallet::create_item) for more details.1499 pub fn create_nft(1500 sender: &T::CrossAccountId,1501 owner: &T::CrossAccountId,1502 collection: &NonfungibleHandle<T>,1503 properties: impl Iterator<Item = Property>,1504 ) -> Result<TokenId, DispatchError> {1505 let data = CreateNftExData {1506 properties: BoundedVec::default(),1507 owner: owner.clone(),1508 };15091510 let budget = budget::Value::new(NESTING_BUDGET);15111512 <PalletNft<T>>::create_item(collection, sender, data, &budget)?;15131514 let nft_id = <PalletNft<T>>::current_token_id(collection.id);15151516 <PalletNft<T>>::set_scoped_token_properties(collection.id, nft_id, RMRK_SCOPE, properties)?;15171518 Ok(nft_id)1519 }15201521 /// Burn an NFT, along with its nested children, limited by `max_burns`. The sender must be the token owner.1522 ///1523 /// See [`burn_recursively`](pallet_nonfungible::pallet::Pallet::burn_recursively) for more details.1524 fn destroy_nft(1525 sender: T::CrossAccountId,1526 collection_id: CollectionId,1527 token_id: TokenId,1528 max_burns: u32,1529 error_if_not_owned: Error<T>,1530 ) -> DispatchResultWithPostInfo {1531 let collection =1532 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;15331534 let token_data =1535 <TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;15361537 let from = token_data.owner;15381539 let owner_check_budget = budget::Value::new(NESTING_BUDGET);15401541 ensure!(1542 <PalletStructure<T>>::check_indirectly_owned(1543 sender.clone(),1544 collection_id,1545 token_id,1546 None,1547 &owner_check_budget1548 )?,1549 error_if_not_owned,1550 );15511552 let burns_budget = budget::Value::new(max_burns);1553 let breadth_budget = budget::Value::new(max_burns);15541555 <PalletNft<T>>::burn_recursively(1556 &collection,1557 &from,1558 token_id,1559 &burns_budget,1560 &breadth_budget,1561 )1562 }15631564 /// Add a sent token pending acceptance to the target owning token as a property.1565 fn insert_pending_child(1566 target: (CollectionId, TokenId),1567 child: (RmrkCollectionId, RmrkNftId),1568 ) -> DispatchResult {1569 Self::mutate_pending_children(target, |pending_children| {1570 pending_children.insert(child);1571 })1572 }15731574 /// Remove a sent token pending acceptance from the target token's properties.1575 fn remove_pending_child(1576 target: (CollectionId, TokenId),1577 child: (RmrkCollectionId, RmrkNftId),1578 ) -> DispatchResult {1579 Self::mutate_pending_children(target, |pending_children| {1580 pending_children.remove(&child);1581 })1582 }15831584 /// Apply a mutation to the property of a token containing sent tokens1585 /// that are currently pending acceptance.1586 fn mutate_pending_children(1587 (target_collection_id, target_nft_id): (CollectionId, TokenId),1588 f: impl FnOnce(&mut PendingChildrenSet),1589 ) -> DispatchResult {1590 <PalletNft<T>>::try_mutate_token_aux_property(1591 target_collection_id,1592 target_nft_id,1593 RMRK_SCOPE,1594 Self::get_scoped_property_key(PendingChildren)?,1595 |pending_children| -> DispatchResult {1596 let mut map = match pending_children {1597 Some(map) => Self::decode_property_value(map)?,1598 None => PendingChildrenSet::new(),1599 };16001601 f(&mut map);16021603 *pending_children = Some(Self::encode_property_value(&map)?);16041605 Ok(())1606 },1607 )1608 }16091610 /// Get an iterator from a token's property containing tokens sent to it1611 /// that are currently pending acceptance.1612 fn iterate_pending_children(1613 collection_id: CollectionId,1614 nft_id: TokenId,1615 ) -> Result<impl Iterator<Item = PendingChild>, DispatchError> {1616 let property = <PalletNft<T>>::token_aux_property((1617 collection_id,1618 nft_id,1619 RMRK_SCOPE,1620 Self::get_scoped_property_key(PendingChildren)?,1621 ));16221623 let pending_children = match property {1624 Some(map) => Self::decode_property_value(&map)?,1625 None => PendingChildrenSet::new(),1626 };16271628 Ok(pending_children.into_iter())1629 }16301631 /// Get incremented resource ID from within an NFT's properties and store the new latest ID.1632 /// Thus, the returned resource ID should be used.1633 ///1634 /// Resource IDs are unique only across an NFT.1635 fn acquire_next_resource_id(1636 collection_id: CollectionId,1637 nft_id: TokenId,1638 ) -> Result<RmrkResourceId, DispatchError> {1639 let resource_id: RmrkResourceId =1640 Self::get_nft_property_decoded(collection_id, nft_id, NextResourceId)?;16411642 let next_id = resource_id1643 .checked_add(1)1644 .ok_or(<Error<T>>::NoAvailableResourceId)?;16451646 <PalletNft<T>>::set_scoped_token_property(1647 collection_id,1648 nft_id,1649 RMRK_SCOPE,1650 Self::encode_rmrk_property(NextResourceId, &next_id)?,1651 )?;16521653 Ok(resource_id)1654 }16551656 /// Create and add a resource for a regular NFT, mark it as pending if the sender1657 /// is not the token owner. The sender must be the collection owner.1658 fn resource_add(1659 sender: T::AccountId,1660 collection_id: CollectionId,1661 nft_id: TokenId,1662 resource: RmrkResourceTypes,1663 ) -> Result<RmrkResourceId, DispatchError> {1664 let collection =1665 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1666 ensure!(collection.owner == sender, Error::<T>::NoPermission);16671668 let sender = T::CrossAccountId::from_sub(sender);1669 let budget = budget::Value::new(NESTING_BUDGET);16701671 let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)1672 .map_err(Self::map_unique_err_to_proxy)?1673 .ok_or::<DispatchError>(<Error<T>>::NoPermission.into())?;16741675 let pending = sender != nft_owner;16761677 let id = Self::acquire_next_resource_id(collection_id, nft_id)?;16781679 let resource_info = RmrkResourceInfo {1680 id,1681 resource,1682 pending,1683 pending_removal: false,1684 };16851686 <PalletNft<T>>::try_mutate_token_aux_property(1687 collection_id,1688 nft_id,1689 RMRK_SCOPE,1690 Self::get_scoped_property_key(ResourceId(id))?,1691 |value| -> DispatchResult {1692 *value = Some(Self::encode_property_value(&resource_info)?);16931694 Ok(())1695 },1696 )?;16971698 Ok(id)1699 }17001701 /// Designate a resource for erasure from an NFT, and remove it if the sender is the token owner.1702 /// The sender must be the collection owner.1703 fn resource_remove(1704 sender: T::AccountId,1705 collection_id: CollectionId,1706 nft_id: TokenId,1707 resource_id: RmrkResourceId,1708 ) -> DispatchResult {1709 let collection =1710 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1711 ensure!(collection.owner == sender, Error::<T>::NoPermission);17121713 let resource_id_key = Self::get_scoped_property_key(ResourceId(resource_id))?;17141715 let resource = <PalletNft<T>>::token_aux_property((1716 collection_id,1717 nft_id,1718 RMRK_SCOPE,1719 resource_id_key.clone(),1720 ))1721 .ok_or(<Error<T>>::ResourceDoesntExist)?;17221723 let resource_info: RmrkResourceInfo = Self::decode_property_value(&resource)?;17241725 let budget = up_data_structs::budget::Value::new(NESTING_BUDGET);1726 let topmost_owner =1727 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)?1728 .ok_or::<DispatchError>(<Error<T>>::NoPermission.into())?;17291730 let sender = T::CrossAccountId::from_sub(sender);1731 if topmost_owner == sender {1732 <PalletNft<T>>::remove_token_aux_property(1733 collection_id,1734 nft_id,1735 RMRK_SCOPE,1736 Self::get_scoped_property_key(ResourceId(resource_id))?,1737 );17381739 if let RmrkResourceTypes::Composable(resource) = resource_info.resource {1740 let base_id = resource.base;17411742 Self::remove_associated_base_id(collection_id, nft_id, base_id)?;1743 }1744 } else {1745 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {1746 res.pending_removal = true;17471748 Ok(())1749 })?;1750 }17511752 Ok(())1753 }17541755 /// Remove a Base ID from an NFT if they are associated.1756 /// The Base itself is deleted if the number of associated NFTs reaches 0.1757 fn remove_associated_base_id(1758 collection_id: CollectionId,1759 nft_id: TokenId,1760 base_id: RmrkBaseId,1761 ) -> DispatchResult {1762 <PalletNft<T>>::try_mutate_token_aux_property(1763 collection_id,1764 nft_id,1765 RMRK_SCOPE,1766 Self::get_scoped_property_key(AssociatedBases)?,1767 |value| -> DispatchResult {1768 let mut bases: BasesMap = match value {1769 Some(value) => Self::decode_property_value(value)?,1770 None => BasesMap::new(),1771 };17721773 let remaining = bases.get(&base_id);17741775 if let Some(remaining) = remaining {1776 if let Some(0) | None = remaining.checked_sub(1) {1777 bases.remove(&base_id);1778 }1779 }17801781 *value = Some(Self::encode_property_value(&bases)?);1782 Ok(())1783 },1784 )1785 }17861787 /// Apply a mutation to a resource stored in the token properties of an NFT.1788 fn try_mutate_resource_info(1789 collection_id: CollectionId,1790 nft_id: TokenId,1791 resource_id: RmrkResourceId,1792 f: impl FnOnce(&mut RmrkResourceInfo) -> DispatchResult,1793 ) -> DispatchResult {1794 <PalletNft<T>>::try_mutate_token_aux_property(1795 collection_id,1796 nft_id,1797 RMRK_SCOPE,1798 Self::get_scoped_property_key(ResourceId(resource_id))?,1799 |value| match value {1800 Some(value) => {1801 let mut resource_info: RmrkResourceInfo = Self::decode_property_value(value)?;18021803 f(&mut resource_info)?;18041805 *value = Self::encode_property_value(&resource_info)?;18061807 Ok(())1808 }1809 None => Err(<Error<T>>::ResourceDoesntExist.into()),1810 },1811 )1812 }18131814 /// Change the owner of an NFT collection, ensuring that the sender is the current owner.1815 fn change_collection_owner(1816 collection_id: CollectionId,1817 collection_type: misc::CollectionType,1818 sender: T::AccountId,1819 new_owner: T::AccountId,1820 ) -> DispatchResult {1821 let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;1822 Self::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))?;18231824 let mut collection = collection.into_inner();18251826 collection.owner = new_owner;1827 collection.save()1828 }18291830 /// Ensure that an account is the collection owner/issuer, return an error if not.1831 pub fn check_collection_owner(1832 collection: &NonfungibleHandle<T>,1833 account: &T::CrossAccountId,1834 ) -> DispatchResult {1835 collection1836 .check_is_owner(account)1837 .map_err(Self::map_unique_err_to_proxy)1838 }18391840 /// Get the latest yet-unused RMRK collection index from the storage.1841 pub fn last_collection_idx() -> RmrkCollectionId {1842 <CollectionIndex<T>>::get()1843 }18441845 /// Get a mapping from a RMRK collection ID to its corresponding Unique collection ID.1846 pub fn unique_collection_id(1847 rmrk_collection_id: RmrkCollectionId,1848 ) -> Result<CollectionId, DispatchError> {1849 <UniqueCollectionId<T>>::try_get(rmrk_collection_id)1850 .map_err(|_| <Error<T>>::CollectionUnknown.into())1851 }18521853 /// Get a mapping from a Unique collection ID to its RMRK collection ID counterpart, if it exists.1854 pub fn rmrk_collection_id(1855 unique_collection_id: CollectionId,1856 ) -> Result<RmrkCollectionId, DispatchError> {1857 Self::get_collection_property_decoded(unique_collection_id, RmrkInternalCollectionId)1858 }18591860 /// Fetch a Unique NFT collection.1861 pub fn get_nft_collection(1862 collection_id: CollectionId,1863 ) -> Result<NonfungibleHandle<T>, DispatchError> {1864 let collection = <CollectionHandle<T>>::try_get(collection_id)1865 .map_err(|_| <Error<T>>::CollectionUnknown)?;18661867 match collection.mode {1868 CollectionMode::NFT => Ok(NonfungibleHandle::cast(collection)),1869 _ => Err(<Error<T>>::CollectionUnknown.into()),1870 }1871 }18721873 /// Check if an NFT collection with such an ID exists.1874 pub fn collection_exists(collection_id: CollectionId) -> bool {1875 <CollectionHandle<T>>::try_get(collection_id).is_ok()1876 }18771878 /// Fetch and decode a RMRK-scoped collection property value in bytes.1879 pub fn get_collection_property(1880 collection_id: CollectionId,1881 key: RmrkProperty,1882 ) -> Result<PropertyValue, DispatchError> {1883 let collection_property = <PalletCommon<T>>::collection_properties(collection_id)1884 .get(&Self::get_scoped_property_key(key)?)1885 .ok_or(<Error<T>>::CollectionUnknown)?1886 .clone();18871888 Ok(collection_property)1889 }18901891 /// Fetch a RMRK-scoped collection property and decode it from bytes into an appropriate type.1892 pub fn get_collection_property_decoded<V: Decode>(1893 collection_id: CollectionId,1894 key: RmrkProperty,1895 ) -> Result<V, DispatchError> {1896 Self::decode_property_value(&Self::get_collection_property(collection_id, key)?)1897 }18981899 /// Get the type of a collection stored as a scoped property.1900 ///1901 /// RMRK Core proxy differentiates between regular collections as well as RMRK Bases as collections.1902 pub fn get_collection_type(1903 collection_id: CollectionId,1904 ) -> Result<misc::CollectionType, DispatchError> {1905 Self::get_collection_property_decoded(collection_id, CollectionType).map_err(|err| {1906 if err != <Error<T>>::CollectionUnknown.into() {1907 <Error<T>>::CorruptedCollectionType.into()1908 } else {1909 err1910 }1911 })1912 }19131914 /// Ensure that the type of the collection equals the provided type,1915 /// otherwise return an error.1916 pub fn ensure_collection_type(1917 collection_id: CollectionId,1918 collection_type: misc::CollectionType,1919 ) -> DispatchResult {1920 let actual_type = Self::get_collection_type(collection_id)?;1921 ensure!(1922 actual_type == collection_type,1923 <CommonError<T>>::NoPermission1924 );19251926 Ok(())1927 }19281929 /// Fetch an NFT collection, but make sure it has the appropriate type.1930 pub fn get_typed_nft_collection(1931 collection_id: CollectionId,1932 collection_type: misc::CollectionType,1933 ) -> Result<NonfungibleHandle<T>, DispatchError> {1934 Self::ensure_collection_type(collection_id, collection_type)?;19351936 Self::get_nft_collection(collection_id)1937 }19381939 /// Same as [`get_typed_nft_collection`](crate::pallet::Pallet::get_typed_nft_collection),1940 /// but also return the Unique collection ID.1941 pub fn get_typed_nft_collection_mapped(1942 rmrk_collection_id: RmrkCollectionId,1943 collection_type: misc::CollectionType,1944 ) -> Result<(NonfungibleHandle<T>, CollectionId), DispatchError> {1945 let unique_collection_id = match collection_type {1946 misc::CollectionType::Regular => Self::unique_collection_id(rmrk_collection_id)?,1947 _ => rmrk_collection_id.into(),1948 };19491950 let collection = Self::get_typed_nft_collection(unique_collection_id, collection_type)?;19511952 Ok((collection, unique_collection_id))1953 }19541955 /// Fetch and decode a RMRK-scoped NFT property value in bytes.1956 pub fn get_nft_property(1957 collection_id: CollectionId,1958 nft_id: TokenId,1959 key: RmrkProperty,1960 ) -> Result<PropertyValue, DispatchError> {1961 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))1962 .get(&Self::get_scoped_property_key(key)?)1963 .ok_or(<Error<T>>::RmrkPropertyIsNotFound)?1964 .clone();19651966 Ok(nft_property)1967 }19681969 /// Fetch a RMRK-scoped NFT property and decode it from bytes into an appropriate type.1970 pub fn get_nft_property_decoded<V: Decode>(1971 collection_id: CollectionId,1972 nft_id: TokenId,1973 key: RmrkProperty,1974 ) -> Result<V, DispatchError> {1975 Self::decode_property_value(&Self::get_nft_property(collection_id, nft_id, key)?)1976 }19771978 /// Check that an NFT exists.1979 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {1980 <TokenData<T>>::contains_key((collection_id, nft_id))1981 }19821983 /// Get the type of an NFT stored as a scoped property.1984 ///1985 /// RMRK Core proxy differentiates between regular NFTs, and RMRK Parts and Themes.1986 pub fn get_nft_type(1987 collection_id: CollectionId,1988 token_id: TokenId,1989 ) -> Result<NftType, DispatchError> {1990 Self::get_nft_property_decoded(collection_id, token_id, TokenType)1991 .map_err(|_| <Error<T>>::NoAvailableNftId.into())1992 }19931994 /// Ensure that the type of the NFT equals the provided type, otherwise return an error.1995 pub fn ensure_nft_type(1996 collection_id: CollectionId,1997 token_id: TokenId,1998 nft_type: NftType,1999 ) -> DispatchResult {2000 let actual_type = Self::get_nft_type(collection_id, token_id)?;2001 ensure!(actual_type == nft_type, <Error<T>>::NoPermission);20022003 Ok(())2004 }20052006 /// Ensure that an account is the owner of the token, either directly2007 /// or at the top of the nesting hierarchy; return an error if it is not.2008 pub fn ensure_nft_owner(2009 collection_id: CollectionId,2010 token_id: TokenId,2011 possible_owner: &T::CrossAccountId,2012 nesting_budget: &dyn budget::Budget,2013 ) -> DispatchResult {2014 let is_owned = <PalletStructure<T>>::check_indirectly_owned(2015 possible_owner.clone(),2016 collection_id,2017 token_id,2018 None,2019 nesting_budget,2020 )2021 .map_err(Self::map_unique_err_to_proxy)?;20222023 ensure!(is_owned, <Error<T>>::NoPermission);20242025 Ok(())2026 }20272028 /// Fetch non-scoped properties of a collection or a token that match the filter keys supplied,2029 /// or, if None are provided, return all non-scoped properties.2030 pub fn filter_user_properties<Key, Value, R, Mapper>(2031 collection_id: CollectionId,2032 token_id: Option<TokenId>,2033 filter_keys: Option<Vec<RmrkPropertyKey>>,2034 mapper: Mapper,2035 ) -> Result<Vec<R>, DispatchError>2036 where2037 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,2038 Value: Decode + Default,2039 Mapper: Fn(Key, Value) -> R,2040 {2041 filter_keys2042 .map(|keys| {2043 let properties = keys2044 .into_iter()2045 .filter_map(|key| {2046 let key: Key = key.try_into().ok()?;20472048 let value = match token_id {2049 Some(token_id) => Self::get_nft_property_decoded(2050 collection_id,2051 token_id,2052 UserProperty(key.as_ref()),2053 ),2054 None => Self::get_collection_property_decoded(2055 collection_id,2056 UserProperty(key.as_ref()),2057 ),2058 }2059 .ok()?;20602061 Some(mapper(key, value))2062 })2063 .collect();20642065 Ok(properties)2066 })2067 .unwrap_or_else(|| {2068 let properties =2069 Self::iterate_user_properties(collection_id, token_id, mapper)?.collect();20702071 Ok(properties)2072 })2073 }20742075 /// Get all non-scoped properties from a collection or a token, and apply some transformation,2076 /// supplied by `mapper`, to each key-value pair.2077 pub fn iterate_user_properties<Key, Value, R, Mapper>(2078 collection_id: CollectionId,2079 token_id: Option<TokenId>,2080 mapper: Mapper,2081 ) -> Result<impl Iterator<Item = R>, DispatchError>2082 where2083 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,2084 Value: Decode + Default,2085 Mapper: Fn(Key, Value) -> R,2086 {2087 let properties = match token_id {2088 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),2089 None => <PalletCommon<T>>::collection_properties(collection_id),2090 };20912092 let properties = properties.into_iter().filter_map(move |(key, value)| {2093 let key = strip_key_prefix(&key, USER_PROPERTY_PREFIX)?;20942095 let key: Key = key.to_vec().try_into().ok()?;2096 let value: Value = value.decode().ok()?;20972098 Some(mapper(key, value))2099 });21002101 Ok(properties)2102 }21032104 /// Match Unique errors to RMRK's own and return the RMRK error if a match is successful.2105 fn map_unique_err_to_proxy(err: DispatchError) -> DispatchError {2106 map_unique_err_to_proxy! {2107 match err {2108 CommonError::NoPermission => NoPermission,2109 CommonError::CollectionTokenLimitExceeded => CollectionFullOrLocked,2110 CommonError::PublicMintingNotAllowed => NoPermission,2111 CommonError::TokenNotFound => NoAvailableNftId,2112 CommonError::ApprovedValueTooLow => NoPermission,2113 CommonError::CantDestroyNotEmptyCollection => CollectionNotEmpty,2114 StructureError::TokenNotFound => NoAvailableNftId,2115 StructureError::OuroborosDetected => CannotSendToDescendentOrSelf,2116 }2117 }2118 }2119}pallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/misc.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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/>.
-
-//! Miscellaneous helpers and utilities used by the proxy pallet.
-
-use super::*;
-use codec::{Encode, Decode, Error};
-
-/// Match an error to a provided pattern matcher and get
-/// the corresponding error of another type if a match is successful.
-#[macro_export]
-macro_rules! map_unique_err_to_proxy {
- (match $err:ident { $($unique_err_ty:ident :: $unique_err:ident => $proxy_err:ident),+ $(,)? }) => {
- $(
- if $err == <$unique_err_ty<T>>::$unique_err.into() {
- return <Error<T>>::$proxy_err.into()
- } else
- )+ {
- $err
- }
- };
-}
-
-/// Interface to decode some serialized bytes into an arbitrary type `T`,
-/// preferably if these bytes were originally encoded from `T`.
-pub trait RmrkDecode<T: Decode, S> {
- /// Try to decode self into an arbitrary type `T`.
- fn decode(&self) -> Result<T, Error>;
-}
-
-impl<T: Decode, S> RmrkDecode<T, S> for BoundedVec<u8, S> {
- fn decode(&self) -> Result<T, Error> {
- let mut value = self.as_slice();
-
- T::decode(&mut value)
- }
-}
-
-/// Interface to "rebind" - change the limit of a bounded byte vector.
-pub trait RmrkRebind<T, S> {
- /// Try to change the limit of a bounded byte vector.
- fn rebind(&self) -> Result<BoundedVec<u8, S>, Error>;
-}
-
-impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>
-where
- BoundedVec<u8, S>: TryFrom<Vec<u8>>,
-{
- fn rebind(&self) -> Result<BoundedVec<u8, S>, Error> {
- BoundedVec::<u8, S>::try_from(self.clone().into_inner())
- .map_err(|_| "BoundedVec exceeds its limit".into())
- }
-}
-
-/// RMRK Base shares functionality with a regular collection, and is thus
-/// stored as one, but they are used for different purposes and need to be differentiated.
-#[derive(Encode, Decode, PartialEq, Eq)]
-pub enum CollectionType {
- Regular,
- Base,
-}
-
-/// RMRK Base, being stored as a collection, can have different kinds of tokens,
-/// all except the `Regular` type, which is attributed to `Regular` collection.
-#[derive(Encode, Decode, PartialEq, Eq)]
-pub enum NftType {
- Regular,
- FixedPart,
- SlotPart,
- Theme,
-}
pallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/property.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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/>.
-
-//! Details of storing and handling RMRK properties.
-
-use super::*;
-use up_data_structs::PropertyScope;
-use core::convert::AsRef;
-
-/// Property prefix for storing resources.
-pub const RESOURCE_ID_PREFIX: &str = "rsid-";
-/// Property prefix for storing custom user-defined properties.
-pub const USER_PROPERTY_PREFIX: &str = "userprop-";
-/// Property scope for RMRK, used to signify that this property
-/// was created and is used by RMRK.
-pub const RMRK_SCOPE: PropertyScope = PropertyScope::Rmrk;
-
-/// Predefined RMRK property keys for storage of RMRK data format on the Unique chain.
-pub enum RmrkProperty<'r> {
- Metadata,
- CollectionType,
- RmrkInternalCollectionId,
- TokenType,
- Transferable,
- RoyaltyInfo,
- Equipped,
- ResourcePriorities,
- NextResourceId,
- ResourceId(RmrkResourceId),
- PendingNftAccept,
- PendingChildren,
- AssociatedBases,
- Parts,
- Base,
- Src,
- EquippedNft,
- BaseType,
- ExternalPartId,
- EquippableList,
- ZIndex,
- ThemeName,
- ThemeInherit,
- UserProperty(&'r [u8]),
-}
-
-impl<'r> RmrkProperty<'r> {
- /// Convert a predefined RMRK property key enum into string bytes.
- pub fn to_key<T: Config>(self) -> Result<PropertyKey, Error<T>> {
- fn get_bytes<T: AsRef<[u8]>>(container: &T) -> &[u8] {
- container.as_ref()
- }
-
- macro_rules! key {
- ($($component:expr),+) => {
- PropertyKey::try_from([$(key!(@ &$component)),+].concat())
- .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)
- };
-
- (@ $key:expr) => {
- get_bytes($key)
- };
- }
-
- match self {
- Self::Metadata => key!("metadata"),
- Self::CollectionType => key!("collection-type"),
- Self::RmrkInternalCollectionId => key!("internal-id"),
- Self::TokenType => key!("token-type"),
- Self::Transferable => key!("transferable"),
- Self::RoyaltyInfo => key!("royalty-info"),
- Self::Equipped => key!("equipped"),
- Self::ResourcePriorities => key!("resource-priorities"),
- Self::NextResourceId => key!("next-resource-id"),
- Self::ResourceId(id) => key!(RESOURCE_ID_PREFIX, id.to_le_bytes()),
- Self::PendingNftAccept => key!("pending-nft-accept"),
- Self::PendingChildren => key!("pending-children"),
- Self::AssociatedBases => key!("assoc-bases"),
- Self::Parts => key!("parts"),
- Self::Base => key!("base"),
- Self::Src => key!("src"),
- Self::EquippedNft => key!("equipped-nft"),
- Self::BaseType => key!("base-type"),
- Self::ExternalPartId => key!("ext-part-id"),
- Self::EquippableList => key!("equippable-list"),
- Self::ZIndex => key!("z-index"),
- Self::ThemeName => key!("theme-name"),
- Self::ThemeInherit => key!("theme-inherit"),
- Self::UserProperty(name) => key!(USER_PROPERTY_PREFIX, name),
- }
- }
-}
-
-/// Strip a property key of its prefix and RMRK scope.
-pub fn strip_key_prefix(key: &PropertyKey, prefix: &str) -> Option<PropertyKey> {
- let key_prefix = PropertyKey::try_from(prefix.as_bytes().to_vec()).ok()?;
- let key_prefix = RMRK_SCOPE.apply(key_prefix).ok()?;
-
- key.as_slice()
- .strip_prefix(key_prefix.as_slice())?
- .to_vec()
- .try_into()
- .ok()
-}
-
-/// Check that the key has the prefix.
-pub fn is_valid_key_prefix(key: &PropertyKey, prefix: &str) -> bool {
- strip_key_prefix(key, prefix).is_some()
-}
pallets/proxy-rmrk-core/src/rpc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/rpc.rs
+++ /dev/null
@@ -1,293 +0,0 @@
-// 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/>.
-
-//! Realizations of RMRK RPCs (remote procedure calls) related to the Core pallet.
-
-use super::*;
-
-/// Get the latest created collection ID.
-pub fn last_collection_idx<T: Config>() -> Result<RmrkCollectionId, DispatchError> {
- Ok(<Pallet<T>>::last_collection_idx())
-}
-
-/// Get collection info by ID.
-pub fn collection_by_id<T: Config>(
- collection_id: RmrkCollectionId,
-) -> Result<Option<RmrkCollectionInfo<T::AccountId>>, DispatchError> {
- let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(
- collection_id,
- misc::CollectionType::Regular,
- ) {
- Ok(c) => c,
- Err(_) => return Ok(None),
- };
-
- let nfts_count = collection.total_supply();
-
- Ok(Some(RmrkCollectionInfo {
- issuer: collection.owner.clone(),
- metadata: <Pallet<T>>::get_collection_property_decoded(
- collection_id,
- RmrkProperty::Metadata,
- )?,
- max: collection.limits.token_limit,
- symbol: <Pallet<T>>::rebind(&collection.token_prefix)?,
- nfts_count,
- }))
-}
-
-/// Get NFT info by collection and NFT IDs.
-pub fn nft_by_id<T: Config>(
- collection_id: RmrkCollectionId,
- nft_by_id: RmrkNftId,
-) -> Result<Option<RmrkInstanceInfo<T::AccountId>>, DispatchError> {
- let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(
- collection_id,
- misc::CollectionType::Regular,
- ) {
- Ok(c) => c,
- Err(_) => return Ok(None),
- };
-
- let nft_id = TokenId(nft_by_id);
- if !<Pallet<T>>::nft_exists(collection_id, nft_id) {
- return Ok(None);
- }
-
- let owner = match collection.token_owner(nft_id) {
- Ok(owner) => match T::CrossTokenAddressMapping::address_to_token(&owner) {
- Some((col, tok)) => {
- let rmrk_collection = <Pallet<T>>::rmrk_collection_id(col)?;
-
- RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(rmrk_collection, tok.0)
- }
- None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone()),
- },
- _ => return Ok(None),
- };
-
- Ok(Some(RmrkInstanceInfo {
- owner: owner,
- royalty: <Pallet<T>>::get_nft_property_decoded(
- collection_id,
- nft_id,
- RmrkProperty::RoyaltyInfo,
- )?,
- metadata: <Pallet<T>>::get_nft_property_decoded(
- collection_id,
- nft_id,
- RmrkProperty::Metadata,
- )?,
- equipped: <Pallet<T>>::get_nft_property_decoded(
- collection_id,
- nft_id,
- RmrkProperty::Equipped,
- )?,
- pending: <Pallet<T>>::get_nft_property_decoded(
- collection_id,
- nft_id,
- RmrkProperty::PendingNftAccept,
- )?,
- }))
-}
-
-/// Get tokens owned by an account in a collection.
-pub fn account_tokens<T: Config>(
- account_id: T::AccountId,
- collection_id: RmrkCollectionId,
-) -> Result<Vec<RmrkNftId>, DispatchError> {
- let cross_account_id = CrossAccountId::from_sub(account_id);
-
- let (collection, collection_id) = match <Pallet<T>>::get_typed_nft_collection_mapped(
- collection_id,
- misc::CollectionType::Regular,
- ) {
- Ok(c) => c,
- Err(_) => return Ok(Vec::new()),
- };
-
- let tokens = collection
- .account_tokens(cross_account_id)
- .into_iter()
- .filter(|token| {
- let is_pending = <Pallet<T>>::get_nft_property_decoded(
- collection_id,
- *token,
- RmrkProperty::PendingNftAccept,
- )
- .unwrap_or(true);
-
- !is_pending
- })
- .map(|token| token.0)
- .collect();
-
- Ok(tokens)
-}
-
-/// Get tokens nested in an NFT - its direct children (not the children's children).
-pub fn nft_children<T: Config>(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
-) -> Result<Vec<RmrkNftChild>, DispatchError> {
- let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {
- Ok(id) => id,
- Err(_) => return Ok(Vec::new()),
- };
- let nft_id = TokenId(nft_id);
- if !<Pallet<T>>::nft_exists(collection_id, nft_id) {
- return Ok(Vec::new());
- }
-
- Ok(
- pallet_nonfungible::TokenChildren::<T>::iter_prefix((collection_id, nft_id))
- .filter_map(|((child_collection, child_token), _)| {
- let rmrk_child_collection =
- <Pallet<T>>::rmrk_collection_id(child_collection).ok()?;
-
- Some(RmrkNftChild {
- collection_id: rmrk_child_collection,
- nft_id: child_token.0,
- })
- })
- .chain(
- <Pallet<T>>::iterate_pending_children(collection_id, nft_id)?.map(
- |(child_collection, child_nft_id)| RmrkNftChild {
- collection_id: child_collection,
- nft_id: child_nft_id,
- },
- ),
- )
- .collect(),
- )
-}
-
-/// Get collection properties, created by the user - not the proxy-specific properties.
-pub fn collection_properties<T: Config>(
- collection_id: RmrkCollectionId,
- filter_keys: Option<Vec<RmrkPropertyKey>>,
-) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {
- Ok(id) => id,
- Err(_) => return Ok(Vec::new()),
- };
- if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {
- return Ok(Vec::new());
- }
-
- let properties = <Pallet<T>>::filter_user_properties(
- collection_id,
- /* token_id = */ None,
- filter_keys,
- |key, value| RmrkPropertyInfo { key, value },
- )?;
-
- Ok(properties)
-}
-
-/// Get NFT properties, created by the user - not the proxy-specific properties.
-pub fn nft_properties<T: Config>(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- filter_keys: Option<Vec<RmrkPropertyKey>>,
-) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {
- Ok(id) => id,
- Err(_) => return Ok(Vec::new()),
- };
- let token_id = TokenId(nft_id);
-
- if <Pallet<T>>::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {
- return Ok(Vec::new());
- }
-
- let properties = <Pallet<T>>::filter_user_properties(
- collection_id,
- Some(token_id),
- filter_keys,
- |key, value| RmrkPropertyInfo { key, value },
- )?;
-
- Ok(properties)
-}
-
-/// Get full information on each resource of an NFT, including pending.
-pub fn nft_resources<T: Config>(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
-) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
- let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {
- Ok(id) => id,
- Err(_) => return Ok(Vec::new()),
- };
- if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {
- return Ok(Vec::new());
- }
-
- let nft_id = TokenId(nft_id);
- if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {
- return Ok(Vec::new());
- }
-
- let resources = <pallet_nonfungible::Pallet<T>>::iterate_token_aux_properties(
- collection_id,
- nft_id,
- PropertyScope::Rmrk,
- )
- .filter_map(|(key, value)| {
- if !is_valid_key_prefix(&key, RESOURCE_ID_PREFIX) {
- return None;
- }
-
- let resource_info: RmrkResourceInfo = <Pallet<T>>::decode_property_value(&value).ok()?;
-
- Some(resource_info)
- })
- .collect();
-
- Ok(resources)
-}
-
-/// Get the priority of a resource in an NFT.
-pub fn nft_resource_priority<T: Config>(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- resource_id: RmrkResourceId,
-) -> Result<Option<u32>, DispatchError> {
- let collection_id = match <Pallet<T>>::unique_collection_id(collection_id) {
- Ok(id) => id,
- Err(_) => return Ok(None),
- };
- if <Pallet<T>>::ensure_collection_type(collection_id, misc::CollectionType::Regular).is_err() {
- return Ok(None);
- }
-
- let nft_id = TokenId(nft_id);
- if <Pallet<T>>::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() {
- return Ok(None);
- }
-
- let priorities: Vec<_> = <Pallet<T>>::get_nft_property_decoded(
- collection_id,
- nft_id,
- RmrkProperty::ResourcePriorities,
- )?;
- Ok(priorities
- .into_iter()
- .enumerate()
- .find(|(_, id)| *id == resource_id)
- .map(|(priority, _): (usize, RmrkResourceId)| priority as u32))
-}
pallets/proxy-rmrk-core/src/weights.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/weights.rs
+++ /dev/null
@@ -1,480 +0,0 @@
-// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
-
-//! Autogenerated weights for pallet_proxy_rmrk_core
-//!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
-
-// Executed Command:
-// target/release/unique-collator
-// benchmark
-// pallet
-// --pallet
-// pallet-proxy-rmrk-core
-// --wasm-execution
-// compiled
-// --extrinsic
-// *
-// --template
-// .maintain/frame-weight-template.hbs
-// --steps=50
-// --repeat=80
-// --heap-pages=4096
-// --output=./pallets/proxy-rmrk-core/src/weights.rs
-
-#![cfg_attr(rustfmt, rustfmt_skip)]
-#![allow(unused_parens)]
-#![allow(unused_imports)]
-#![allow(clippy::unnecessary_cast)]
-
-use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
-use sp_std::marker::PhantomData;
-
-/// Weight functions needed for pallet_proxy_rmrk_core.
-pub trait WeightInfo {
- fn create_collection() -> Weight;
- fn destroy_collection() -> Weight;
- fn change_collection_issuer() -> Weight;
- fn lock_collection() -> Weight;
- fn mint_nft(b: u32, ) -> Weight;
- fn burn_nft(b: u32, ) -> Weight;
- fn send() -> Weight;
- fn accept_nft() -> Weight;
- fn reject_nft() -> Weight;
- fn set_property() -> Weight;
- fn set_priority() -> Weight;
- fn add_basic_resource() -> Weight;
- fn add_composable_resource() -> Weight;
- fn add_slot_resource() -> Weight;
- fn remove_resource() -> Weight;
- fn accept_resource() -> Weight;
- fn accept_resource_removal() -> Weight;
-}
-
-/// Weights for pallet_proxy_rmrk_core using the Substrate node and recommended hardware.
-pub struct SubstrateWeight<T>(PhantomData<T>);
-impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
- // Storage: Common CreatedCollectionCount (r:1 w:1)
- // Storage: Common DestroyedCollectionCount (r:1 w:0)
- // Storage: System Account (r:2 w:2)
- // Storage: RmrkCore CollectionIndex (r:1 w:1)
- // Storage: Common CollectionPropertyPermissions (r:0 w:1)
- // Storage: Common CollectionProperties (r:0 w:1)
- // Storage: Common CollectionById (r:0 w:1)
- // Storage: RmrkCore UniqueCollectionId (r:0 w:1)
- fn create_collection() -> Weight {
- Weight::from_ref_time(49_754_000)
- .saturating_add(T::DbWeight::get().reads(5 as u64))
- .saturating_add(T::DbWeight::get().writes(8 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:1)
- // Storage: Common CollectionById (r:1 w:1)
- // Storage: Nonfungible TokenData (r:1 w:0)
- // Storage: Common DestroyedCollectionCount (r:1 w:1)
- // Storage: Nonfungible TokensMinted (r:0 w:1)
- // Storage: Nonfungible TokensBurnt (r:0 w:1)
- // Storage: Common AdminAmount (r:0 w:1)
- fn destroy_collection() -> Weight {
- Weight::from_ref_time(48_588_000)
- .saturating_add(T::DbWeight::get().reads(5 as u64))
- .saturating_add(T::DbWeight::get().writes(6 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:1)
- // Storage: Common CollectionProperties (r:1 w:0)
- fn change_collection_issuer() -> Weight {
- Weight::from_ref_time(25_054_000)
- .saturating_add(T::DbWeight::get().reads(3 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:1)
- // Storage: Nonfungible TokensMinted (r:1 w:0)
- // Storage: Nonfungible TokensBurnt (r:1 w:0)
- fn lock_collection() -> Weight {
- Weight::from_ref_time(26_483_000)
- .saturating_add(T::DbWeight::get().reads(5 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokensMinted (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:2 w:2)
- fn mint_nft(b: u32, ) -> Weight {
- Weight::from_ref_time(62_419_000)
- // Standard Error: 7_000
- .saturating_add(Weight::from_ref_time(12_325_000).saturating_mul(b as u64))
- .saturating_add(T::DbWeight::get().reads(6 as u64))
- .saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(b as u64)))
- .saturating_add(T::DbWeight::get().writes(5 as u64))
- .saturating_add(T::DbWeight::get().writes((1 as u64).saturating_mul(b as u64)))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:1 w:1)
- // Storage: Nonfungible TokenChildren (r:1 w:0)
- // Storage: Nonfungible TokensBurnt (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible Allowance (r:1 w:0)
- // Storage: Nonfungible Owned (r:0 w:1)
- // Storage: Nonfungible TokenProperties (r:0 w:1)
- fn burn_nft(b: u32, ) -> Weight {
- (Weight::from_ref_time(0))
- // Standard Error: 1_488_000
- .saturating_add(Weight::from_ref_time(298_367_000).saturating_mul(b as u64))
- .saturating_add(T::DbWeight::get().reads(9 as u64))
- .saturating_add(T::DbWeight::get().reads((4 as u64).saturating_mul(b as u64)))
- .saturating_add(T::DbWeight::get().writes(6 as u64))
- .saturating_add(T::DbWeight::get().writes((4 as u64).saturating_mul(b as u64)))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:0)
- // Storage: Nonfungible AccountBalance (r:2 w:2)
- // Storage: Nonfungible Allowance (r:1 w:0)
- // Storage: Nonfungible TokenChildren (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:2)
- fn send() -> Weight {
- Weight::from_ref_time(81_942_000)
- .saturating_add(T::DbWeight::get().reads(12 as u64))
- .saturating_add(T::DbWeight::get().writes(6 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:2 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:2 w:0)
- // Storage: Nonfungible TokenData (r:6 w:1)
- // Storage: Nonfungible AccountBalance (r:2 w:2)
- // Storage: Nonfungible Allowance (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- // Storage: Nonfungible TokenChildren (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:2)
- fn accept_nft() -> Weight {
- Weight::from_ref_time(97_925_000)
- .saturating_add(T::DbWeight::get().reads(16 as u64))
- .saturating_add(T::DbWeight::get().writes(8 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:5)
- // Storage: Nonfungible TokenProperties (r:1 w:5)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- // Storage: Nonfungible TokenChildren (r:9 w:4)
- // Storage: Nonfungible TokensBurnt (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:5 w:5)
- // Storage: Nonfungible Allowance (r:5 w:0)
- // Storage: Nonfungible Owned (r:0 w:5)
- fn reject_nft() -> Weight {
- Weight::from_ref_time(277_794_000)
- .saturating_add(T::DbWeight::get().reads(30 as u64))
- .saturating_add(T::DbWeight::get().writes(26 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:5 w:0)
- fn set_property() -> Weight {
- Weight::from_ref_time(54_657_000)
- .saturating_add(T::DbWeight::get().reads(9 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:5 w:0)
- fn set_priority() -> Weight {
- Weight::from_ref_time(55_056_000)
- .saturating_add(T::DbWeight::get().reads(9 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn add_basic_resource() -> Weight {
- Weight::from_ref_time(61_673_000)
- .saturating_add(T::DbWeight::get().reads(10 as u64))
- .saturating_add(T::DbWeight::get().writes(2 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:2 w:2)
- fn add_composable_resource() -> Weight {
- Weight::from_ref_time(67_125_000)
- .saturating_add(T::DbWeight::get().reads(11 as u64))
- .saturating_add(T::DbWeight::get().writes(3 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn add_slot_resource() -> Weight {
- Weight::from_ref_time(69_058_000)
- .saturating_add(T::DbWeight::get().reads(10 as u64))
- .saturating_add(T::DbWeight::get().writes(2 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:5 w:0)
- fn remove_resource() -> Weight {
- Weight::from_ref_time(53_427_000)
- .saturating_add(T::DbWeight::get().reads(9 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn accept_resource() -> Weight {
- Weight::from_ref_time(50_623_000)
- .saturating_add(T::DbWeight::get().reads(9 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn accept_resource_removal() -> Weight {
- Weight::from_ref_time(50_917_000)
- .saturating_add(T::DbWeight::get().reads(9 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
-}
-
-// For backwards compatibility and tests
-impl WeightInfo for () {
- // Storage: Common CreatedCollectionCount (r:1 w:1)
- // Storage: Common DestroyedCollectionCount (r:1 w:0)
- // Storage: System Account (r:2 w:2)
- // Storage: RmrkCore CollectionIndex (r:1 w:1)
- // Storage: Common CollectionPropertyPermissions (r:0 w:1)
- // Storage: Common CollectionProperties (r:0 w:1)
- // Storage: Common CollectionById (r:0 w:1)
- // Storage: RmrkCore UniqueCollectionId (r:0 w:1)
- fn create_collection() -> Weight {
- Weight::from_ref_time(49_754_000)
- .saturating_add(RocksDbWeight::get().reads(5 as u64))
- .saturating_add(RocksDbWeight::get().writes(8 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:1)
- // Storage: Common CollectionById (r:1 w:1)
- // Storage: Nonfungible TokenData (r:1 w:0)
- // Storage: Common DestroyedCollectionCount (r:1 w:1)
- // Storage: Nonfungible TokensMinted (r:0 w:1)
- // Storage: Nonfungible TokensBurnt (r:0 w:1)
- // Storage: Common AdminAmount (r:0 w:1)
- fn destroy_collection() -> Weight {
- Weight::from_ref_time(48_588_000)
- .saturating_add(RocksDbWeight::get().reads(5 as u64))
- .saturating_add(RocksDbWeight::get().writes(6 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:1)
- // Storage: Common CollectionProperties (r:1 w:0)
- fn change_collection_issuer() -> Weight {
- Weight::from_ref_time(25_054_000)
- .saturating_add(RocksDbWeight::get().reads(3 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:1)
- // Storage: Nonfungible TokensMinted (r:1 w:0)
- // Storage: Nonfungible TokensBurnt (r:1 w:0)
- fn lock_collection() -> Weight {
- Weight::from_ref_time(26_483_000)
- .saturating_add(RocksDbWeight::get().reads(5 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokensMinted (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:2 w:2)
- fn mint_nft(b: u32, ) -> Weight {
- Weight::from_ref_time(62_419_000)
- // Standard Error: 7_000
- .saturating_add(Weight::from_ref_time(12_325_000).saturating_mul(b as u64))
- .saturating_add(RocksDbWeight::get().reads(6 as u64))
- .saturating_add(RocksDbWeight::get().reads((1 as u64).saturating_mul(b as u64)))
- .saturating_add(RocksDbWeight::get().writes(5 as u64))
- .saturating_add(RocksDbWeight::get().writes((1 as u64).saturating_mul(b as u64)))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:1 w:1)
- // Storage: Nonfungible TokenChildren (r:1 w:0)
- // Storage: Nonfungible TokensBurnt (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible Allowance (r:1 w:0)
- // Storage: Nonfungible Owned (r:0 w:1)
- // Storage: Nonfungible TokenProperties (r:0 w:1)
- fn burn_nft(b: u32, ) -> Weight {
- (Weight::from_ref_time(0))
- // Standard Error: 1_488_000
- .saturating_add(Weight::from_ref_time(298_367_000).saturating_mul(b as u64))
- .saturating_add(RocksDbWeight::get().reads(9 as u64))
- .saturating_add(RocksDbWeight::get().reads((4 as u64).saturating_mul(b as u64)))
- .saturating_add(RocksDbWeight::get().writes(6 as u64))
- .saturating_add(RocksDbWeight::get().writes((4 as u64).saturating_mul(b as u64)))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:0)
- // Storage: Nonfungible AccountBalance (r:2 w:2)
- // Storage: Nonfungible Allowance (r:1 w:0)
- // Storage: Nonfungible TokenChildren (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:2)
- fn send() -> Weight {
- Weight::from_ref_time(81_942_000)
- .saturating_add(RocksDbWeight::get().reads(12 as u64))
- .saturating_add(RocksDbWeight::get().writes(6 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:2 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:2 w:0)
- // Storage: Nonfungible TokenData (r:6 w:1)
- // Storage: Nonfungible AccountBalance (r:2 w:2)
- // Storage: Nonfungible Allowance (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- // Storage: Nonfungible TokenChildren (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:2)
- fn accept_nft() -> Weight {
- Weight::from_ref_time(97_925_000)
- .saturating_add(RocksDbWeight::get().reads(16 as u64))
- .saturating_add(RocksDbWeight::get().writes(8 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:5)
- // Storage: Nonfungible TokenProperties (r:1 w:5)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- // Storage: Nonfungible TokenChildren (r:9 w:4)
- // Storage: Nonfungible TokensBurnt (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:5 w:5)
- // Storage: Nonfungible Allowance (r:5 w:0)
- // Storage: Nonfungible Owned (r:0 w:5)
- fn reject_nft() -> Weight {
- Weight::from_ref_time(277_794_000)
- .saturating_add(RocksDbWeight::get().reads(30 as u64))
- .saturating_add(RocksDbWeight::get().writes(26 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:5 w:0)
- fn set_property() -> Weight {
- Weight::from_ref_time(54_657_000)
- .saturating_add(RocksDbWeight::get().reads(9 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:5 w:0)
- fn set_priority() -> Weight {
- Weight::from_ref_time(55_056_000)
- .saturating_add(RocksDbWeight::get().reads(9 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn add_basic_resource() -> Weight {
- Weight::from_ref_time(61_673_000)
- .saturating_add(RocksDbWeight::get().reads(10 as u64))
- .saturating_add(RocksDbWeight::get().writes(2 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:2 w:2)
- fn add_composable_resource() -> Weight {
- Weight::from_ref_time(67_125_000)
- .saturating_add(RocksDbWeight::get().reads(11 as u64))
- .saturating_add(RocksDbWeight::get().writes(3 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn add_slot_resource() -> Weight {
- Weight::from_ref_time(69_058_000)
- .saturating_add(RocksDbWeight::get().reads(10 as u64))
- .saturating_add(RocksDbWeight::get().writes(2 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:5 w:0)
- fn remove_resource() -> Weight {
- Weight::from_ref_time(53_427_000)
- .saturating_add(RocksDbWeight::get().reads(9 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn accept_resource() -> Weight {
- Weight::from_ref_time(50_623_000)
- .saturating_add(RocksDbWeight::get().reads(9 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
- // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: Nonfungible TokenData (r:5 w:0)
- // Storage: Nonfungible TokenAuxProperties (r:1 w:1)
- fn accept_resource_removal() -> Weight {
- Weight::from_ref_time(50_917_000)
- .saturating_add(RocksDbWeight::get().reads(9 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
-}
pallets/proxy-rmrk-equip/CHANGELOG.mddiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/CHANGELOG.md
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- bureaucrate goes here -->
-## [v0.1.2] 2022-08-16
-
-### Other changes
-
-- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
-
-- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
-
-- refactor: Remove `#[transactional]` from extrinsics 7fd36cea2f6e00c02c67ccc1de9649ae404efd31
-
-Every extrinsic now runs in transaction implicitly, and
-`#[transactional]` on pallet dispatchable is now meaningless
-
-Upstream-Change: https://github.com/paritytech/substrate/issues/10806
-
-- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
\ No newline at end of file
pallets/proxy-rmrk-equip/Cargo.tomldiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/Cargo.toml
+++ /dev/null
@@ -1,39 +0,0 @@
-[package]
-edition = "2021"
-license = "GPLv3"
-name = "pallet-rmrk-equip"
-version = "0.1.2"
-
-[dependencies]
-# Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
-codec = { workspace = true, package = "parity-scale-codec" }
-
-scale-info = { workspace = true }
-
-frame-benchmarking = {workspace = true, optional = true }
-frame-support = { workspace = true }
-frame-system = { workspace = true }
-pallet-common = { workspace = true }
-pallet-evm = { workspace = true }
-pallet-nonfungible = { workspace = true }
-pallet-proxy-rmrk-core = { workspace = true }
-sp-runtime = { workspace = true }
-sp-std = { workspace = true }
-up-data-structs = { workspace = true }
-
-[features]
-default = ["std"]
-runtime-benchmarks = ['frame-benchmarking', 'frame-support/runtime-benchmarks', 'frame-system/runtime-benchmarks']
-std = [
- "frame-support/std",
- "frame-system/std",
- "pallet-common/std",
- "pallet-evm/std",
- "pallet-nonfungible/std",
- "pallet-proxy-rmrk-core/std",
- "sp-runtime/std",
- "sp-std/std",
- "up-data-structs/std",
- 'frame-benchmarking/std',
-]
-try-runtime = ["frame-support/try-runtime"]
pallets/proxy-rmrk-equip/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/src/benchmarking.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-// 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/>.
-
-use sp_std::vec;
-
-use frame_benchmarking::{benchmarks, account};
-use frame_system::RawOrigin;
-use frame_support::{
- traits::{Currency, Get},
- BoundedVec,
-};
-
-use up_data_structs::*;
-
-use super::*;
-
-const SEED: u32 = 1;
-
-fn create_data<S: Get<u32>>() -> BoundedVec<u8, S> {
- vec![b'A'; S::get() as usize].try_into().expect("size == S")
-}
-
-fn create_u32_array<S: Get<u32>>() -> BoundedVec<u32, S> {
- vec![0; S::get() as usize].try_into().expect("size == S")
-}
-
-fn create_max_part(id: RmrkSlotId) -> RmrkPartType {
- RmrkPartType::SlotPart(RmrkSlotPart {
- id,
- equippable: RmrkEquippableList::Custom(create_u32_array()),
- src: create_data(),
- z: 1,
- })
-}
-
-fn create_parts_array<S: Get<u32>>(num: u32) -> BoundedVec<RmrkPartType, S> {
- let mut parts: BoundedVec<RmrkPartType, S> = vec![].try_into().expect("0 <= S");
-
- for i in 0..num {
- parts.try_push(create_max_part(i)).expect("num <= S");
- }
-
- parts
-}
-
-fn create_max_theme_property() -> RmrkThemeProperty {
- RmrkThemeProperty {
- key: create_data(),
- value: create_data(),
- }
-}
-
-fn create_theme_properties_array<S: Get<u32>>(num: u32) -> BoundedVec<RmrkThemeProperty, S> {
- vec![create_max_theme_property(); num as usize]
- .try_into()
- .expect("num <= S")
-}
-
-fn create_max_theme(name: RmrkString, props_num: u32) -> RmrkBoundedTheme {
- RmrkBoundedTheme {
- name,
- properties: create_theme_properties_array(props_num),
- inherit: false,
- }
-}
-
-benchmarks! {
- create_base {
- let b in 0..RmrkPartsLimit::get();
-
- let caller = account("caller", 0, SEED);
- <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
-
- let base_type = create_data();
- let symbol = create_data();
- let parts = create_parts_array(b);
- }: _(RawOrigin::Signed(caller), base_type, symbol, parts)
-
- theme_add {
- let b in 0..MaxPropertiesPerTheme::get();
-
- let caller = account("caller", 0, SEED);
- <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
-
- let base_type = create_data();
- let symbol = create_data();
- let parts = create_parts_array(0);
-
- <Pallet<T>>::create_base(RawOrigin::Signed(caller.clone()).into(), base_type, symbol, parts)?;
- let base_id = 1;
-
-
- let default_theme_name = b"default".to_vec().try_into().expect("default is a valid name; qed");
- let default_theme = create_max_theme(default_theme_name, 0);
-
- <Pallet<T>>::theme_add(RawOrigin::Signed(caller.clone()).into(), base_id, default_theme)?;
-
- let theme = create_max_theme(create_data(), b);
- }: _(RawOrigin::Signed(caller), base_id, theme)
-
- equippable {
- let caller = account("caller", 0, SEED);
- <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
-
- let base_id = 1;
- let slot_id = 42;
-
- let base_type = create_data();
- let symbol = create_data();
- let parts = vec! {
- RmrkPartType::SlotPart(RmrkSlotPart {
- id: slot_id,
- equippable: RmrkEquippableList::All,
- src: create_data(),
- z: 1,
- })
- }.try_into().expect("1 <= RmrkPartsLimit");
-
- <Pallet<T>>::create_base(RawOrigin::Signed(caller.clone()).into(), base_type, symbol, parts)?;
-
- let equippables = RmrkEquippableList::Custom(create_u32_array());
- }: _(RawOrigin::Signed(caller), base_id, slot_id, equippables)
-}
pallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/src/lib.rs
+++ /dev/null
@@ -1,508 +0,0 @@
-// 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/>.
-
-//! # RMRK Core Proxy Pallet
-//!
-//! A pallet used as proxy for RMRK Core (<https://rmrk-team.github.io/rmrk-substrate/#/pallets/rmrk-core>).
-//!
-//! - [`Config`]
-//! - [`Call`]
-//! - [`Pallet`]
-//!
-//! ## Overview
-//!
-//! The RMRK Equip Proxy pallet mirrors the functionality of RMRK Equip,
-//! binding its externalities to Unique's own underlying structure.
-//! It is purposed to mimic RMRK Equip exactly, allowing seamless integrations
-//! of solutions based on RMRK.
-//!
-//! RMRK Equip itself contains functionality to equip NFTs, and work with Bases,
-//! Parts, and Themes. See [Proxy Implementation](#proxy-implementation) for details.
-//!
-//! Equip Proxy is responsible for a more specific area of RMRK, and heavily relies on the Core.
-//! For a more foundational description of proxy implementation, please refer to [`pallet_rmrk_core`].
-//!
-//! *Note*, that while RMRK itself is subject to active development and restructuring,
-//! the proxy may be caught temporarily out of date.
-//!
-//! ### What is RMRK?
-//!
-//! RMRK is a set of NFT standards which compose several "NFT 2.0 lego" primitives.
-//! Putting these legos together allows a user to create NFT systems of arbitrary complexity.
-//!
-//! Meaning, RMRK NFTs are dynamic, able to nest into each other and form a hierarchy,
-//! make use of specific changeable and partially shared metadata in the form of resources,
-//! and more.
-//!
-//! Visit RMRK documentation and repositories to learn more:
-//! - Docs: <https://docs.rmrk.app/getting-started/>
-//! - FAQ: <https://coda.io/@rmrk/faq>
-//! - Substrate code repository: <https://github.com/rmrk-team/rmrk-substrate>
-//! - RMRK spec repository: <https://github.com/rmrk-team/rmrk-spec>
-//!
-//! ## Terminology
-//!
-//! For more information on RMRK, see RMRK's own documentation.
-//!
-//! ### Intro to RMRK
-//!
-//! - **Resource:** Additional piece of metadata of an NFT usually serving to add
-//! a piece of media on top of the root metadata (NFT's own), be it a different wing
-//! on the root template bird or something entirely unrelated.
-//!
-//! - **Base:** A list of possible "components" - Parts, a combination of which can
-//! be appended/equipped to/on an NFT.
-//!
-//! - **Part:** Something that, together with other Parts, can constitute an NFT.
-//! Parts are defined in the Base to which they belong. Parts can be either
-//! of the `slot` type or `fixed` type. Slots are intended for equippables.
-//! Note that "part of something" and "Part of a Base" can be easily confused,
-//! and so in this documentation these words are distinguished by the capital letter.
-//!
-//! - **Theme:** Named objects of variable => value pairs which get interpolated into
-//! the Base's `themable` Parts. Themes can hold any value, but are often represented
-//! in RMRK's examples as colors applied to visible Parts.
-//!
-//! ### Peculiarities in Unique
-//!
-//! - **Scoped properties:** Properties that are normally obscured from users.
-//! Their purpose is to contain structured metadata that was not included in the Unique standard
-//! for collections and tokens, meant to be operated on by proxies and other outliers.
-//! Scoped property keys are prefixed with `some-scope:`, where `some-scope` is
-//! an arbitrary keyword, like "rmrk". `:` is considered an unacceptable symbol in user-defined
-//! properties, which, along with other safeguards, makes scoped ones impossible to tamper with.
-//!
-//! - **Auxiliary properties:** A slightly different structure of properties,
-//! trading universality of use for more convenient storage, writes and access.
-//! Meant to be inaccessible to end users.
-//!
-//! ## Proxy Implementation
-//!
-//! An external user is supposed to be able to utilize this proxy as they would
-//! utilize RMRK, and get exactly the same results. Normally, Unique transactions
-//! are off-limits to RMRK collections and tokens, and vice versa. However,
-//! the information stored on chain can be freely interpreted by storage reads and Unique RPCs.
-//!
-//! ### ID Mapping
-//!
-//! RMRK's collections' IDs are counted independently of Unique's and start at 0.
-//! Note that tokens' IDs still start at 1.
-//! The collections themselves, as well as tokens, are stored as Unique collections,
-//! and thus RMRK IDs are mapped to Unique IDs (but not vice versa).
-//!
-//! ### External/Internal Collection Insulation
-//!
-//! A Unique transaction cannot target collections purposed for RMRK,
-//! and they are flagged as `external` to specify that. On the other hand,
-//! due to the mapping, RMRK transactions and RPCs simply cannot reach Unique collections.
-//!
-//! ### Native Properties
-//!
-//! Many of RMRK's native parameters are stored as scoped properties of a collection
-//! or an NFT on the chain. Scoped properties are prefixed with `rmrk:`, where `:`
-//! is an unacceptable symbol in user-defined properties, which, along with other safeguards,
-//! makes them impossible to tamper with.
-//!
-//! ### Collection and NFT Types, or Base, Parts and Themes Handling
-//!
-//! RMRK introduces the concept of a Base, which is a catalogue of Parts,
-//! possible components of an NFT. Due to its similarity with the functionality
-//! of a token collection, a Base is stored and handled as one, and the Base's Parts and Themes
-//! are this collection's NFTs. See [`CollectionType`] and [`NftType`].
-//!
-//! ## Interface
-//!
-//! ### Dispatchables
-//!
-//! - `create_base` - Create a new Base.
-//! - `theme_add` - Add a Theme to a Base.
-//! - `equippable` - Update the array of Collections allowed to be equipped to a Base's specified Slot Part.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-
-use frame_support::{pallet_prelude::*, BoundedVec, dispatch::DispatchResult};
-use frame_system::{pallet_prelude::*, ensure_signed};
-use sp_runtime::DispatchError;
-use up_data_structs::*;
-use pallet_common::{Pallet as PalletCommon, Error as CommonError};
-use pallet_proxy_rmrk_core::{
- Pallet as PalletCore, Error as CoreError,
- misc::{self, *},
- property::RmrkProperty::*,
-};
-use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle};
-use pallet_evm::account::CrossAccountId;
-use weights::WeightInfo;
-
-pub use pallet::*;
-
-#[cfg(feature = "runtime-benchmarks")]
-pub mod benchmarking;
-pub mod rpc;
-pub mod weights;
-
-pub type SelfWeightOf<T> = <T as Config>::WeightInfo;
-
-#[frame_support::pallet]
-pub mod pallet {
- use super::*;
-
- #[pallet::config]
- pub trait Config: frame_system::Config + pallet_proxy_rmrk_core::Config {
- /// Overarching event type.
- type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
-
- /// The weight information of this pallet.
- type WeightInfo: WeightInfo;
- }
-
- /// Map of a Base ID and a Part ID to an NFT in the Base collection serving as the Part.
- #[pallet::storage]
- #[pallet::getter(fn internal_part_id)]
- pub type InernalPartId<T: Config> =
- StorageDoubleMap<_, Twox64Concat, CollectionId, Twox64Concat, RmrkPartId, TokenId>;
-
- /// Checkmark that a Base has a Theme NFT named "default".
- #[pallet::storage]
- #[pallet::getter(fn base_has_default_theme)]
- pub type BaseHasDefaultTheme<T: Config> =
- StorageMap<_, Twox64Concat, CollectionId, bool, ValueQuery>;
-
- #[pallet::pallet]
- #[pallet::generate_store(pub(super) trait Store)]
- pub struct Pallet<T>(_);
-
- #[pallet::event]
- #[pallet::generate_deposit(pub(super) fn deposit_event)]
- pub enum Event<T: Config> {
- BaseCreated {
- issuer: T::AccountId,
- base_id: RmrkBaseId,
- },
- EquippablesUpdated {
- base_id: RmrkBaseId,
- slot_id: RmrkSlotId,
- },
- }
-
- #[pallet::error]
- pub enum Error<T> {
- /// No permission to perform action.
- PermissionError,
- /// Could not find an ID for a Base collection. It is likely there were too many collections created on the chain, causing an overflow.
- NoAvailableBaseId,
- /// Could not find a suitable ID for a Part, likely too many Part tokens were created in the Base, causing an overflow
- NoAvailablePartId,
- /// Base collection linked to this ID does not exist.
- BaseDoesntExist,
- /// No Theme named "default" is associated with the Base.
- NeedsDefaultThemeFirst,
- /// Part linked to this ID does not exist.
- PartDoesntExist,
- /// Cannot assign equippables to a fixed Part.
- NoEquippableOnFixedPart,
- }
-
- #[pallet::call]
- impl<T: Config> Pallet<T> {
- /// Create a new Base.
- ///
- /// Modeled after the [Base interaction](https://github.com/rmrk-team/rmrk-spec/blob/master/standards/rmrk2.0.0/interactions/base.md)
- ///
- /// # Permissions
- /// - Anyone - will be assigned as the issuer of the Base.
- ///
- /// # Arguments:
- /// - `origin`: Caller, will be assigned as the issuer of the Base
- /// - `base_type`: Arbitrary media type, e.g. "svg".
- /// - `symbol`: Arbitrary client-chosen symbol.
- /// - `parts`: Array of Fixed and Slot Parts composing the Base,
- /// confined in length by [`RmrkPartsLimit`](up_data_structs::RmrkPartsLimit).
- #[pallet::call_index(0)]
- #[pallet::weight(<SelfWeightOf<T>>::create_base(parts.len() as u32))]
- pub fn create_base(
- origin: OriginFor<T>,
- base_type: RmrkString,
- symbol: RmrkBaseSymbol,
- parts: BoundedVec<RmrkPartType, RmrkPartsLimit>,
- ) -> DispatchResult {
- let sender = ensure_signed(origin)?;
- let cross_sender = T::CrossAccountId::from_sub(sender.clone());
-
- let data = CreateCollectionData {
- limits: None,
- token_prefix: symbol
- .into_inner()
- .try_into()
- .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
- ..Default::default()
- };
-
- let collection_id_res = <PalletNft<T>>::init_collection(
- cross_sender.clone(),
- cross_sender.clone(),
- data,
- up_data_structs::CollectionFlags {
- external: true,
- ..Default::default()
- },
- );
-
- if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
- return Err(<Error<T>>::NoAvailableBaseId.into());
- }
-
- let collection_id = collection_id_res?;
-
- <PalletCommon<T>>::set_scoped_collection_properties(
- collection_id,
- PropertyScope::Rmrk,
- [
- <PalletCore<T>>::encode_rmrk_property(
- CollectionType,
- &misc::CollectionType::Base,
- )?,
- <PalletCore<T>>::encode_rmrk_property(BaseType, &base_type)?,
- ]
- .into_iter(),
- )?;
-
- let collection = <PalletCore<T>>::get_nft_collection(collection_id)?;
-
- for part in parts {
- Self::create_part(&cross_sender, &collection, part)?;
- }
-
- Self::deposit_event(Event::BaseCreated {
- issuer: sender,
- base_id: collection_id.0,
- });
-
- Ok(())
- }
-
- /// Add a Theme to a Base.
- /// A Theme named "default" is required prior to adding other Themes.
- ///
- /// Modeled after [Themeadd interaction](https://github.com/rmrk-team/rmrk-spec/blob/master/standards/rmrk2.0.0/interactions/themeadd.md).
- ///
- /// # Permissions:
- /// - Base issuer
- ///
- /// # Arguments:
- /// - `origin`: sender of the transaction
- /// - `base_id`: Base ID containing the Theme to be updated.
- /// - `theme`: Theme to add to the Base. A Theme has a name and properties, which are an
- /// array of [key, value, inherit].
- /// - `key`: Arbitrary BoundedString, defined by client.
- /// - `value`: Arbitrary BoundedString, defined by client.
- /// - `inherit`: Optional bool.
- #[pallet::call_index(1)]
- #[pallet::weight(<SelfWeightOf<T>>::theme_add(theme.properties.len() as u32))]
- pub fn theme_add(
- origin: OriginFor<T>,
- base_id: RmrkBaseId,
- theme: RmrkBoundedTheme,
- ) -> DispatchResult {
- let sender = ensure_signed(origin)?;
-
- let sender = T::CrossAccountId::from_sub(sender);
- let owner = &sender;
-
- let collection_id: CollectionId = base_id.into();
-
- let collection = Self::get_base(collection_id)?;
-
- if theme.name.as_slice() == b"default" {
- <BaseHasDefaultTheme<T>>::insert(collection_id, true);
- } else if !Self::base_has_default_theme(collection_id) {
- return Err(<Error<T>>::NeedsDefaultThemeFirst.into());
- }
-
- let token_id = <PalletCore<T>>::create_nft(
- &sender,
- owner,
- &collection,
- [
- <PalletCore<T>>::encode_rmrk_property(TokenType, &NftType::Theme)?,
- <PalletCore<T>>::encode_rmrk_property(ThemeName, &theme.name)?,
- <PalletCore<T>>::encode_rmrk_property(ThemeInherit, &theme.inherit)?,
- ]
- .into_iter(),
- )
- .map_err(|_| <Error<T>>::PermissionError)?;
-
- for property in theme.properties {
- <PalletNft<T>>::set_scoped_token_property(
- collection_id,
- token_id,
- PropertyScope::Rmrk,
- <PalletCore<T>>::encode_rmrk_property(
- UserProperty(property.key.as_slice()),
- &property.value,
- )?,
- )?;
- }
-
- Ok(())
- }
-
- /// Update the array of Collections allowed to be equipped to a Base's specified Slot Part.
- ///
- /// Modeled after [equippable interaction](https://github.com/rmrk-team/rmrk-spec/blob/master/standards/rmrk2.0.0/interactions/equippable.md).
- ///
- /// # Permissions:
- /// - Base issuer
- ///
- /// # Arguments:
- /// - `origin`: sender of the transaction
- /// - `base_id`: Base containing the Slot Part to be updated.
- /// - `slot_id`: Slot Part whose Equippable List is being updated .
- /// - `equippables`: List of equippables that will override the current Equippables list.
- #[pallet::call_index(2)]
- #[pallet::weight(<SelfWeightOf<T>>::equippable())]
- pub fn equippable(
- origin: OriginFor<T>,
- base_id: RmrkBaseId,
- slot_id: RmrkSlotId,
- equippables: RmrkEquippableList,
- ) -> DispatchResult {
- let sender = ensure_signed(origin)?;
-
- let base_collection_id = base_id.into();
- let collection = Self::get_base(base_collection_id)?;
-
- <PalletCore<T>>::check_collection_owner(
- &collection,
- &T::CrossAccountId::from_sub(sender),
- )
- .map_err(|err| {
- if err == <CoreError<T>>::NoPermission.into() {
- <Error<T>>::PermissionError.into()
- } else {
- err
- }
- })?;
-
- let part_id = Self::internal_part_id(base_collection_id, slot_id)
- .ok_or(<Error<T>>::PartDoesntExist)?;
-
- let nft_type = <PalletCore<T>>::get_nft_type(base_collection_id, part_id)
- .map_err(|_| <Error<T>>::PartDoesntExist)?;
-
- match nft_type {
- NftType::Regular | NftType::Theme => return Err(<Error<T>>::PermissionError.into()),
- NftType::FixedPart => return Err(<Error<T>>::NoEquippableOnFixedPart.into()),
- NftType::SlotPart => {
- <PalletNft<T>>::set_scoped_token_property(
- base_collection_id,
- part_id,
- PropertyScope::Rmrk,
- <PalletCore<T>>::encode_rmrk_property(EquippableList, &equippables)?,
- )?;
- }
- }
-
- Self::deposit_event(Event::EquippablesUpdated { base_id, slot_id });
-
- Ok(())
- }
- }
-}
-
-impl<T: Config> Pallet<T> {
- /// Create (or overwrite) a Part in a Base.
- /// The Part and the Base are represented as an NFT and a Collection.
- fn create_part(
- sender: &T::CrossAccountId,
- collection: &NonfungibleHandle<T>,
- part: RmrkPartType,
- ) -> DispatchResult {
- let owner = sender;
-
- let part_id = part.id();
- let src = part.src();
- let z_index = part.z_index();
-
- let nft_type = match part {
- RmrkPartType::FixedPart(_) => NftType::FixedPart,
- RmrkPartType::SlotPart(_) => NftType::SlotPart,
- };
-
- let token_id = match Self::internal_part_id(collection.id, part_id) {
- Some(token_id) => token_id,
- None => {
- let token_id =
- <PalletCore<T>>::create_nft(sender, owner, collection, [].into_iter())
- .map_err(|err| match err {
- DispatchError::Arithmetic(_) => <Error<T>>::NoAvailablePartId.into(),
- err => err,
- })?;
-
- <InernalPartId<T>>::insert(collection.id, part_id, token_id);
-
- <PalletNft<T>>::set_scoped_token_property(
- collection.id,
- token_id,
- PropertyScope::Rmrk,
- <PalletCore<T>>::encode_rmrk_property(ExternalPartId, &part_id)?,
- )?;
-
- token_id
- }
- };
-
- <PalletNft<T>>::set_scoped_token_properties(
- collection.id,
- token_id,
- PropertyScope::Rmrk,
- [
- <PalletCore<T>>::encode_rmrk_property(TokenType, &nft_type)?,
- <PalletCore<T>>::encode_rmrk_property(Src, &src)?,
- <PalletCore<T>>::encode_rmrk_property(ZIndex, &z_index)?,
- ]
- .into_iter(),
- )?;
-
- if let RmrkPartType::SlotPart(part) = part {
- <PalletNft<T>>::set_scoped_token_property(
- collection.id,
- token_id,
- PropertyScope::Rmrk,
- <PalletCore<T>>::encode_rmrk_property(EquippableList, &part.equippable)?,
- )?;
- }
-
- Ok(())
- }
-
- /// Ensure that the collection under the Base ID is a Base collection,
- /// and fetch it.
- fn get_base(base_id: CollectionId) -> Result<NonfungibleHandle<T>, DispatchError> {
- let collection =
- <PalletCore<T>>::get_typed_nft_collection(base_id, misc::CollectionType::Base)
- .map_err(|err| {
- if err == <CoreError<T>>::CollectionUnknown.into() {
- <Error<T>>::BaseDoesntExist.into()
- } else {
- err
- }
- })?;
- collection.check_is_external()?;
-
- Ok(collection)
- }
-}
pallets/proxy-rmrk-equip/src/rpc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/src/rpc.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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/>.
-
-//! Realizations of RMRK RPCs (remote procedure calls) related to the Equip pallet.
-
-use super::*;
-use pallet_proxy_rmrk_core::{misc, property::*};
-use sp_std::vec::Vec;
-
-/// Get base info by its ID.
-pub fn base<T: Config>(
- base_id: RmrkBaseId,
-) -> Result<Option<RmrkBaseInfo<T::AccountId>>, DispatchError> {
- let (collection, collection_id) =
- match <PalletCore<T>>::get_typed_nft_collection_mapped(base_id, misc::CollectionType::Base)
- {
- Ok(c) => c,
- Err(_) => return Ok(None),
- };
-
- Ok(Some(RmrkBaseInfo {
- issuer: collection.owner.clone(),
- base_type: <PalletCore<T>>::get_collection_property_decoded(
- collection_id,
- RmrkProperty::BaseType,
- )?,
- symbol: <PalletCore<T>>::rebind(&collection.token_prefix)?,
- }))
-}
-
-/// Get all parts of a base.
-pub fn base_parts<T: Config>(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
- use pallet_common::CommonCollectionOperations;
-
- let (collection, collection_id) =
- match <PalletCore<T>>::get_typed_nft_collection_mapped(base_id, misc::CollectionType::Base)
- {
- Ok(c) => c,
- Err(_) => return Ok(Vec::new()),
- };
-
- let parts = collection
- .collection_tokens()
- .into_iter()
- .filter_map(|token_id| {
- let nft_type = <PalletCore<T>>::get_nft_type(collection_id, token_id).ok()?;
-
- match nft_type {
- NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {
- id: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::ExternalPartId,
- )
- .ok()?,
- src: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::Src,
- )
- .ok()?,
- z: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::ZIndex,
- )
- .ok()?,
- })),
- NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {
- id: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::ExternalPartId,
- )
- .ok()?,
- src: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::Src,
- )
- .ok()?,
- z: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::ZIndex,
- )
- .ok()?,
- equippable: <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::EquippableList,
- )
- .ok()?,
- })),
- _ => None,
- }
- })
- .collect();
-
- Ok(parts)
-}
-
-/// Get the theme names belonging to a base.
-pub fn theme_names<T: Config>(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
- use pallet_common::CommonCollectionOperations;
-
- let (collection, collection_id) =
- match <PalletCore<T>>::get_typed_nft_collection_mapped(base_id, misc::CollectionType::Base)
- {
- Ok(c) => c,
- Err(_) => return Ok(Vec::new()),
- };
-
- let theme_names = collection
- .collection_tokens()
- .iter()
- .filter_map(|token_id| {
- let nft_type = <PalletCore<T>>::get_nft_type(collection_id, *token_id).ok()?;
-
- match nft_type {
- NftType::Theme => <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- *token_id,
- RmrkProperty::ThemeName,
- )
- .ok(),
- _ => None,
- }
- })
- .collect();
-
- Ok(theme_names)
-}
-
-/// Get theme info, including properties, optionally limited to the provided keys.
-pub fn theme<T: Config>(
- base_id: RmrkBaseId,
- theme_name: RmrkThemeName,
- filter_keys: Option<Vec<RmrkPropertyKey>>,
-) -> Result<Option<RmrkTheme>, DispatchError> {
- use pallet_common::CommonCollectionOperations;
-
- let (collection, collection_id) =
- match <PalletCore<T>>::get_typed_nft_collection_mapped(base_id, misc::CollectionType::Base)
- {
- Ok(c) => c,
- Err(_) => return Ok(None),
- };
-
- let theme_info = collection
- .collection_tokens()
- .into_iter()
- .find_map(|token_id| {
- <PalletCore<T>>::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;
-
- let name: RmrkString = <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- token_id,
- RmrkProperty::ThemeName,
- )
- .ok()?;
-
- if name == theme_name {
- Some((name, token_id))
- } else {
- None
- }
- });
-
- let (name, theme_id) = match theme_info {
- Some((name, theme_id)) => (name, theme_id),
- None => return Ok(None),
- };
-
- let properties = <PalletCore<T>>::filter_user_properties(
- collection_id,
- Some(theme_id),
- filter_keys,
- |key, value| RmrkThemeProperty { key, value },
- )?;
-
- let inherit = <PalletCore<T>>::get_nft_property_decoded(
- collection_id,
- theme_id,
- RmrkProperty::ThemeInherit,
- )?;
-
- let theme = RmrkTheme {
- name,
- properties,
- inherit,
- };
-
- Ok(Some(theme))
-}
pallets/proxy-rmrk-equip/src/weights.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/src/weights.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
-
-//! Autogenerated weights for pallet_proxy_rmrk_equip
-//!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
-
-// Executed Command:
-// target/release/unique-collator
-// benchmark
-// pallet
-// --pallet
-// pallet-proxy-rmrk-equip
-// --wasm-execution
-// compiled
-// --extrinsic
-// *
-// --template
-// .maintain/frame-weight-template.hbs
-// --steps=50
-// --repeat=80
-// --heap-pages=4096
-// --output=./pallets/proxy-rmrk-equip/src/weights.rs
-
-#![cfg_attr(rustfmt, rustfmt_skip)]
-#![allow(unused_parens)]
-#![allow(unused_imports)]
-#![allow(clippy::unnecessary_cast)]
-
-use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
-use sp_std::marker::PhantomData;
-
-/// Weight functions needed for pallet_proxy_rmrk_equip.
-pub trait WeightInfo {
- fn create_base(b: u32, ) -> Weight;
- fn theme_add(b: u32, ) -> Weight;
- fn equippable() -> Weight;
-}
-
-/// Weights for pallet_proxy_rmrk_equip using the Substrate node and recommended hardware.
-pub struct SubstrateWeight<T>(PhantomData<T>);
-impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
- // Storage: Common CreatedCollectionCount (r:1 w:1)
- // Storage: Common DestroyedCollectionCount (r:1 w:0)
- // Storage: System Account (r:2 w:2)
- // Storage: Common CollectionPropertyPermissions (r:0 w:1)
- // Storage: Common CollectionProperties (r:0 w:1)
- // Storage: Common CollectionById (r:0 w:1)
- // Storage: RmrkEquip InernalPartId (r:1 w:1)
- // Storage: Nonfungible TokensMinted (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:1)
- fn create_base(b: u32, ) -> Weight {
- Weight::from_ref_time(58_417_000)
- // Standard Error: 27_000
- .saturating_add(Weight::from_ref_time(20_439_000).saturating_mul(b as u64))
- .saturating_add(T::DbWeight::get().reads(6 as u64))
- .saturating_add(T::DbWeight::get().reads((2 as u64).saturating_mul(b as u64)))
- .saturating_add(T::DbWeight::get().writes(8 as u64))
- .saturating_add(T::DbWeight::get().writes((4 as u64).saturating_mul(b as u64)))
- }
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: RmrkEquip BaseHasDefaultTheme (r:1 w:0)
- // Storage: Nonfungible TokensMinted (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:1)
- fn theme_add(b: u32, ) -> Weight {
- Weight::from_ref_time(46_005_000)
- // Standard Error: 42_000
- .saturating_add(Weight::from_ref_time(2_922_000).saturating_mul(b as u64))
- .saturating_add(T::DbWeight::get().reads(6 as u64))
- .saturating_add(T::DbWeight::get().writes(5 as u64))
- }
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: RmrkEquip InernalPartId (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- fn equippable() -> Weight {
- Weight::from_ref_time(32_526_000)
- .saturating_add(T::DbWeight::get().reads(4 as u64))
- .saturating_add(T::DbWeight::get().writes(1 as u64))
- }
-}
-
-// For backwards compatibility and tests
-impl WeightInfo for () {
- // Storage: Common CreatedCollectionCount (r:1 w:1)
- // Storage: Common DestroyedCollectionCount (r:1 w:0)
- // Storage: System Account (r:2 w:2)
- // Storage: Common CollectionPropertyPermissions (r:0 w:1)
- // Storage: Common CollectionProperties (r:0 w:1)
- // Storage: Common CollectionById (r:0 w:1)
- // Storage: RmrkEquip InernalPartId (r:1 w:1)
- // Storage: Nonfungible TokensMinted (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:1)
- fn create_base(b: u32, ) -> Weight {
- Weight::from_ref_time(58_417_000)
- // Standard Error: 27_000
- .saturating_add(Weight::from_ref_time(20_439_000).saturating_mul(b as u64))
- .saturating_add(RocksDbWeight::get().reads(6 as u64))
- .saturating_add(RocksDbWeight::get().reads((2 as u64).saturating_mul(b as u64)))
- .saturating_add(RocksDbWeight::get().writes(8 as u64))
- .saturating_add(RocksDbWeight::get().writes((4 as u64).saturating_mul(b as u64)))
- }
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: RmrkEquip BaseHasDefaultTheme (r:1 w:0)
- // Storage: Nonfungible TokensMinted (r:1 w:1)
- // Storage: Nonfungible AccountBalance (r:1 w:1)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- // Storage: Nonfungible TokenData (r:0 w:1)
- // Storage: Nonfungible Owned (r:0 w:1)
- fn theme_add(b: u32, ) -> Weight {
- Weight::from_ref_time(46_005_000)
- // Standard Error: 42_000
- .saturating_add(Weight::from_ref_time(2_922_000).saturating_mul(b as u64))
- .saturating_add(RocksDbWeight::get().reads(6 as u64))
- .saturating_add(RocksDbWeight::get().writes(5 as u64))
- }
- // Storage: Common CollectionProperties (r:1 w:0)
- // Storage: Common CollectionById (r:1 w:0)
- // Storage: RmrkEquip InernalPartId (r:1 w:0)
- // Storage: Nonfungible TokenProperties (r:1 w:1)
- fn equippable() -> Weight {
- Weight::from_ref_time(32_526_000)
- .saturating_add(RocksDbWeight::get().reads(4 as u64))
- .saturating_add(RocksDbWeight::get().writes(1 as u64))
- }
-}
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -48,8 +48,8 @@
};
use crate::{
- AccountBalance, Balance, Config, CreateItemData, Pallet, RefungibleHandle, SelfWeightOf,
- TokenProperties, TokensMinted, TotalSupply, weights::WeightInfo,
+ AccountBalance, Balance, Config, CreateItemData, Pallet, RefungibleHandle,
+ TokenProperties, TokensMinted, TotalSupply, SelfWeightOf, weights::WeightInfo,
};
frontier_contract! {
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -28,6 +28,7 @@
use pallet_common::{
erc::{CommonEvmHandler, PrecompileResult},
eth::{collection_id_to_address, CrossAddress},
+ CommonWeightInfo,
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::{
@@ -39,7 +40,7 @@
use sp_core::U256;
use up_data_structs::TokenId;
-use crate::{Allowance, Balance, Config, Pallet, RefungibleHandle, TotalSupply};
+use crate::{Allowance, Balance, Config, Pallet, RefungibleHandle, TotalSupply, common::CommonWeights, SelfWeightOf, weights::WeightInfo};
/// Refungible token handle contains information about token's collection and id
///
primitives/data-structs/Cargo.tomldiffbeforeafterboth--- a/primitives/data-structs/Cargo.toml
+++ b/primitives/data-structs/Cargo.toml
@@ -15,7 +15,6 @@
derivative = { workspace = true }
frame-support = { workspace = true }
pallet-evm = { workspace = true }
-rmrk-traits = { workspace = true }
scale-info = { workspace = true }
serde = { workspace = true, optional = true }
sp-core = { workspace = true }
@@ -33,7 +32,6 @@
"codec/std",
"frame-support/std",
"pallet-evm/std",
- "rmrk-traits/std",
"serde/std",
"serde1",
"sp-core/std",
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -27,33 +27,18 @@
use frame_support::{
storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet},
traits::Get,
- parameter_types,
};
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
use sp_core::U256;
-use sp_runtime::{ArithmeticError, sp_std::prelude::Vec, Permill};
+use sp_runtime::{ArithmeticError, sp_std::prelude::Vec};
use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};
use bondrewd::Bitfields;
use frame_support::{BoundedVec, traits::ConstU32};
use derivative::Derivative;
use scale_info::TypeInfo;
-
-// RMRK
-use rmrk_traits::{
- CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme, ThemeProperty,
- ResourceTypes, BasicResource, ComposableResource, SlotResource, EquippableList,
-};
-pub use rmrk_traits::{
- primitives::{
- CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId,
- SlotId as RmrkSlotId, PartId as RmrkPartId, ResourceId as RmrkResourceId,
- },
- NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
- FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart,
-};
mod bondrewd_codec;
mod bounded;
@@ -174,6 +159,12 @@
impl EncodeLike<u32> for CollectionId {}
impl EncodeLike<CollectionId> for u32 {}
+impl From<u32> for CollectionId {
+ fn from(value: u32) -> Self {
+ Self(value)
+ }
+}
+
/// Token id.
#[derive(
Encode,
@@ -1367,73 +1358,3 @@
Properties::new(MAX_TOKEN_PROPERTIES_SIZE)
}
}
-
-// RMRK
-// todo document?
-parameter_types! {
- #[derive(PartialEq, TypeInfo)]
- pub const RmrkStringLimit: u32 = 128;
- #[derive(PartialEq)]
- pub const RmrkCollectionSymbolLimit: u32 = MAX_TOKEN_PREFIX_LENGTH;
- #[derive(PartialEq)]
- pub const RmrkResourceSymbolLimit: u32 = 10;
- #[derive(PartialEq)]
- pub const RmrkBaseSymbolLimit: u32 = MAX_TOKEN_PREFIX_LENGTH;
- #[derive(PartialEq)]
- pub const RmrkKeyLimit: u32 = 32;
- #[derive(PartialEq)]
- pub const RmrkValueLimit: u32 = 256;
- #[derive(PartialEq)]
- pub const RmrkMaxCollectionsEquippablePerPart: u32 = 100;
- #[derive(PartialEq)]
- pub const MaxPropertiesPerTheme: u32 = 5;
- #[derive(PartialEq)]
- pub const RmrkPartsLimit: u32 = 25;
- #[derive(PartialEq)]
- pub const RmrkMaxPriorities: u32 = 25;
- #[derive(PartialEq)]
- pub const MaxResourcesOnMint: u32 = 100;
-}
-
-impl From<RmrkCollectionId> for CollectionId {
- fn from(id: RmrkCollectionId) -> Self {
- Self(id)
- }
-}
-
-impl From<RmrkNftId> for TokenId {
- fn from(id: RmrkNftId) -> Self {
- Self(id)
- }
-}
-
-pub type RmrkCollectionInfo<AccountId> =
- CollectionInfo<RmrkString, RmrkCollectionSymbol, AccountId>;
-pub type RmrkInstanceInfo<AccountId> = NftInfo<AccountId, Permill, RmrkString>;
-pub type RmrkResourceInfo = ResourceInfo<RmrkString, RmrkBoundedParts>;
-pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
-pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
-pub type BoundedEquippableCollectionIds =
- BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>;
-pub type RmrkPartType = PartType<RmrkString, BoundedEquippableCollectionIds>;
-pub type RmrkEquippableList = EquippableList<BoundedEquippableCollectionIds>;
-pub type RmrkThemeProperty = ThemeProperty<RmrkString>;
-pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;
-pub type RmrkBoundedTheme = Theme<RmrkString, BoundedVec<RmrkThemeProperty, MaxPropertiesPerTheme>>;
-pub type RmrkResourceTypes = ResourceTypes<RmrkString, RmrkBoundedParts>;
-
-pub type RmrkBasicResource = BasicResource<RmrkString>;
-pub type RmrkComposableResource = ComposableResource<RmrkString, RmrkBoundedParts>;
-pub type RmrkSlotResource = SlotResource<RmrkString>;
-
-pub type RmrkString = BoundedVec<u8, RmrkStringLimit>;
-pub type RmrkCollectionSymbol = BoundedVec<u8, RmrkCollectionSymbolLimit>;
-pub type RmrkBaseSymbol = BoundedVec<u8, RmrkBaseSymbolLimit>;
-pub type RmrkKeyString = BoundedVec<u8, RmrkKeyLimit>;
-pub type RmrkValueString = BoundedVec<u8, RmrkValueLimit>;
-pub type RmrkBoundedResource = BoundedVec<u8, RmrkResourceSymbolLimit>;
-pub type RmrkBoundedParts = BoundedVec<RmrkPartId, RmrkPartsLimit>; // todo make sure it is needed
-
-pub type RmrkRpcString = Vec<u8>;
-pub type RmrkThemeName = RmrkRpcString;
-pub type RmrkPropertyKey = RmrkRpcString;
primitives/rmrk-rpc/CHANGELOG.mddiffbeforeafterboth--- a/primitives/rmrk-rpc/CHANGELOG.md
+++ /dev/null
@@ -1,10 +0,0 @@
-<!-- bureaucrate goes here -->
-## [v0.0.2] 2022-08-16
-
-### Other changes
-
-- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
-
-- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
-
-- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
\ No newline at end of file
primitives/rmrk-rpc/Cargo.tomldiffbeforeafterboth--- a/primitives/rmrk-rpc/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-edition = "2021"
-license = ""
-name = "rmrk-rpc"
-version = "0.0.2"
-
-[dependencies]
-codec = { workspace = true }
-rmrk-traits = { workspace = true }
-sp-api = { workspace = true }
-sp-runtime = { workspace = true }
-sp-std = { workspace = true }
-
-[features]
-default = ["std"]
-std = ["codec/std", "rmrk-traits/std", "sp-api/std", "sp-runtime/std", "sp-std/std"]
primitives/rmrk-rpc/src/lib.rsdiffbeforeafterboth--- a/primitives/rmrk-rpc/src/lib.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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 sp_api::{Encode, Decode};
-use sp_std::vec::Vec;
-use sp_runtime::DispatchError;
-use rmrk_traits::{primitives::*, NftChild};
-
-pub type Result<T> = core::result::Result<T, DispatchError>;
-
-pub type RpcString = Vec<u8>;
-
-pub type PropertyKey = RpcString;
-
-pub type ThemeName = RpcString;
-
-sp_api::decl_runtime_apis! {
- pub trait RmrkApi<
- AccountId,
- CollectionInfo,
- NftInfo,
- ResourceInfo,
- PropertyInfo,
- BaseInfo,
- PartType,
- Theme
- >
- where
- AccountId: Encode,
- CollectionInfo: Decode,
- NftInfo: Decode,
- ResourceInfo: Decode,
- PropertyInfo: Decode,
- BaseInfo: Decode,
- PartType: Decode,
- Theme: Decode,
- {
- fn last_collection_idx() -> Result<CollectionId>;
-
- fn collection_by_id(id: CollectionId) -> Result<Option<CollectionInfo>>;
-
- fn nft_by_id(collection_id: CollectionId, nft_id: NftId) -> Result<Option<NftInfo>>;
-
- fn account_tokens(account_id: AccountId, collection_id: CollectionId) -> Result<Vec<NftId>>;
-
- fn nft_children(collection_id: CollectionId, nft_id: NftId) -> Result<Vec<NftChild>>;
-
- fn collection_properties(collection_id: CollectionId, filter_keys: Option<Vec<PropertyKey>>) -> Result<Vec<PropertyInfo>>;
-
- fn nft_properties(collection_id: CollectionId, nft_id: NftId, filter_keys: Option<Vec<PropertyKey>>) -> Result<Vec<PropertyInfo>>;
-
- fn nft_resources(collection_id: CollectionId, nft_id: NftId) -> Result<Vec<ResourceInfo>>;
-
- fn nft_resource_priority(collection_id: CollectionId, nft_id: NftId, resource_id: ResourceId) -> Result<Option<u32>>;
-
- fn base(base_id: BaseId) -> Result<Option<BaseInfo>>;
-
- fn base_parts(base_id: BaseId) -> Result<Vec<PartType>>;
-
- fn theme_names(base_id: BaseId) -> Result<Vec<ThemeName>>;
-
- fn theme(base_id: BaseId, theme_name: ThemeName, filter_keys: Option<Vec<PropertyKey>>) -> Result<Option<Theme>>;
- }
-}
primitives/rmrk-traits/Cargo.tomldiffbeforeafterboth--- a/primitives/rmrk-traits/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-authors = ["RMRK Team", "Unique Network <support@uniquenetwork.io>"]
-description = "RMRK proxy data structs definitions"
-edition = "2021"
-homepage = "https://unique.network"
-license = 'GPLv3'
-name = "rmrk-traits"
-repository = 'https://github.com/UniqueNetwork/unique-chain'
-version = "0.1.0"
-
-[dependencies]
-# Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
-codec = { workspace = true, package = "parity-scale-codec" }
-
-scale-info = { workspace = true }
-serde = { workspace = true, optional = true }
-
-[features]
-default = ["std"]
-serde1 = ["serde/alloc"]
-std = ["codec/std", "serde/std", "serde1"]
primitives/rmrk-traits/src/base.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/base.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode, MaxEncodedLen};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- AccountId: Serialize,
- BoundedString: AsRef<[u8]>
- "#)
-)]
-pub struct BaseInfo<AccountId, BoundedString> {
- /// Original creator of the Base
- pub issuer: AccountId,
-
- /// Specifies how an NFT should be rendered, ie "svg"
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub base_type: BoundedString,
-
- /// User provided symbol during Base creation
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub symbol: BoundedString,
-}
primitives/rmrk-traits/src/collection.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/collection.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode, MaxEncodedLen};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- AccountId: Serialize,
- BoundedString: AsRef<[u8]>,
- BoundedSymbol: AsRef<[u8]>
- "#)
-)]
-pub struct CollectionInfo<BoundedString, BoundedSymbol, AccountId> {
- /// Current bidder and bid price.
- pub issuer: AccountId,
-
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub metadata: BoundedString,
- pub max: Option<u32>,
-
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub symbol: BoundedSymbol,
- pub nfts_count: u32,
-}
primitives/rmrk-traits/src/lib.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/lib.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-#![cfg_attr(not(feature = "std"), no_std)]
-
-pub mod base;
-pub mod collection;
-pub mod nft;
-pub mod part;
-pub mod property;
-pub mod resource;
-pub mod theme;
-
-#[cfg(feature = "std")]
-mod serialize;
-
-pub use base::BaseInfo;
-pub use part::{EquippableList, FixedPart, PartType, SlotPart};
-pub use theme::{Theme, ThemeProperty};
-pub use collection::CollectionInfo;
-pub use nft::{AccountIdOrCollectionNftTuple, NftInfo, RoyaltyInfo, NftChild};
-pub use property::PropertyInfo;
-pub use resource::{BasicResource, ComposableResource, ResourceInfo, ResourceTypes, SlotResource};
-pub mod primitives {
- pub type CollectionId = u32;
- pub type ResourceId = u32;
- pub type NftId = u32;
- pub type BaseId = u32;
- pub type SlotId = u32;
- pub type PartId = u32;
- pub type ZIndex = u32;
-}
primitives/rmrk-traits/src/nft.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/nft.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode, MaxEncodedLen};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-use crate::primitives::*;
-
-#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-pub enum AccountIdOrCollectionNftTuple<AccountId> {
- AccountId(AccountId),
- CollectionAndNftTuple(CollectionId, NftId),
-}
-
-/// Royalty information (recipient and amount)
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-pub struct RoyaltyInfo<AccountId, RoyaltyAmount> {
- /// Recipient (AccountId) of the royalty
- pub recipient: AccountId,
- /// Amount (Permill) of the royalty
- pub amount: RoyaltyAmount,
-}
-
-/// Nft info.
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- AccountId: Serialize,
- RoyaltyAmount: Serialize,
- BoundedString: AsRef<[u8]>
- "#)
-)]
-pub struct NftInfo<AccountId, RoyaltyAmount, BoundedString> {
- /// The owner of the NFT, can be either an Account or a tuple (CollectionId, NftId)
- pub owner: AccountIdOrCollectionNftTuple<AccountId>,
- /// Royalty (optional)
- pub royalty: Option<RoyaltyInfo<AccountId, RoyaltyAmount>>,
-
- /// Arbitrary data about an instance, e.g. IPFS hash
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub metadata: BoundedString,
-
- /// Equipped state
- pub equipped: bool,
- /// Pending state (if sent to NFT)
- pub pending: bool,
-}
-
-#[cfg_attr(feature = "std", derive(PartialEq, Eq, Serialize))]
-#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
-pub struct NftChild {
- pub collection_id: CollectionId,
- pub nft_id: NftId,
-}
primitives/rmrk-traits/src/part.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/part.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode, MaxEncodedLen};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-use crate::primitives::*;
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct FixedPart<BoundedString> {
- pub id: PartId,
- pub z: ZIndex,
-
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub src: BoundedString,
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
- feature = "std",
- serde(bound = "BoundedCollectionList: AsRef<[CollectionId]>")
-)]
-pub enum EquippableList<BoundedCollectionList> {
- All,
- Empty,
- Custom(#[cfg_attr(feature = "std", serde(with = "serialize::vec"))] BoundedCollectionList),
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedString: AsRef<[u8]>,
- BoundedCollectionList: AsRef<[CollectionId]>
- "#)
-)]
-pub struct SlotPart<BoundedString, BoundedCollectionList> {
- pub id: PartId,
- pub equippable: EquippableList<BoundedCollectionList>,
-
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub src: BoundedString,
-
- pub z: ZIndex,
-}
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedString: AsRef<[u8]>,
- BoundedCollectionList: AsRef<[CollectionId]>
- "#)
-)]
-pub enum PartType<BoundedString, BoundedCollectionList> {
- FixedPart(FixedPart<BoundedString>),
- SlotPart(SlotPart<BoundedString, BoundedCollectionList>),
-}
-
-impl<BoundedString, BoundedCollectionList> PartType<BoundedString, BoundedCollectionList> {
- pub fn id(&self) -> PartId {
- match self {
- Self::FixedPart(part) => part.id,
- Self::SlotPart(part) => part.id,
- }
- }
-
- pub fn src(&self) -> &BoundedString {
- match self {
- Self::FixedPart(part) => &part.src,
- Self::SlotPart(part) => &part.src,
- }
- }
-
- pub fn z_index(&self) -> ZIndex {
- match self {
- Self::FixedPart(part) => part.z,
- Self::SlotPart(part) => part.z,
- }
- }
-}
primitives/rmrk-traits/src/property.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/property.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[derive(Encode, Decode, PartialEq, TypeInfo)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedKey: AsRef<[u8]>,
- BoundedValue: AsRef<[u8]>
- "#)
-)]
-pub struct PropertyInfo<BoundedKey, BoundedValue> {
- /// Key of the property
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub key: BoundedKey,
-
- /// Value of the property
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub value: BoundedValue,
-}
primitives/rmrk-traits/src/resource.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/resource.rs
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode, MaxEncodedLen};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-use crate::primitives::*;
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct BasicResource<BoundedString> {
- /// If the resource is Media, the base property is absent. Media src should be a URI like an
- /// IPFS hash.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub src: Option<BoundedString>,
-
- /// Reference to IPFS location of metadata
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub metadata: Option<BoundedString>,
-
- /// Optional location or identier of license
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub license: Option<BoundedString>,
-
- /// If the resource has the thumb property, this will be a URI to a thumbnail of the given
- /// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
- /// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
- /// another bird, showing the full render of one bird inside the other's inventory might be a
- /// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
- /// image that is lighter and faster to load but representative of this resource.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub thumb: Option<BoundedString>,
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedString: AsRef<[u8]>,
- BoundedParts: AsRef<[PartId]>
- "#)
-)]
-pub struct ComposableResource<BoundedString, BoundedParts> {
- /// If a resource is composed, it will have an array of parts that compose it
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub parts: BoundedParts,
-
- /// A Base is uniquely identified by the combination of the word `base`, its minting block
- /// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
- /// base-4477293-kanaria_superbird.
- pub base: BaseId,
-
- /// If the resource is Media, the base property is absent. Media src should be a URI like an
- /// IPFS hash.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub src: Option<BoundedString>,
-
- /// Reference to IPFS location of metadata
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub metadata: Option<BoundedString>,
-
- /// If the resource has the slot property, it was designed to fit into a specific Base's slot.
- /// The baseslot will be composed of two dot-delimited values, like so:
- /// "base-4477293-kanaria_superbird.machine_gun_scope". This means: "This resource is
- /// compatible with the machine_gun_scope slot of base base-4477293-kanaria_superbird
-
- /// Optional location or identier of license
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub license: Option<BoundedString>,
-
- /// If the resource has the thumb property, this will be a URI to a thumbnail of the given
- /// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
- /// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
- /// another bird, showing the full render of one bird inside the other's inventory might be a
- /// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
- /// image that is lighter and faster to load but representative of this resource.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub thumb: Option<BoundedString>,
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct SlotResource<BoundedString> {
- /// A Base is uniquely identified by the combination of the word `base`, its minting block
- /// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
- /// base-4477293-kanaria_superbird.
- pub base: BaseId,
-
- /// If the resource is Media, the base property is absent. Media src should be a URI like an
- /// IPFS hash.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub src: Option<BoundedString>,
-
- /// Reference to IPFS location of metadata
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub metadata: Option<BoundedString>,
-
- /// If the resource has the slot property, it was designed to fit into a specific Base's slot.
- /// The baseslot will be composed of two dot-delimited values, like so:
- /// "base-4477293-kanaria_superbird.machine_gun_scope". This means: "This resource is
- /// compatible with the machine_gun_scope slot of base base-4477293-kanaria_superbird
- pub slot: SlotId,
-
- /// The license field, if present, should contain a link to a license (IPFS or static HTTP
- /// url), or an identifier, like RMRK_nocopy or ipfs://ipfs/someHashOfLicense.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub license: Option<BoundedString>,
-
- /// If the resource has the thumb property, this will be a URI to a thumbnail of the given
- /// resource. For example, if we have a composable NFT like a Kanaria bird, the resource is
- /// complex and too detailed to show in a search-results page or a list. Also, if a bird owns
- /// another bird, showing the full render of one bird inside the other's inventory might be a
- /// bit of a strain on the browser. For this reason, the thumb value can contain a URI to an
- /// image that is lighter and faster to load but representative of this resource.
- #[cfg_attr(feature = "std", serde(with = "serialize::opt_vec"))]
- pub thumb: Option<BoundedString>,
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedString: AsRef<[u8]>,
- BoundedParts: AsRef<[PartId]>
- "#)
-)]
-pub enum ResourceTypes<BoundedString, BoundedParts> {
- Basic(BasicResource<BoundedString>),
- Composable(ComposableResource<BoundedString, BoundedParts>),
- Slot(SlotResource<BoundedString>),
-}
-
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedString: AsRef<[u8]>,
- BoundedParts: AsRef<[PartId]>
- "#)
-)]
-pub struct ResourceInfo<BoundedString, BoundedParts> {
- /// ID is a unique identifier for a resource across all those of a single NFT.
- /// The combination of a collection ID, an NFT ID, and the resource ID must be
- /// unique across the entire RMRK ecosystem.
- //#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub id: ResourceId,
-
- /// Resource type and the accordingly structured data stored
- pub resource: ResourceTypes<BoundedString, BoundedParts>,
-
- /// If resource is sent to non-rootowned NFT, pending will be false and need to be accepted
- pub pending: bool,
-
- /// If resource removal request is sent by non-rootowned NFT, pending will be true and need to be accepted
- pub pending_removal: bool,
-}
primitives/rmrk-traits/src/serialize.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/serialize.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use core::convert::AsRef;
-use serde::ser::{self, Serialize};
-
-pub mod vec {
- use super::*;
-
- pub fn serialize<D, V, C>(value: &C, serializer: D) -> Result<D::Ok, D::Error>
- where
- D: ser::Serializer,
- V: Serialize,
- C: AsRef<[V]>,
- {
- value.as_ref().serialize(serializer)
- }
-}
-
-pub mod opt_vec {
- use super::*;
-
- pub fn serialize<D, V, C>(value: &Option<C>, serializer: D) -> Result<D::Ok, D::Error>
- where
- D: ser::Serializer,
- V: Serialize,
- C: AsRef<[V]>,
- {
- match value {
- Some(value) => super::vec::serialize(value, serializer),
- None => serializer.serialize_none(),
- }
- }
-}
primitives/rmrk-traits/src/theme.rsdiffbeforeafterboth--- a/primitives/rmrk-traits/src/theme.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2021-2022 RMRK
-// This file is part of rmrk-substrate.
-// License: Apache 2.0 modified by RMRK, see https://github.com/rmrk-team/rmrk-substrate/blob/main/LICENSE
-
-use codec::{Decode, Encode};
-use scale_info::TypeInfo;
-
-#[cfg(feature = "std")]
-use serde::Serialize;
-
-#[cfg(feature = "std")]
-use crate::serialize;
-
-#[cfg_attr(feature = "std", derive(Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
-#[cfg_attr(
- feature = "std",
- serde(bound = r#"
- BoundedString: AsRef<[u8]>,
- PropertyList: AsRef<[ThemeProperty<BoundedString>]>,
- "#)
-)]
-pub struct Theme<BoundedString, PropertyList> {
- /// Name of the theme
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub name: BoundedString,
-
- /// Theme properties
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub properties: PropertyList,
- /// Inheritability
- pub inherit: bool,
-}
-
-#[cfg_attr(feature = "std", derive(Eq, Serialize))]
-#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
-#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
-pub struct ThemeProperty<BoundedString> {
- /// Key of the property
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub key: BoundedString,
-
- /// Value of the property
- #[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
- pub value: BoundedString,
-}
runtime/common/config/pallets/mod.rsdiffbeforeafterboth--- a/runtime/common/config/pallets/mod.rs
+++ b/runtime/common/config/pallets/mod.rs
@@ -35,9 +35,6 @@
};
use sp_arithmetic::Perbill;
-#[cfg(feature = "rmrk")]
-pub mod rmrk;
-
#[cfg(feature = "scheduler")]
pub mod scheduler;
runtime/common/config/pallets/rmrk.rsdiffbeforeafterboth--- a/runtime/common/config/pallets/rmrk.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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/>.
-
-use crate::{Runtime, RuntimeEvent};
-
-impl pallet_proxy_rmrk_core::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
- type RuntimeEvent = RuntimeEvent;
-}
-
-impl pallet_proxy_rmrk_equip::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
- type RuntimeEvent = RuntimeEvent;
-}
runtime/common/construct_runtime.rsdiffbeforeafterboth--- a/runtime/common/construct_runtime.rs
+++ b/runtime/common/construct_runtime.rs
@@ -82,11 +82,9 @@
Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
- #[cfg(feature = "rmrk")]
- RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
+ // RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
- #[cfg(feature = "rmrk")]
- RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
+ // RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
#[cfg(feature = "app-promotion")]
AppPromotion: pallet_app_promotion::{Pallet, Call, Storage, Event<T>} = 73,
runtime/common/maintenance.rsdiffbeforeafterboth--- a/runtime/common/maintenance.rs
+++ b/runtime/common/maintenance.rs
@@ -70,11 +70,6 @@
#[cfg(feature = "scheduler")]
RuntimeCall::Scheduler(_) => Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
- #[cfg(feature = "rmrk")]
- RuntimeCall::RmrkCore(_) | RuntimeCall::RmrkEquip(_) => {
- Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
- }
-
#[cfg(feature = "app-promotion")]
RuntimeCall::AppPromotion(_) => {
Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
runtime/common/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -231,149 +231,6 @@
}
}
- impl rmrk_rpc::RmrkApi<
- Block,
- AccountId,
- RmrkCollectionInfo<AccountId>,
- RmrkInstanceInfo<AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<AccountId>,
- RmrkPartType,
- RmrkTheme
- > for Runtime {
- fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>();
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn collection_properties(
- collection_id: RmrkCollectionId,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn nft_properties(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn nft_resources(collection_id: RmrkCollectionId,nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn nft_resource_priority(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- resource_id: RmrkResourceId
- ) -> Result<Option<u32>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
-
- #[allow(unused_variables)]
- fn theme(
- base_id: RmrkBaseId,
- theme_name: RmrkThemeName,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Option<RmrkTheme>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys);
-
- #[cfg(not(feature = "rmrk"))]
- return unsupported!();
- }
- }
-
impl sp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
VERSION
@@ -701,13 +558,7 @@
#[cfg(feature = "scheduler")]
list_benchmark!(list, extra, pallet_unique_scheduler_v2, Scheduler);
-
- #[cfg(feature = "rmrk")]
- list_benchmark!(list, extra, pallet_proxy_rmrk_core, RmrkCore);
- #[cfg(feature = "rmrk")]
- list_benchmark!(list, extra, pallet_proxy_rmrk_equip, RmrkEquip);
-
#[cfg(feature = "collator-selection")]
list_benchmark!(list, extra, pallet_collator_selection, CollatorSelection);
@@ -771,12 +622,6 @@
#[cfg(feature = "scheduler")]
add_benchmark!(params, batches, pallet_unique_scheduler_v2, Scheduler);
-
- #[cfg(feature = "rmrk")]
- add_benchmark!(params, batches, pallet_proxy_rmrk_core, RmrkCore);
-
- #[cfg(feature = "rmrk")]
- add_benchmark!(params, batches, pallet_proxy_rmrk_equip, RmrkEquip);
#[cfg(feature = "collator-selection")]
add_benchmark!(params, batches, pallet_collator_selection, CollatorSelection);
runtime/opal/Cargo.tomldiffbeforeafterboth--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -41,8 +41,6 @@
'pallet-inflation/runtime-benchmarks',
'pallet-maintenance/runtime-benchmarks',
'pallet-nonfungible/runtime-benchmarks',
- 'pallet-proxy-rmrk-core/runtime-benchmarks',
- 'pallet-proxy-rmrk-equip/runtime-benchmarks',
'pallet-refungible/runtime-benchmarks',
'pallet-structure/runtime-benchmarks',
'pallet-timestamp/runtime-benchmarks',
@@ -95,8 +93,6 @@
'pallet-identity/std',
'pallet-inflation/std',
'pallet-nonfungible/std',
- 'pallet-proxy-rmrk-core/std',
- 'pallet-proxy-rmrk-equip/std',
'pallet-randomness-collective-flip/std',
'pallet-refungible/std',
'pallet-structure/std',
@@ -108,7 +104,6 @@
'pallet-unique-scheduler-v2/std',
'pallet-unique/std',
'parachain-info/std',
- 'rmrk-rpc/std',
'serde',
'sp-api/std',
'sp-block-builder/std',
@@ -176,8 +171,6 @@
'pallet-inflation/try-runtime',
'pallet-maintenance/try-runtime',
'pallet-nonfungible/try-runtime',
- 'pallet-proxy-rmrk-core/try-runtime',
- 'pallet-proxy-rmrk-equip/try-runtime',
'pallet-randomness-collective-flip/try-runtime',
'pallet-refungible/try-runtime',
'pallet-structure/try-runtime',
@@ -197,7 +190,6 @@
foreign-assets = []
pallet-test-utils = []
refungible = []
-rmrk = []
scheduler = []
################################################################################
@@ -282,14 +274,11 @@
pallet-inflation = { workspace = true }
pallet-maintenance = { workspace = true }
pallet-nonfungible = { workspace = true }
-pallet-proxy-rmrk-core = { workspace = true }
-pallet-proxy-rmrk-equip = { workspace = true }
pallet-refungible = { workspace = true }
pallet-structure = { workspace = true }
pallet-unique = { workspace = true }
pallet-unique-scheduler-v2 = { workspace = true }
precompile-utils-macro = { workspace = true }
-rmrk-rpc = { workspace = true }
scale-info = { workspace = true }
up-common = { workspace = true }
up-data-structs = { workspace = true }
runtime/quartz/Cargo.tomldiffbeforeafterboth--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -42,8 +42,6 @@
'pallet-inflation/runtime-benchmarks',
'pallet-maintenance/runtime-benchmarks',
'pallet-nonfungible/runtime-benchmarks',
- 'pallet-proxy-rmrk-core/runtime-benchmarks',
- 'pallet-proxy-rmrk-equip/runtime-benchmarks',
'pallet-refungible/runtime-benchmarks',
'pallet-structure/runtime-benchmarks',
'pallet-timestamp/runtime-benchmarks',
@@ -95,8 +93,6 @@
'pallet-fungible/std',
'pallet-inflation/std',
'pallet-nonfungible/std',
- 'pallet-proxy-rmrk-core/std',
- 'pallet-proxy-rmrk-equip/std',
'pallet-randomness-collective-flip/std',
'pallet-refungible/std',
'pallet-structure/std',
@@ -107,7 +103,6 @@
'pallet-treasury/std',
'pallet-unique/std',
'parachain-info/std',
- 'rmrk-rpc/std',
'serde',
'sp-api/std',
'sp-block-builder/std',
@@ -171,8 +166,6 @@
'pallet-inflation/try-runtime',
'pallet-maintenance/try-runtime',
'pallet-nonfungible/try-runtime',
- 'pallet-proxy-rmrk-core/try-runtime',
- 'pallet-proxy-rmrk-equip/try-runtime',
'pallet-randomness-collective-flip/try-runtime',
'pallet-refungible/try-runtime',
'pallet-structure/try-runtime',
@@ -189,7 +182,6 @@
collator-selection = []
foreign-assets = []
refungible = []
-rmrk = []
scheduler = []
################################################################################
@@ -228,7 +220,6 @@
pallet-xcm = { workspace = true }
parachain-info = { workspace = true }
polkadot-parachain = { workspace = true }
-rmrk-rpc = { workspace = true }
smallvec = { workspace = true }
sp-api = { workspace = true }
sp-arithmetic = { workspace = true }
@@ -260,8 +251,6 @@
pallet-identity = { workspace = true }
pallet-inflation = { workspace = true }
pallet-nonfungible = { workspace = true }
-pallet-proxy-rmrk-core = { workspace = true }
-pallet-proxy-rmrk-equip = { workspace = true }
pallet-refungible = { workspace = true }
pallet-structure = { workspace = true }
pallet-unique = { workspace = true }
runtime/unique/Cargo.tomldiffbeforeafterboth--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -39,8 +39,6 @@
'pallet-inflation/runtime-benchmarks',
'pallet-maintenance/runtime-benchmarks',
'pallet-nonfungible/runtime-benchmarks',
- 'pallet-proxy-rmrk-core/runtime-benchmarks',
- 'pallet-proxy-rmrk-equip/runtime-benchmarks',
'pallet-refungible/runtime-benchmarks',
'pallet-structure/runtime-benchmarks',
'pallet-timestamp/runtime-benchmarks',
@@ -93,8 +91,6 @@
'pallet-fungible/std',
'pallet-inflation/std',
'pallet-nonfungible/std',
- 'pallet-proxy-rmrk-core/std',
- 'pallet-proxy-rmrk-equip/std',
'pallet-randomness-collective-flip/std',
'pallet-refungible/std',
'pallet-structure/std',
@@ -105,7 +101,6 @@
'pallet-treasury/std',
'pallet-unique/std',
'parachain-info/std',
- 'rmrk-rpc/std',
'sp-api/std',
'sp-block-builder/std',
'sp-core/std',
@@ -169,8 +164,6 @@
'pallet-inflation/try-runtime',
'pallet-maintenance/try-runtime',
'pallet-nonfungible/try-runtime',
- 'pallet-proxy-rmrk-core/try-runtime',
- 'pallet-proxy-rmrk-equip/try-runtime',
'pallet-randomness-collective-flip/try-runtime',
'pallet-refungible/try-runtime',
'pallet-structure/try-runtime',
@@ -187,7 +180,6 @@
collator-selection = []
foreign-assets = []
refungible = []
-rmrk = []
scheduler = []
################################################################################
@@ -255,12 +247,9 @@
pallet-identity = { workspace = true }
pallet-inflation = { workspace = true }
pallet-nonfungible = { workspace = true }
-pallet-proxy-rmrk-core = { workspace = true }
-pallet-proxy-rmrk-equip = { workspace = true }
pallet-refungible = { workspace = true }
pallet-structure = { workspace = true }
pallet-unique = { workspace = true }
-rmrk-rpc = { workspace = true }
scale-info = { workspace = true }
up-common = { workspace = true }
up-data-structs = { workspace = true }
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -43,7 +43,6 @@
"testEthFractionalizer": "yarn setup && mocha --timeout 9999999 -r ts-node/register './**/eth/fractionalizer/**/*.*test.ts'",
"testEthMarketplace": "yarn setup && mocha --timeout 9999999 -r ts-node/register './**/eth/marketplace/**/*.*test.ts'",
"testEvent": "yarn setup && mocha --timeout 9999999 -r ts-node/register ./src/check-event/*.*test.ts",
- "testRmrk": "yarn setup && mocha --timeout 9999999 -r ts-node/register ./**/rmrk/*.*test.ts",
"testEthPayable": "mocha --timeout 9999999 -r ts-node/register './**/eth/payable.test.ts'",
"testEvmCoder": "mocha --timeout 9999999 -r ts-node/register './**/eth/evmCoder.test.ts'",
"testNesting": "mocha --timeout 9999999 -r ts-node/register ./**/nest.test.ts",
tests/src/.outdated/rmrk/acceptNft.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/acceptNft.seqtest.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {
- createCollection,
- mintNft,
- sendNft,
- acceptNft,
-} from './util/tx';
-import {NftIdTuple} from './util/fetch';
-import {isNftChildOfAnother, expectTxFailure, requirePallets, Pallets} from './util/helpers';
-
-describe('integration test: accept NFT', () => {
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- const createTestCollection = async (issuerUri: string) => {
- return await createCollection(
- api,
- issuerUri,
- 'accept-metadata',
- null,
- 'acpt',
- );
- };
-
- it('accept NFT', async () => {
- const ownerAlice = alice;
- const ownerBob = bob;
-
- const aliceCollectionId = await createTestCollection(alice);
- const bobCollectionId = await createTestCollection(bob);
-
- const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT);
- await acceptNft(api, alice, bobCollectionId, childNftId, newOwnerNFT);
-
- const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.true;
- });
-
- it('[negative] unable to accept NFT by a not-an-owner', async () => {
- const ownerAlice = alice;
- const ownerBob = bob;
-
- const aliceCollectionId = await createTestCollection(alice);
- const bobCollectionId = await createTestCollection(bob);
-
- const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT);
- const tx = acceptNft(api, bob, bobCollectionId, childNftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('[negative] unable to accept non-existing NFT', async () => {
- const collectionId = 0;
- const maxNftId = 0xFFFFFFFF;
-
- const owner = alice;
- const aliceCollectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, owner, aliceCollectionId, 'parent-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- const tx = acceptNft(api, alice, collectionId, maxNftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative] unable to accept NFT which is not sent', async () => {
- const ownerAlice = alice;
- const ownerBob = bob;
-
- const aliceCollectionId = await createTestCollection(alice);
- const bobCollectionId = await createTestCollection(bob);
-
- const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- const tx = acceptNft(api, alice, bobCollectionId, childNftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
-
- const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.false;
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/addResource.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/addResource.seqtest.ts
+++ /dev/null
@@ -1,435 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {NftIdTuple} from './util/fetch';
-import {expectTxFailure, getResourceById, requirePallets, Pallets} from './util/helpers';
-import {
- addNftBasicResource,
- acceptNftResource,
- createCollection,
- mintNft,
- sendNft,
- addNftSlotResource,
- addNftComposableResource,
-} from './util/tx';
-import {RmrkTraitsResourceResourceInfo as ResourceInfo} from '@polkadot/types/lookup';
-
-describe('integration test: add NFT resource', () => {
- const alice = '//Alice';
- const bob = '//Bob';
- const src = 'test-res-src';
- const metadata = 'test-res-metadata';
- const license = 'test-res-license';
- const thumb = 'test-res-thumb';
-
- const nonexistentId = 99999;
-
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- it('add resource', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
- });
-
- it('add a resource to the nested NFT', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const parentNftId = await mintNft(api, alice, alice, collectionIdAlice, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, alice, collectionIdAlice, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionIdAlice, childNftId, newOwnerNFT);
-
- await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- childNftId,
- src,
- metadata,
- license,
- thumb,
- );
- });
-
- it('add multiple resources', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const baseId = 42;
- const slotId = 10;
- const parts = [0, 5, 2];
-
- const resourcesInfo = [];
- const resourceNum = 4;
-
- const checkResource = (resource: ResourceInfo, resType: string, expectedId: number, expected: {
- src: string,
- metadata: string,
- license: string,
- thumb: string
- }) => {
-
- // FIXME A workaround. It seems it is a PolkadotJS bug.
- // All of the following are `false`.
- //
- // console.log('>>> basic:', resource.resource.isBasic);
- // console.log('>>> composable:', resource.resource.isComposable);
- // console.log('>>> slot:', resource.resource.isSlot);
- const resourceJson = (resource.resource.toHuman() as any)[resType];
-
- expect(resource.id.toNumber(), 'Error: Invalid resource Id')
- .to.be.eq(expectedId);
-
- expect(resourceJson.src, 'Error: Invalid resource src')
- .to.be.eq(expected.src);
- expect(resourceJson.metadata, 'Error: Invalid resource metadata')
- .to.be.eq(expected.metadata);
- expect(resourceJson.license, 'Error: Invalid resource license')
- .to.be.eq(expected.license);
- expect(resourceJson.thumb, 'Error: Invalid resource thumb')
- .to.be.eq(expected.thumb);
- };
-
- for (let i = 0; i < resourceNum; i++) {
- resourcesInfo.push({
- src: src + 'r-' + i,
- metadata: metadata + 'r-' + i,
- license: license + 'r-' + i,
- thumb: thumb + 'r-' + i,
- });
- }
-
- const firstBasicResourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- resourcesInfo[0].src,
- resourcesInfo[0].metadata,
- resourcesInfo[0].license,
- resourcesInfo[0].thumb,
- );
-
- const secondBasicResourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- resourcesInfo[1].src,
- resourcesInfo[1].metadata,
- resourcesInfo[1].license,
- resourcesInfo[1].thumb,
- );
-
- const composableResourceId = await addNftComposableResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- parts,
- baseId,
- resourcesInfo[2].src,
- resourcesInfo[2].metadata,
- resourcesInfo[2].license,
- resourcesInfo[2].thumb,
- );
-
- const slotResourceId = await addNftSlotResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- baseId,
- slotId,
- resourcesInfo[3].src,
- resourcesInfo[3].metadata,
- resourcesInfo[3].license,
- resourcesInfo[3].thumb,
- );
-
- const firstResource = await getResourceById(api, collectionIdAlice, nftAlice, firstBasicResourceId);
- await checkResource(firstResource, 'Basic', firstBasicResourceId, resourcesInfo[0]);
-
- const secondResource = await getResourceById(api, collectionIdAlice, nftAlice, secondBasicResourceId);
- await checkResource(secondResource, 'Basic', secondBasicResourceId, resourcesInfo[1]);
-
- const composableResource = await getResourceById(api, collectionIdAlice, nftAlice, composableResourceId);
- await checkResource(composableResource, 'Composable', composableResourceId, resourcesInfo[2]);
-
- const slotResource = await getResourceById(api, collectionIdAlice, nftAlice, slotResourceId);
- await checkResource(slotResource, 'Slot', slotResourceId, resourcesInfo[3]);
- });
-
- it('[negative]: unable to add a resource to the non-existing NFT', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const tx = addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nonexistentId,
- src,
- metadata,
- license,
- thumb,
- );
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative]: unable to add a resource by a not-an-owner user', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const tx = addNftBasicResource(
- api,
- bob,
- 'added',
- collectionIdAlice,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('[negative]: unable to add a resource to the nested NFT if it isnt root owned by the caller', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const parentNftId = await mintNft(api, alice, alice, collectionIdAlice, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, alice, collectionIdAlice, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionIdAlice, childNftId, newOwnerNFT);
-
- const tx = addNftBasicResource(
- api,
- bob,
- 'added',
- collectionIdAlice,
- childNftId,
- src,
- metadata,
- license,
- thumb,
- );
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('accept resource', async () => {
- const collectionIdBob = await createCollection(
- api,
- bob,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- bob,
- alice,
- collectionIdBob,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- bob,
- 'pending',
- collectionIdBob,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- await acceptNftResource(api, alice, collectionIdBob, nftAlice, resourceId);
- });
-
- it('[negative]: unable to accept a non-existing resource', async () => {
- const collectionIdBob = await createCollection(
- api,
- bob,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- bob,
- alice,
- collectionIdBob,
- 'nft-metadata',
- );
-
- const tx = acceptNftResource(api, alice, collectionIdBob, nftAlice, nonexistentId);
- await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx);
- });
-
- it('[negative]: unable to accept a resource by a not-an-NFT-owner user', async () => {
- const collectionIdBob = await createCollection(
- api,
- bob,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- bob,
- alice,
- collectionIdBob,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- bob,
- 'pending',
- collectionIdBob,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- const tx = acceptNftResource(api, bob, collectionIdBob, nftAlice, resourceId);
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('[negative]: unable to accept a resource to a non-target NFT', async () => {
- const collectionIdBob = await createCollection(
- api,
- bob,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- bob,
- alice,
- collectionIdBob,
- 'nft-metadata',
- );
-
- const wrongNft = await mintNft(
- api,
- bob,
- alice,
- collectionIdBob,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- bob,
- 'pending',
- collectionIdBob,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- const tx = acceptNftResource(api, bob, collectionIdBob, wrongNft, resourceId);
-
- await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx);
- });
-
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/addTheme.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/addTheme.seqtest.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {createBase, addTheme} from './util/tx';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {getThemeNames} from './util/fetch';
-
-describe('integration test: add Theme to Base', () => {
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkEquip]);
- });
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- it('add default theme', async () => {
- const baseId = await createBase(api, alice, 'default-themed-base', 'DTBase', []);
- await addTheme(api, alice, baseId, {
- name: 'default',
- properties: [
- {
- key: 'some-key',
- value: 'some-key-value',
- },
- {
- key: 'another-key',
- value: 'another-key-value',
- },
- ],
- });
- });
-
- it('add default theme and a custom one', async () => {
- const baseId = await createBase(api, alice, '2-themed-base', '2TBase', []);
- await addTheme(api, alice, baseId, {
- name: 'default',
- properties: [
- {
- key: 'default-key',
- value: 'default-key-value',
- },
- ],
- });
- await addTheme(api, alice, baseId, {
- name: 'custom-theme',
- properties: [
- {
- key: 'custom-key-0',
- value: 'custom-key-value-0',
- },
- {
- key: 'custom-key-1',
- value: 'custom-key-value-1',
- },
- ],
- });
- });
-
- it('fetch filtered theme keys', async () => {
- const baseId = await createBase(api, alice, '2-themed-base', '2TBase', []);
- await addTheme(api, alice, baseId, {
- name: 'default',
- properties: [
- {
- key: 'first-key',
- value: 'first-key-value',
- },
- {
- key: 'second-key',
- value: 'second-key-value',
- },
- ],
- }, ['second-key']);
- });
-
- it('fetch theme names', async() => {
- const baseId = await createBase(api, alice, '3-themed-base', '3TBase', []);
- const names = [
- 'default',
- 'first-theme',
- 'second-theme',
- ];
-
- for (let i = 0; i < names.length; i++) {
- await addTheme(api, alice, baseId, {name: names[i], properties: [{key: 'dummy', value: 'dummy'}]});
- }
-
- const fetchedNames = await getThemeNames(api, baseId);
-
- for (let i = 0; i < names.length; i++) {
- const isFound = fetchedNames.find((name) => name === names[i]) !== undefined;
-
- expect(isFound, 'Error: invalid theme names').to.be.true;
- }
- });
-
- it('[negative] unable to add theme to non-existing base', async () => {
- const maxBaseId = 0xFFFFFFFF;
- const tx = addTheme(api, alice, maxBaseId, {
- name: 'default',
- properties: [],
- });
-
- await expectTxFailure(/rmrkEquip\.BaseDoesntExist/, tx);
- });
-
- it('[negative] unable to add custom theme if no default theme', async () => {
- const baseId = await createBase(api, alice, 'no-default-themed-base', 'NDTBase', []);
- const tx = addTheme(api, alice, baseId, {
- name: 'custom-theme',
- properties: [],
- });
-
- await expectTxFailure(/rmrkEquip\.NeedsDefaultThemeFirst/, tx);
- });
-
- it('[negative] unable to add theme by a not-an-owner', async () => {
- const baseId = await createBase(api, alice, 'no-default-themed-base', 'NDTBase', []);
- const tx = addTheme(api, bob, baseId, {
- name: 'default',
- properties: [],
- });
-
- await expectTxFailure(/rmrkEquip\.PermissionError/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/burnNft.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/burnNft.seqtest.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {NftIdTuple, getChildren} from './util/fetch';
-import {burnNft, createCollection, sendNft, mintNft} from './util/tx';
-
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-describe('integration test: burn nft', () => {
- const alice = '//Alice';
- const bob = '//Bob';
-
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
- it('burn nft', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- const nftId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
- await burnNft(api, alice, collectionId, nftId);
- });
- });
-
- it('burn nft with children', async () => {
- const collectionId = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const parentNftId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-
- const childNftId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT);
-
- const childrenBefore = await getChildren(api, collectionId, parentNftId);
- expect(childrenBefore.length === 1, 'Error: parent NFT should have children')
- .to.be.true;
-
- const child = childrenBefore[0];
- expect(child.collectionId.eq(collectionId), 'Error: invalid child collection Id')
- .to.be.true;
-
- expect(child.nftId.eq(childNftId), 'Error: invalid child NFT Id')
- .to.be.true;
-
- await burnNft(api, alice, collectionId, parentNftId);
-
- const childrenAfter = await getChildren(api, collectionId, parentNftId);
-
- expect(childrenAfter.length === 0, 'Error: children should be burned').to.be.true;
- });
-
- it('burn child nft', async () => {
- const collectionId = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const parentNftId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-
- const childNftId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT);
-
- const childrenBefore = await getChildren(api, collectionId, parentNftId);
- expect(childrenBefore.length === 1, 'Error: parent NFT should have children')
- .to.be.true;
-
- const child = childrenBefore[0];
- expect(child.collectionId.eq(collectionId), 'Error: invalid child collection Id')
- .to.be.true;
-
- expect(child.nftId.eq(childNftId), 'Error: invalid child NFT Id')
- .to.be.true;
-
- await burnNft(api, alice, collectionId, childNftId);
-
- const childrenAfter = await getChildren(api, collectionId, parentNftId);
-
- expect(childrenAfter.length === 0, 'Error: children should be burned').to.be.true;
- });
-
- it('[negative] burn non-existing NFT', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- const tx = burnNft(api, alice, collectionId, 99999);
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
- });
-
- it('[negative] burn not an owner NFT user', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- const nftId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
- const tx = burnNft(api, bob, collectionId, nftId);
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/changeCollectionIssuer.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/changeCollectionIssuer.seqtest.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {
- changeIssuer,
- createCollection,
-} from './util/tx';
-
-describe('integration test: collection issuer', () => {
- const alice = '//Alice';
- const bob = '//Bob';
-
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
-
- it('change collection issuer', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- await changeIssuer(api, alice, collectionId, bob);
- });
- });
-
- it('[negative] change not an owner NFT collection issuer', async () => {
- await createCollection(api, bob, 'test-metadata', null, 'test-symbol').then(async (collectionId) => {
- const tx = changeIssuer(api, alice, collectionId, bob);
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
- });
-
- it('[negative] change non-existigit NFT collection issuer', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async () => {
- const tx = changeIssuer(api, alice, 99999, bob);
- await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx);
- });
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/createBase.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/createBase.seqtest.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {requirePallets, Pallets} from './util/helpers';
-import {createCollection, createBase} from './util/tx';
-
-describe('integration test: create new Base', () => {
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
- });
-
- const alice = '//Alice';
-
- it('create empty Base', async () => {
- await createBase(api, alice, 'empty-base-type', 'EBase', []);
- });
-
- it('create Base with fixed part', async () => {
- await createBase(api, alice, 'fixedpart-base-type', 'FPBase', [
- {
- 'FixedPart': {
- id: 42,
- z: 0,
- src: 'some-fixed-url',
- },
- },
- ]);
- });
-
- it('create Base with slot part (no collection)', async () => {
- await createBase(api, alice, 'slotpart-base-type', 'SPBase', [
- {
- 'SlotPart': {
- id: 112,
- equippable: 'Empty',
- z: 0,
- src: 'some-fallback-slot-url',
- },
- },
- ]);
- });
-
- it('create Base with slot part (any collection)', async () => {
- await createBase(api, alice, 'slotpartany-base-type', 'SPABase', [
- {
- 'SlotPart': {
- id: 222,
- equippable: 'All',
- z: 1,
- src: 'some-fallback-slot-url',
- },
- },
- ]);
- });
-
- it('create Base with slot part (custom collections)', async () => {
- const firstCollectionId = await createCollection(
- api,
- alice,
- 'first-collection-meta',
- null,
- 'first-collection',
- );
-
- const secondCollectionId = await createCollection(
- api,
- alice,
- 'first-collection-meta',
- null,
- 'first-collection',
- );
-
- await createBase(api, alice, 'slotpartcustom-base-type', 'SPCBase', [
- {
- 'SlotPart': {
- id: 1024,
- equippable: {
- 'Custom': [firstCollectionId, secondCollectionId],
- },
- z: 2,
- src: 'some-fallback-slot-url',
- },
- },
- ]);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/createCollection.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/createCollection.seqtest.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {requirePallets, Pallets} from './util/helpers';
-import {createCollection} from './util/tx';
-
-describe('Integration test: create new collection', () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
-
- const alice = '//Alice';
-
- it('create NFT collection', async () => {
- await createCollection(api, alice, 'test-metadata', 42, 'test-symbol');
- });
-
- it('create NFT collection without token limit', async () => {
- await createCollection(api, alice, 'no-limit-metadata', null, 'no-limit-symbol');
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/deleteCollection.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/deleteCollection.seqtest.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {createCollection, deleteCollection} from './util/tx';
-
-describe('integration test: delete collection', () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- it('delete NFT collection', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- await deleteCollection(api, alice, collectionId.toString());
- });
- });
-
- it('[negative] delete non-existing NFT collection', async () => {
- const tx = deleteCollection(api, alice, '99999');
- await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx);
- });
-
- it('[negative] delete not an owner NFT collection', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- const tx = deleteCollection(api, bob, collectionId.toString());
- await expectTxFailure(/rmrkCore.NoPermission/, tx);
- });
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/equipNft.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/equipNft.seqtest.ts
+++ /dev/null
@@ -1,340 +0,0 @@
-import {ApiPromise} from '@polkadot/api';
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {getNft, NftIdTuple} from './util/fetch';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {
- addNftComposableResource,
- addNftSlotResource,
- createBase,
- createCollection,
- equipNft,
- mintNft,
- sendNft,
- unequipNft,
-} from './util/tx';
-
-const alice = '//Alice';
-const bob = '//Bob';
-
-const composableParts: number[] = [5, 2, 7];
-const composableSrc = 'test-cmp-src';
-const composableMetadata = 'test-cmp-metadata';
-const composableLicense = 'test-comp-license';
-const composableThumb = 'test-comp-thumb';
-
-const slotSrc = 'test-slot-src';
-const slotLicense = 'test-slot-license';
-const slotMetadata = 'test-slot-metadata';
-const slotThumb = 'test-slot-thumb';
-
-const slotId = 1;
-
-function createTestCollection(api: ApiPromise): Promise<number> {
- return createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-}
-
-async function mintTestNft(api: ApiPromise, collectionId: number): Promise<number> {
- return await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-}
-
-async function mintChildNft(api: ApiPromise, collectionId: number, parentNftId: number): Promise<number> {
- const nftChildId = await mintTestNft(api, collectionId);
-
- const parentNFT: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionId, nftChildId, parentNFT);
-
- return nftChildId;
-}
-
-function createTestBase(api: ApiPromise): Promise<number> {
- return createBase(api, alice, 'test-base', 'DTBase', [
- {
- SlotPart: {
- id: slotId,
- equippable: 'All',
- z: 1,
- src: slotSrc,
- },
- },
- ]);
-}
-
-async function addTestComposable(api: ApiPromise, collectionId: number, nftId: number, baseId: number) {
- await addNftComposableResource(
- api,
- alice,
- 'added',
- collectionId,
- nftId,
- composableParts,
- baseId,
- composableSrc,
- composableMetadata,
- composableLicense,
- composableThumb,
- );
-}
-
-async function addTestSlot(api: ApiPromise, collectionId: number, nftId: number, baseId: number, slotId: number): Promise<number> {
- return await addNftSlotResource(
- api,
- alice,
- 'added',
- collectionId,
- nftId,
- baseId,
- slotId,
- slotSrc,
- slotMetadata,
- slotLicense,
- slotThumb,
- );
-}
-
-async function checkEquipStatus(
- api: ApiPromise,
- expectedStatus: 'equipped' | 'unequipped',
- collectionId: number,
- nftId: number,
-) {
- const itemNftDataOpt = await getNft(api, collectionId, nftId);
- expect(itemNftDataOpt.isSome, 'Error: unable to fetch item NFT data');
-
- const itemNftData = itemNftDataOpt.unwrap();
- expect(itemNftData.equipped.isTrue, `Error: item NFT should be ${expectedStatus}`)
- .to.be.equal(expectedStatus === 'equipped');
-}
-
-describe.skip('integration test: Equip NFT', () => {
-
- let api: any;
-
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
- });
-
- it('equip nft', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- await equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId);
-
- await checkEquipStatus(api, 'equipped', collectionId, nftChildId);
- });
-
- it('unequip nft', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- await equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId);
-
- await checkEquipStatus(api, 'equipped', collectionId, nftChildId);
-
- await unequipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId);
- await checkEquipStatus(api, 'unequipped', collectionId, nftChildId);
- });
-
- it('[negative] equip NFT onto non-existing NFT', async () => {
- const collectionId = await createTestCollection(api);
-
- const nftChildId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
- const invalidEquipperNFT: NftIdTuple = [collectionId, 9999999];
-
- const baseId = 0;
- const resourceId = 0;
-
- const tx = equipNft(api, alice, itemNFT, invalidEquipperNFT, resourceId, baseId, slotId);
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative] equip non-existing NFT', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'nft-metadata',
- );
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const invalidItemNFT: NftIdTuple = [collectionId, 99999999];
-
- const resourceId = 0;
-
- const tx = equipNft(api, alice, invalidItemNFT, equipperNFT, resourceId, baseId, slotId);
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative] equip NFT by a not-an-owner user', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const tx = equipNft(api, bob, itemNFT, equipperNFT, resourceId, baseId, slotId);
- await expectTxFailure(/rmrkEquip\.PermissionError/, tx);
- });
-
- it('[negative] unable to equip NFT onto indirect parent NFT', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
- const nftGrandchildId = await mintChildNft(api, collectionId, nftChildId);
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftGrandchildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftGrandchildId];
-
- const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId);
- await expectTxFailure(/rmrkEquip\.MustBeDirectParent/, tx);
- });
-
- it('[negative] unable to equip NFT onto parent NFT with another base', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- const invalidBaseId = 99999;
-
- const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, invalidBaseId, slotId);
- await expectTxFailure(/rmrkEquip\.NoResourceForThisBaseFoundOnNft/, tx);
- });
-
- it('[negative] unable to equip NFT into slot with another id', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createTestBase(api);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- const incorrectSlotId = slotId + 1;
- const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, incorrectSlotId);
- await expectTxFailure(/rmrkEquip\.ItemHasNoResourceToEquipThere/, tx);
- });
-
- it('[negative] unable to equip NFT with incorrect slot (fixed part)', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createBase(api, alice, 'test-base', 'DTBase', [
- {
- FixedPart: {
- id: slotId,
- equippable: 'All',
- z: 1,
- src: slotSrc,
- },
- },
- ]);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId);
- await expectTxFailure(/rmrkEquip\.CantEquipFixedPart/, tx);
- });
-
- it('[negative] unable to equip NFT from a collection that is not allowed by the slot', async () => {
- const collectionId = await createTestCollection(api);
- const nftParentId = await mintTestNft(api, collectionId);
- const nftChildId = await mintChildNft(api, collectionId, nftParentId);
-
- const baseId = await createBase(api, alice, 'test-base', 'DTBase', [
- {
- SlotPart: {
- id: 1,
- z: 1,
- equippable: 'Empty',
- src: slotSrc,
- },
- },
- ]);
-
- await addTestComposable(api, collectionId, nftParentId, baseId);
- const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId);
-
- const equipperNFT: NftIdTuple = [collectionId, nftParentId];
- const itemNFT: NftIdTuple = [collectionId, nftChildId];
-
- const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId);
- await expectTxFailure(/rmrkEquip\.CollectionNotEquippable/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/getOwnedNfts.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/getOwnedNfts.seqtest.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {requirePallets, Pallets} from './util/helpers';
-import {getOwnedNfts} from './util/fetch';
-import {mintNft, createCollection} from './util/tx';
-
-describe('integration test: get owned NFTs', () => {
- let api: any;
-
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
- const alice = '//Alice';
-
- it('fetch all NFTs owned by a user', async () => {
- const owner = alice;
- const collectionMetadata = 'aliceCollectionMetadata';
- const collectionMax = null;
- const collectionSymbol = 'AliceSym';
- const recipientUri = null;
- const royalty = null;
- const nftMetadata = 'alice-NFT-metadata';
-
- const collectionId = await createCollection(
- api,
- alice,
- collectionMetadata,
- collectionMax,
- collectionSymbol,
- );
-
- const nftIds = [
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata + '-0',
- recipientUri,
- royalty,
- ),
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata + '-1',
- recipientUri,
- royalty,
- ),
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata + '-2',
- recipientUri,
- royalty,
- ),
- ];
-
- const ownedNfts = await getOwnedNfts(api, alice, collectionId);
-
- const isFound = (nftId: number) => {
- return ownedNfts.find((ownedNftId) => {
- return ownedNftId === nftId;
- }) !== undefined;
- };
-
- nftIds.forEach((nftId) => {
- expect(isFound(nftId), `NFT ${nftId} should be owned by ${alice}`)
- .to.be.true;
- });
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/lockCollection.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/lockCollection.seqtest.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {createCollection, lockCollection, mintNft} from './util/tx';
-
-describe('integration test: lock collection', () => {
- const alice = '//Alice';
- const bob = '//Bob';
- const max = 5;
-
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- it('lock collection', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- await lockCollection(api, alice, collectionId);
- });
- });
-
- it('[negative] lock non-existing NFT collection', async () => {
- const tx = lockCollection(api, alice, 99999);
- await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx);
- });
-
- it('[negative] lock not an owner NFT collection issuer', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- const tx = lockCollection(api, bob, collectionId);
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
- });
-
- it('lock collection with minting', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- max,
- 'test-symbol',
- ).then(async (collectionId) => {
- for (let i = 0; i < 5; i++) {
- await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'test-metadata',
- null,
- null,
- );
- }
- await lockCollection(api, alice, collectionId, max);
- });
- });
-
- it('[negative] unable to mint NFT inside a locked collection', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- max,
- 'test-symbol',
- ).then(async (collectionId) => {
- await lockCollection(api, alice, collectionId);
- const tx = mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'test-metadata',
- null,
- null,
- );
- await expectTxFailure(/rmrkCore\.CollectionFullOrLocked/, tx);
- });
- });
-
- it('[negative] unable to mint NFT inside a full collection', async () => {
- await createCollection(api, alice, 'test-metadata', 1, 'test-symbol').then(async (collectionId) => {
- await mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'test-metadata',
- null,
- null,
- );
- const tx = mintNft(
- api,
- alice,
- alice,
- collectionId,
- 'test-metadata',
- null,
- null,
- );
- await expectTxFailure(/rmrkCore\.CollectionFullOrLocked/, tx);
- });
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/mintNft.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/mintNft.seqtest.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {getNft} from './util/fetch';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {createCollection, mintNft} from './util/tx';
-
-describe('integration test: mint new NFT', () => {
- let api: any;
-
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
- const alice = '//Alice';
- const bob = '//Bob';
- const maxCollectionId = 0xFFFFFFFF;
- const maxNftId = 0xFFFFFFFF;
-
- it('mint NFT', async () => {
- const owner = null;
- const collectionMetadata = 'mintingCollectionMetadata';
- const collectionMax = null;
- const collectionSymbol = 'MCS';
- const recipientUri = null;
- const royalty = null;
- const nftMetadata = 'NFT-test-metadata';
-
- const collectionId = await createCollection(
- api,
- alice,
- collectionMetadata,
- collectionMax,
- collectionSymbol,
- );
-
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata,
- recipientUri,
- royalty,
- );
- });
-
- it('mint NFT and set another owner', async () => {
- const owner = bob;
- const collectionMetadata = 'setOwnerCollectionMetadata';
- const collectionMax = null;
- const collectionSymbol = 'SOCS';
- const recipientUri = null;
- const royalty = null;
- const nftMetadata = 'setOwner-NFT-metadata';
-
- const collectionId = await createCollection(
- api,
- alice,
- collectionMetadata,
- collectionMax,
- collectionSymbol,
- );
-
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata,
- recipientUri,
- royalty,
- );
- });
-
- it('mint NFT with recipient and roalty', async () => {
- const owner = alice;
- const collectionMetadata = 'mintingCollectionMetadata';
- const collectionMax = null;
- const collectionSymbol = 'MCS';
- const recipientUri = bob;
- const royalty = 70000;
- const nftMetadata = 'recipient-royalty-NFT-test-metadata';
-
- const collectionId = await createCollection(
- api,
- alice,
- collectionMetadata,
- collectionMax,
- collectionSymbol,
- );
-
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata,
- recipientUri,
- royalty,
- );
- });
-
- it('mint NFT with resources', async () => {
- const owner = alice;
- const collectionMetadata = 'mintingCollectionMetadata';
- const collectionMax = null;
- const collectionSymbol = 'MCS';
- const nftMetadata = 'NFT-with-resources-test-metadata';
- const resources = [
- {
- basic: {
- metadata: 'basic-resource-nft-minting',
- },
- }, {
- slot: {
- metadata: 'slot-resource-nft-minting',
- slot: 9,
- },
- }, {
- composable: {
- metadata: 'composable-resource-nft-minting',
- parts: [0, 5, 2],
- },
- }, {
- slot: {
- metadata: 'slot-resource-nft-minting-2',
- thumb: 'srnm2',
- base: 5,
- },
- },
- ];
-
- const collectionId = await createCollection(
- api,
- alice,
- collectionMetadata,
- collectionMax,
- collectionSymbol,
- );
-
- await mintNft(
- api,
- alice,
- owner,
- collectionId,
- nftMetadata,
- null,
- null,
- true,
- resources,
- );
- });
-
- it('[negative] unable to mint NFT within non-existing collection', async () => {
- const owner = alice;
- const recipientUri = null;
- const royalty = null;
- const nftMetadata = 'NFT-test-metadata';
-
- const tx = mintNft(
- api,
- alice,
- owner,
- maxCollectionId,
- nftMetadata,
- recipientUri,
- royalty,
- );
-
- await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx);
- });
-
- it("[negative] unable to mint NFT by a user that isn't the owner of the collection", async () => {
- const owner = alice;
- const collectionMetadata = 'mintingCollectionMetadata';
- const collectionMax = null;
- const collectionSymbol = 'MCS';
- const recipientUri = null;
- const royalty = null;
- const nftMetadata = 'NFT-test-metadata';
-
- const collectionId = await createCollection(
- api,
- alice,
- collectionMetadata,
- collectionMax,
- collectionSymbol,
- );
-
- const tx = mintNft(
- api,
- bob,
- owner,
- collectionId,
- nftMetadata,
- recipientUri,
- royalty,
- );
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('[negative] unable to fetch non-existing NFT', async () => {
- const nft = await getNft(api, maxCollectionId, maxNftId);
- expect(nft.isSome).to.be.false;
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/rejectNft.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/rejectNft.seqtest.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {
- createCollection,
- mintNft,
- sendNft,
- rejectNft,
-} from './util/tx';
-import {NftIdTuple} from './util/fetch';
-import {isNftChildOfAnother, expectTxFailure, requirePallets, Pallets} from './util/helpers';
-
-describe('integration test: reject NFT', () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
-
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- const createTestCollection = async (issuerUri: string) => {
- return await createCollection(
- api,
- issuerUri,
- 'reject-metadata',
- null,
- 'rjct',
- );
- };
-
- it('reject NFT', async () => {
- const ownerAlice = alice;
- const ownerBob = bob;
-
- const aliceCollectionId = await createTestCollection(alice);
- const bobCollectionId = await createTestCollection(bob);
-
- const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT);
- await rejectNft(api, alice, bobCollectionId, childNftId);
-
- const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT);
- expect(isChild, 'Error: rejected NFT is still a child of the target NFT').to.be.false;
- });
-
- it('[negative] unable to reject NFT by a not-an-owner', async () => {
- const ownerAlice = alice;
- const ownerBob = bob;
-
- const aliceCollectionId = await createTestCollection(alice);
- const bobCollectionId = await createTestCollection(bob);
-
- const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT);
- const tx = rejectNft(api, bob, bobCollectionId, childNftId);
-
- await expectTxFailure(/rmrkCore\.CannotRejectNonOwnedNft/, tx);
- });
-
- it('[negative] unable to reject non-existing NFT', async () => {
- const maxNftId = 0xFFFFFFFF;
-
- const collectionId = await createTestCollection(alice);
-
- const tx = rejectNft(api, alice, collectionId, maxNftId);
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative] unable to reject NFT which is not sent', async () => {
- const ownerAlice = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'parent-nft-metadata');
-
- const tx = rejectNft(api, alice, collectionId, nftId);
-
- await expectTxFailure(/rmrkCore\.CannotRejectNonPendingNft/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/removeResource.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/removeResource.seqtest.ts
+++ /dev/null
@@ -1,340 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {NftIdTuple} from './util/fetch';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {
- acceptResourceRemoval, addNftBasicResource, createCollection, mintNft, removeNftResource, sendNft,
-} from './util/tx';
-
-
-
-
-describe('Integration test: remove nft resource', () => {
- let api: any;
- before(async function() {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- const alice = '//Alice';
- const bob = '//Bob';
- const src = 'test-basic-src';
- const metadata = 'test-basic-metadata';
- const license = 'test-basic-license';
- const thumb = 'test-basic-thumb';
-
- it('deleting a resource directly by the NFT owner', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- await removeNftResource(api, 'removed', alice, collectionIdAlice, nftAlice, resourceId);
- });
-
- it('deleting resources indirectly by the NFT owner', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const parentNftId = await mintNft(api, alice, alice, collectionIdAlice, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, alice, collectionIdAlice, 'child-nft-metadata');
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- childNftId,
- src,
- metadata,
- license,
- thumb,
- );
-
- const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionIdAlice, childNftId, newOwnerNFT);
-
- await removeNftResource(api, 'removed', alice, collectionIdAlice, childNftId, resourceId);
- });
-
- it('deleting a resource by the collection owner', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftBob = await mintNft(
- api,
- alice,
- bob,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'pending',
- collectionIdAlice,
- nftBob,
- src,
- metadata,
- license,
- thumb,
- );
-
- await removeNftResource(api, 'pending', alice, collectionIdAlice, nftBob, resourceId);
- await acceptResourceRemoval(api, bob, collectionIdAlice, nftBob, resourceId);
- });
-
- it('deleting a resource in a nested NFT by the collection owner', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const parentNftId = await mintNft(
- api,
- alice,
- bob,
- collectionIdAlice,
- 'parent-nft-metadata',
- );
- const childNftId = await mintNft(
- api,
- alice,
- bob,
- collectionIdAlice,
- 'child-nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'pending',
- collectionIdAlice,
- childNftId,
- src,
- metadata,
- license,
- thumb,
- );
-
- const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId];
-
- await sendNft(api, 'sent', bob, collectionIdAlice, childNftId, newOwnerNFT);
-
- await removeNftResource(api, 'pending', alice, collectionIdAlice, childNftId, resourceId);
- await acceptResourceRemoval(api, bob, collectionIdAlice, childNftId, resourceId);
- });
-
- it('[negative]: can\'t delete a resource in a non-existing collection', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- const tx = removeNftResource(api, 'removed', alice, 0xFFFFFFFF, nftAlice, resourceId);
- await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); // FIXME: inappropriate error message (NoAvailableNftId)
- });
-
- it('[negative]: only collection owner can delete a resource', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- const tx = removeNftResource(api, 'removed', bob, collectionIdAlice, nftAlice, resourceId);
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('[negative]: cannot delete a resource that does not exist', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const tx = removeNftResource(api, 'removed', alice, collectionIdAlice, nftAlice, 127);
- await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx);
- });
-
- it('[negative]: Cannot accept deleting resource without owner attempt do delete it', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftBob = await mintNft(
- api,
- alice,
- bob,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'pending',
- collectionIdAlice,
- nftBob,
- src,
- metadata,
- license,
- thumb,
- );
-
- const tx = acceptResourceRemoval(api, bob, collectionIdAlice, nftBob, resourceId);
- await expectTxFailure(/rmrkCore\.ResourceNotPending/, tx);
- });
-
- it('[negative]: cannot confirm the deletion of a non-existing resource', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftBob = await mintNft(
- api,
- alice,
- bob,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const tx = acceptResourceRemoval(api, bob, collectionIdAlice, nftBob, 127);
- await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx);
- });
-
- it('[negative]: Non-owner user cannot confirm the deletion of resource', async () => {
- const collectionIdAlice = await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- );
-
- const nftAlice = await mintNft(
- api,
- alice,
- alice,
- collectionIdAlice,
- 'nft-metadata',
- );
-
- const resourceId = await addNftBasicResource(
- api,
- alice,
- 'added',
- collectionIdAlice,
- nftAlice,
- src,
- metadata,
- license,
- thumb,
- );
-
- const tx = acceptResourceRemoval(api, bob, collectionIdAlice, nftAlice, resourceId);
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/rmrkIsolation.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/rmrkIsolation.seqtest.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import {executeTransaction} from '../substrate/substrate-api';
-import {IKeyringPair} from '@polkadot/types/types';
-import {itSub, expect, usingPlaygrounds, Pallets, requirePalletsOrSkip} from '../../util';
-import {UniqueHelper} from '../../util/playgrounds/unique';
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-
-async function createRmrkCollection(helper: UniqueHelper, sender: IKeyringPair): Promise<{uniqueId: number, rmrkId: number}> {
- const result = await helper.executeExtrinsic(sender, 'api.tx.rmrkCore.createCollection', ['metadata', null, 'symbol'], true);
-
- const uniqueId = helper.util.extractCollectionIdFromCreationResult(result);
-
- let rmrkId = null;
- result.result.events.forEach(({event: {data, method, section}}) => {
- if ((section === 'rmrkCore') && (method === 'CollectionCreated')) {
- rmrkId = parseInt(data[1].toString(), 10);
- }
- });
-
- if (rmrkId === null) {
- throw Error('No rmrkCore.CollectionCreated event was found!');
- }
-
- return {
- uniqueId,
- rmrkId,
- };
-}
-
-async function createRmrkNft(helper: UniqueHelper, sender: IKeyringPair, collectionId: number): Promise<number> {
- const result = await helper.executeExtrinsic(
- sender,
- 'api.tx.rmrkCore.mintNft',
- [
- sender.address,
- collectionId,
- sender.address,
- null,
- 'nft-metadata',
- true,
- null,
- ],
- true,
- );
-
- let rmrkNftId = null;
- result.result.events.forEach(({event: {data, method, section}}) => {
- if ((section === 'rmrkCore') && (method === 'NftMinted')) {
- rmrkNftId = parseInt(data[2].toString(), 10);
- }
- });
-
- if (rmrkNftId === null) {
- throw Error('No rmrkCore.NftMinted event was found!');
- }
-
- return rmrkNftId;
-}
-
-describe('RMRK External Integration Test', () => {
- before(async function() {
- await usingPlaygrounds(async (_helper, privateKey) => {
- alice = await privateKey('//Alice');
- });
- });
-
- itSub.ifWithPallets('Creates a new RMRK collection that is mapped to a different ID and is tagged as external', [Pallets.RmrkCore], async ({helper}) => {
- // throw away collection to bump last Unique collection ID to test ID mapping
- await helper.nft.mintCollection(alice, {tokenPrefix: 'unqt'});
-
- const collectionIds = await createRmrkCollection(helper, alice);
-
- expect(collectionIds.rmrkId).to.be.lessThan(collectionIds.uniqueId, 'collection ID mapping');
-
- const collection = (await helper.nft.getCollectionObject(collectionIds.uniqueId).getData())!; // (await getDetailedCollectionInfo(api, collectionIds.uniqueId))!;
- expect(collection.raw.readOnly, 'tagged external').to.be.true;
- });
-});
-
-describe('Negative Integration Test: External Collections, Internal Ops', () => {
- let uniqueCollectionId: number;
- let rmrkCollectionId: number;
- let rmrkNftId: number;
- let normalizedAlice: {Substrate: string};
-
- before(async function() {
- await usingPlaygrounds(async (helper, privateKey) => {
- alice = await privateKey('//Alice');
- bob = await privateKey('//Bob');
- normalizedAlice = {Substrate: helper.address.normalizeSubstrateToChainFormat(alice.address)};
-
- requirePalletsOrSkip(this, helper, [Pallets.RmrkCore]);
-
- const collectionIds = await createRmrkCollection(helper, alice);
- uniqueCollectionId = collectionIds.uniqueId;
- rmrkCollectionId = collectionIds.rmrkId;
-
- rmrkNftId = await createRmrkNft(helper, alice, rmrkCollectionId);
- });
- });
-
- itSub.ifWithPallets('[Negative] Forbids Unique operations with an external collection, handled by dispatch_call', [Pallets.RmrkCore], async ({helper}) => {
- // Collection item creation
-
- await expect(helper.nft.mintToken(alice, {collectionId: uniqueCollectionId, owner: {Substrate: alice.address}}), 'creating item')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- const txCreateMultipleItems = helper.getApi().tx.unique.createMultipleItems(uniqueCollectionId, normalizedAlice, [{NFT: {}}, {NFT: {}}]);
- await expect(executeTransaction(helper.getApi(), alice, txCreateMultipleItems), 'creating multiple')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.mintMultipleTokens(alice, uniqueCollectionId, [{owner: {Substrate: alice.address}}]), 'creating multiple ex')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- // Collection properties
-
- await expect(helper.nft.setProperties(alice, uniqueCollectionId, [{key: 'a', value: '1'}, {key: 'b'}]), 'setting collection properties')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.deleteProperties(alice, uniqueCollectionId, ['a']), 'deleting collection properties')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.setTokenPropertyPermissions(alice, uniqueCollectionId, [{key: 'a', permission: {mutable: true}}]), 'setting property permissions')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- // NFT
-
- await expect(helper.nft.burnToken(alice, uniqueCollectionId, rmrkNftId, 1n), 'burning')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.burnTokenFrom(alice, uniqueCollectionId, rmrkNftId, {Substrate: alice.address}, 1n), 'burning-from')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.transferToken(alice, uniqueCollectionId, rmrkNftId, {Substrate: bob.address}), 'transferring')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.approveToken(alice, uniqueCollectionId, rmrkNftId, {Substrate: bob.address}), 'approving')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.transferTokenFrom(alice, uniqueCollectionId, rmrkNftId, {Substrate: alice.address}, {Substrate: bob.address}), 'transferring-from')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- // NFT properties
-
- await expect(helper.nft.setTokenProperties(alice, uniqueCollectionId, rmrkNftId, [{key: 'a', value: '2'}]), 'setting token properties')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.deleteTokenProperties(alice, uniqueCollectionId, rmrkNftId, ['a']))
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
- });
-
- itSub.ifWithPallets('[Negative] Forbids Unique collection operations with an external collection', [Pallets.RmrkCore], async ({helper}) => {
- await expect(helper.nft.burn(alice, uniqueCollectionId), 'destroying collection')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- // Allow list
-
- await expect(helper.nft.addToAllowList(alice, uniqueCollectionId, {Substrate: bob.address}), 'adding to allow list')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.removeFromAllowList(alice, uniqueCollectionId, {Substrate: bob.address}), 'removing from allowlist')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- // Owner / Admin / Sponsor
-
- await expect(helper.nft.changeOwner(alice, uniqueCollectionId, bob.address), 'changing owner')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.addAdmin(alice, uniqueCollectionId, {Substrate: bob.address}), 'adding admin')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.removeAdmin(alice, uniqueCollectionId, {Substrate: bob.address}), 'removing admin')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.setSponsor(alice, uniqueCollectionId, bob.address), 'setting sponsor')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.confirmSponsorship(alice, uniqueCollectionId), 'confirming sponsor')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.removeSponsor(alice, uniqueCollectionId), 'removing sponsor')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- // Limits / permissions / transfers
-
- const txSetTransfers = helper.getApi().tx.unique.setTransfersEnabledFlag(uniqueCollectionId, true);
- await expect(executeTransaction(helper.getApi(), alice, txSetTransfers), 'setting transfers enabled flag')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.setLimits(alice, uniqueCollectionId, {transfersEnabled: false}), 'setting collection limits')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
-
- await expect(helper.nft.setPermissions(alice, uniqueCollectionId, {access: 'AllowList'}), 'setting collection permissions')
- .to.be.rejectedWith(/common\.CollectionIsExternal/);
- });
-});
-
-describe('Negative Integration Test: Internal Collections, External Ops', () => {
- let collectionId: number;
- let nftId: number;
-
- before(async () => {
- await usingPlaygrounds(async (helper, privateKey) => {
- alice = await privateKey('//Alice');
- bob = await privateKey('//Bob');
-
- const collection = await helper.nft.mintCollection(alice, {tokenPrefix: 'iceo'});
- collectionId = collection.collectionId;
- nftId = (await collection.mintToken(alice)).tokenId;
- });
- });
-
- itSub.ifWithPallets('[Negative] Forbids RMRK operations with the internal collection and NFT (due to the lack of mapping)', [Pallets.RmrkCore], async ({helper}) => {
- const api = helper.getApi();
-
- const txChangeOwner = api.tx.rmrkCore.changeCollectionIssuer(collectionId, bob.address);
- await expect(executeTransaction(api, alice, txChangeOwner), 'changing collection issuer')
- .to.be.rejectedWith(/rmrkCore\.CollectionUnknown/);
-
- const maxBurns = 10;
- const txBurnItem = api.tx.rmrkCore.burnNft(collectionId, nftId, maxBurns);
- await expect(executeTransaction(api, alice, txBurnItem), 'burning NFT').to.be.rejectedWith(/rmrkCore\.CollectionUnknown/);
- });
-});
tests/src/.outdated/rmrk/sendNft.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/sendNft.seqtest.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-import {expect} from 'chai';
-import {getApiConnection} from '../substrate/substrate-api';
-import {createCollection, mintNft, sendNft} from './util/tx';
-import {NftIdTuple} from './util/fetch';
-import {isNftChildOfAnother, expectTxFailure, requirePallets, Pallets} from './util/helpers';
-
-describe('integration test: send NFT', () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- const maxNftId = 0xFFFFFFFF;
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- const createTestCollection = async (issuerUri: string) => {
- return await createCollection(
- api,
- issuerUri,
- 'nft-collection-metadata',
- null,
- 'nft-collection',
- );
- };
-
-
- it('send NFT to another user', async () => {
- const originalOwnerUri = alice;
- const newOwnerUri = bob;
-
- const collectionId = await createTestCollection(alice);
-
- const nftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'nft-metadata');
-
- await sendNft(api, 'sent', originalOwnerUri, collectionId, nftId, newOwnerUri);
- });
-
- it('[negative] unable to send non-existing NFT', async () => {
- const originalOwnerUri = alice;
- const newOwnerUri = bob;
-
- const collectionId = 0;
- const tx = sendNft(api, 'sent', originalOwnerUri, collectionId, maxNftId, newOwnerUri);
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative] unable to send NFT by a not-an-owner', async () => {
- const originalOwnerUri = alice;
- const newOwnerUri = bob;
-
- const collectionId = await createTestCollection(alice);
-
- const nftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'nft-metadata');
-
- const tx = sendNft(api, 'sent', newOwnerUri, collectionId, nftId, newOwnerUri);
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('send NFT to another NFT (same owner)', async () => {
- const originalOwnerUri = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT);
-
- const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.true;
- });
-
- it('[negative] send non-existing NFT to another NFT', async () => {
- const originalOwnerUri = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata');
- const childNftId = maxNftId;
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- const tx = sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
-
- const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.false;
- });
-
- it('send NFT to another NFT (by not-an-owner)', async () => {
- const originalOwnerUri = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const author = alice;
- const attacker = bob;
-
- const parentNftId = await mintNft(api, author, originalOwnerUri, collectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, author, originalOwnerUri, collectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- const tx = sendNft(api, 'sent', attacker, collectionId, childNftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
-
- const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.false;
- });
-
- it('[negative] send NFT to non-existing NFT', async () => {
- const originalOwnerUri = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = maxNftId;
- const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- const tx = sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
-
- const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.false;
- });
-
- it('send NFT to another NFT owned by another user', async () => {
- const ownerAlice = alice;
- const ownerBob = bob;
-
- const aliceCollectionId = await createTestCollection(alice);
- const bobCollectionId = await createTestCollection(bob);
-
- const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId];
-
- await sendNft(api, 'pending', bob, bobCollectionId, childNftId, newOwnerNFT);
- });
-
- it('[negative] unable to send NFT to itself', async () => {
- const nftOwner = alice;
- const collectionId = await createTestCollection(alice);
-
- const nftId = await mintNft(api, alice, nftOwner, collectionId, 'ouroboros-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionId, nftId];
-
- const tx = sendNft(api, 'sent', alice, collectionId, nftId, newOwnerNFT);
-
- await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx);
-
- const isChild = await isNftChildOfAnother(api, collectionId, nftId, newOwnerNFT);
- expect(isChild).to.be.false;
- });
-
- it('[negative] unable to send NFT to child NFT', async () => {
- const originalOwnerUri = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata');
-
- const newOwnerNFT: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT);
-
- const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT);
- expect(isChild).to.be.true;
-
- const descendentOwner: NftIdTuple = [collectionId, childNftId];
- const tx = sendNft(api, 'sent', alice, collectionId, parentNftId, descendentOwner);
-
- await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx);
- const isOuroboros = await isNftChildOfAnother(api, collectionId, parentNftId, descendentOwner);
- expect(isOuroboros).to.be.false;
- });
-
- it('[negative] unable to send NFT to descendent NFT', async () => {
- const originalOwnerUri = alice;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata');
- const grandsonNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'grandson-nft-metadata');
-
- const ownerParentNFT: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', alice, collectionId, childNftId, ownerParentNFT);
-
- const isChild = await isNftChildOfAnother(api, collectionId, childNftId, ownerParentNFT);
- expect(isChild).to.be.true;
-
- const ownerChildNFT: NftIdTuple = [collectionId, childNftId];
- await sendNft(api, 'sent', alice, collectionId, grandsonNftId, ownerChildNFT);
-
- const isGrandson = await isNftChildOfAnother(api, collectionId, grandsonNftId, ownerChildNFT);
- expect(isGrandson).to.be.true;
-
- const ownerGrandsonNFT: NftIdTuple = [collectionId, grandsonNftId];
- const tx = sendNft(api, 'sent', alice, collectionId, parentNftId, ownerGrandsonNFT);
-
- await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx);
- const isOuroboros = await isNftChildOfAnother(api, collectionId, parentNftId, ownerGrandsonNFT);
- expect(isOuroboros).to.be.false;
- });
-
- it('send nested NFT to another user', async () => {
- const originalOwner = alice;
- const newOwner = bob;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, originalOwner, collectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, originalOwner, collectionId, 'child-nft-metadata');
-
- const parentNftTuple: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', originalOwner, collectionId, childNftId, parentNftTuple);
-
- await sendNft(api, 'sent', originalOwner, collectionId, childNftId, newOwner);
- });
-
- it('[negative] send nested NFT to another user (by a not-root-owner)', async () => {
- const originalOwner = alice;
- const newOwner = bob;
-
- const collectionId = await createTestCollection(alice);
-
- const parentNftId = await mintNft(api, alice, originalOwner, collectionId, 'parent-nft-metadata');
- const childNftId = await mintNft(api, alice, originalOwner, collectionId, 'child-nft-metadata');
-
- const parentNftTuple: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', originalOwner, collectionId, childNftId, parentNftTuple);
-
- const tx = sendNft(api, 'sent', newOwner, collectionId, childNftId, newOwner);
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/setCollectionProperty.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/setCollectionProperty.seqtest.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {createCollection, setPropertyCollection} from './util/tx';
-
-describe('integration test: set collection property', () => {
- const alice = '//Alice';
- const bob = '//Bob';
-
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- it('set collection property', async () => {
- await createCollection(
- api,
- alice,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- await setPropertyCollection(api, alice, collectionId, 'test_key', '42');
- await setPropertyCollection(api, alice, collectionId, 'test_key', '10');
- await setPropertyCollection(
- api,
- alice,
- collectionId,
- 'second_test_key',
- '111',
- );
- });
- });
-
- it('[negative] set non-existing collection property', async () => {
- const tx = setPropertyCollection(
- api,
- alice,
- 9999,
- 'test_key',
- '42',
- );
- await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx);
- });
-
- it('[negative] set property not an owner NFT collection issuer', async () => {
- await createCollection(
- api,
- bob,
- 'test-metadata',
- null,
- 'test-symbol',
- ).then(async (collectionId) => {
- const tx = setPropertyCollection(
- api,
- alice,
- collectionId,
- 'test_key',
- '42',
- );
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/setEquippableList.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/setEquippableList.seqtest.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {createCollection, createBase, setEquippableList} from './util/tx';
-
-describe("integration test: set slot's Equippable List", () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- it("set Base's slot Equippable List", async () => {
- const collectionIds = [
- await createCollection(
- api,
- alice,
- 'equiplist-collection-metadata',
- null,
- 'equiplist-0',
- ),
- await createCollection(
- api,
- alice,
- 'equiplist-collection-metadata',
- null,
- 'equiplist-1',
- ),
- ];
-
- const slotId = 202;
-
- const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [
- {
- 'SlotPart': {
- id: slotId,
- equippable: 'All',
- z: 1,
- src: 'some-fallback-slot-url',
- },
- },
- ]);
-
- await setEquippableList(api, alice, baseId, slotId, 'All');
- await setEquippableList(api, alice, baseId, slotId, 'Empty');
- await setEquippableList(api, alice, baseId, slotId, {'Custom': collectionIds});
- });
-
- it('[negative] unable to set equippable list of a slot of non-existing base', async () => {
- const maxBaseId = 0xFFFFFFFF;
- const slotId = 0;
-
- const tx = setEquippableList(api, alice, maxBaseId, slotId, 'All');
- await expectTxFailure(/rmrkEquip\.BaseDoesntExist/, tx);
- });
-
- it('[negative] unable to set equippable list by a not-an-owner', async () => {
- const slotId = 42;
-
- const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [
- {
- 'SlotPart': {
- id: slotId,
- equippable: 'All',
- z: 1,
- src: 'some-fallback-slot-url',
- },
- },
- ]);
-
- const tx = setEquippableList(api, bob, baseId, slotId, 'All');
- await expectTxFailure(/rmrkEquip\.PermissionError/, tx);
- });
-
- it('[negative] unable to set equippable list to a fixed part', async () => {
- const fixedPartId = 42;
-
- const baseId = await createBase(api, alice, 'fixedpart-base-type', 'fixedpart', [
- {
- 'FixedPart': {
- id: fixedPartId,
- z: 0,
- src: 'fixed-part-url',
- },
- },
- ]);
-
- const tx = setEquippableList(api, alice, baseId, fixedPartId, 'All');
- await expectTxFailure(/rmrkEquip\.NoEquippableOnFixedPart/, tx);
- });
-
- it('[negative] unable to set equippable list to non-existing slot', async () => {
- const slotId = 777;
- const maxSlotId = 0xFFFFFFFF;
-
- const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [
- {
- 'SlotPart': {
- id: slotId,
- equippable: 'All',
- z: 1,
- src: 'some-fallback-slot-url',
- },
- },
- ]);
-
- const tx = setEquippableList(api, alice, baseId, maxSlotId, 'All');
- await expectTxFailure(/rmrkEquip\.PartDoesntExist/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/setNftProperty.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/setNftProperty.seqtest.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {NftIdTuple} from './util/fetch';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {createCollection, mintNft, sendNft, setNftProperty} from './util/tx';
-
-describe('integration test: set NFT property', () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- const createTestCollection = async (issuerUri: string) => {
- return await createCollection(
- api,
- issuerUri,
- 'setprop-nft-collection-metadata',
- null,
- 'setprop',
- );
- };
-
- it('set NFT property', async () => {
- const ownerAlice = alice;
-
- const collectionId = await createTestCollection(alice);
- const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-nft');
-
- await setNftProperty(api, alice, collectionId, nftId, 'test-key', 'test-key-value');
- await setNftProperty(api, alice, collectionId, nftId, 'test-key', 'updated-key-value');
- await setNftProperty(api, alice, collectionId, nftId, 'second-test-key', 'second-test-key-value');
- });
-
- it('[negative] unable to set a property of non-existing NFT', async () => {
- const collectionId = 0;
- const maxNftId = 0xFFFFFFFF;
-
- const tx = setNftProperty(api, alice, collectionId, maxNftId, 'test-key', 'test-value');
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- it('[negative] unable to set a property by not-an-owner', async () => {
- const ownerAlice = alice;
-
- const collectionId = await createTestCollection(alice);
- const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-nft');
-
- const tx = setNftProperty(api, bob, collectionId, nftId, 'test-key', 'test-key-value');
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('set a property to nested NFT', async () => {
- const ownerAlice = alice;
-
- const collectionId = await createTestCollection(alice);
- const parentNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-parent-nft');
- const childNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-child-nft');
-
- const ownerNft: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', ownerAlice, collectionId, childNftId, ownerNft);
-
- await setNftProperty(api, alice, collectionId, childNftId, 'test-key', 'test-key-value');
- });
-
- it('[negative] set a property to nested NFT (by not-root-owner)', async () => {
- const ownerAlice = alice;
-
- const collectionId = await createTestCollection(alice);
- const parentNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-parent-nft');
- const childNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-child-nft');
-
- const ownerNft: NftIdTuple = [collectionId, parentNftId];
-
- await sendNft(api, 'sent', ownerAlice, collectionId, childNftId, ownerNft);
-
- const tx = setNftProperty(api, bob, collectionId, childNftId, 'test-key', 'test-key-value');
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/setResourcePriorities.seqtest.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/setResourcePriorities.seqtest.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import {getApiConnection} from '../substrate/substrate-api';
-import {expectTxFailure, requirePallets, Pallets} from './util/helpers';
-import {mintNft, createCollection, setResourcePriorities} from './util/tx';
-
-describe('integration test: set NFT resource priorities', () => {
- let api: any;
- before(async function () {
- api = await getApiConnection();
- await requirePallets(this, [Pallets.RmrkCore]);
- });
-
- const alice = '//Alice';
- const bob = '//Bob';
-
- const createTestCollection = (issuerUri: string) => {
- return createCollection(
- api,
- issuerUri,
- 'resprio-collection-metadata',
- null,
- 'resprio',
- );
- };
-
- it('set NFT resource priorities', async () => {
- const owner = alice;
-
- const collectionId = await createTestCollection(alice);
- const nftId = await mintNft(api, alice, owner, collectionId, 'resprio-nft-metadata');
-
- await setResourcePriorities(api, alice, collectionId, nftId, [10, 42]);
- });
-
- it('[negative] set NFT resource priorities by a not-an-owner', async () => {
- const owner = alice;
- const attacker = bob;
-
- const collectionId = await createTestCollection(alice);
- const nftId = await mintNft(api, alice, owner, collectionId, 'resprio-nft-metadata');
-
- const tx = setResourcePriorities(api, attacker, collectionId, nftId, [10, 42]);
-
- await expectTxFailure(/rmrkCore\.NoPermission/, tx);
- });
-
- it('[negative] set NFT resource priorities to non-existing NFT', async () => {
- const collectionId = 0;
- const maxNftId = 0xFFFFFFFF;
-
- const tx = setResourcePriorities(api, alice, collectionId, maxNftId, [10, 42]);
-
- await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx);
- });
-
- after(async() => { await api.disconnect(); });
-});
tests/src/.outdated/rmrk/util/fetch.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/util/fetch.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-import {ApiPromise} from '@polkadot/api';
-import type {Option} from '@polkadot/types-codec';
-import type {
- RmrkTraitsCollectionCollectionInfo as Collection,
- RmrkTraitsNftNftInfo as Nft,
- RmrkTraitsResourceResourceInfo as Resource,
- RmrkTraitsBaseBaseInfo as Base,
- RmrkTraitsPartPartType as PartType,
- RmrkTraitsNftNftChild as NftChild,
- RmrkTraitsTheme as Theme,
- RmrkTraitsPropertyPropertyInfo as Property,
-} from '../../../interfaces/default/types'; // '@polkadot/types/lookup';
-import '../../../interfaces/augment-api';
-import '../../../interfaces/augment-api-query';
-import privateKey from '../../substrate/privateKey';
-
-export type NftIdTuple = [number, number];
-
-export async function getCollectionsCount(api: ApiPromise): Promise<number> {
- return (await api.rpc.rmrk.lastCollectionIdx()).toNumber();
-}
-
-export function getCollection(api: ApiPromise, id: number): Promise<Option<Collection>> {
- return api.rpc.rmrk.collectionById(id);
-}
-
-export async function getOwnedNfts(
- api: ApiPromise,
- ownerUri: string,
- collectionId: number,
-): Promise<number[]> {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const owner = privateKey(ownerUri, Number(ss58Format));
-
- return (await api.rpc.rmrk.accountTokens(owner.address, collectionId))
- .map((value) => value.toNumber());
-}
-
-export function getNft(api: ApiPromise, collectionId: number, nftId: number): Promise<Option<Nft>> {
- return api.rpc.rmrk.nftById(collectionId, nftId);
-}
-
-export async function getCollectionProperties(api: ApiPromise, collectionId: number): Promise<Property[]> {
- return (await api.rpc.rmrk.collectionProperties(collectionId)).toArray();
-}
-
-export async function getNftProperties(api: ApiPromise, collectionId: number, nftId: number): Promise<Property[]> {
- return (await api.rpc.rmrk.nftProperties(collectionId, nftId)).toArray();
-}
-
-export async function getChildren(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
-): Promise<NftChild[]> {
- return (await api.rpc.rmrk.nftChildren(collectionId, nftId)).toArray();
-}
-
-export function getBase(api: ApiPromise, baseId: number): Promise<Option<Base>> {
- return api.rpc.rmrk.base(baseId);
-}
-
-export async function getParts(api: ApiPromise, baseId: number): Promise<PartType[]> {
- return (await api.rpc.rmrk.baseParts(baseId)).toArray();
-}
-
-export async function getEquippableList(
- api: ApiPromise,
- baseId: number,
- slotId: number,
-): Promise<'All' | 'Empty' | { 'Custom': number[] } | null> {
- const parts = await getParts(api, baseId);
-
- const part = parts.find((part) => {
- if (part.isSlotPart) {
- return part.asSlotPart.id.toNumber() === slotId;
- } else {
- return false;
- }
- });
-
- if (part) {
- const slot = part.asSlotPart;
- if (slot.equippable.isCustom) {
- return {
- 'Custom': slot.equippable.asCustom
- .toArray()
- .map((collectionId) => collectionId.toNumber()),
- };
- } else if (slot.equippable.isAll) {
- return 'All';
- } else {
- return 'Empty';
- }
- } else {
- return null;
- }
-}
-
-export async function getResourcePriority(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
- resourceId: number,
-): Promise<number> {
- return (await api.rpc.rmrk.nftResourcePriority(collectionId, nftId, resourceId))
- .unwrap().toNumber();
-}
-
-export async function getThemeNames(api: ApiPromise, baseId: number): Promise<string[]> {
- return (await api.rpc.rmrk.themeNames(baseId))
- .map((name) => name.toUtf8());
-}
-
-export function getTheme(
- api: ApiPromise,
- baseId: number,
- themeName: string,
- keys: string[] | null = null,
-): Promise<Option<Theme>> {
- return api.rpc.rmrk.themes(baseId, themeName, keys);
-}
-
-export async function getResources(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
-): Promise<Resource[]> {
- return (await api.rpc.rmrk.nftResources(collectionId, nftId)).toArray();
-}
tests/src/.outdated/rmrk/util/helpers.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/util/helpers.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-import {ApiPromise} from '@polkadot/api';
-import {
- RmrkTraitsNftAccountIdOrCollectionNftTuple as NftOwner,
- RmrkTraitsPropertyPropertyInfo as Property,
- RmrkTraitsResourceResourceInfo as ResourceInfo,
-} from '@polkadot/types/lookup';
-import type {EventRecord} from '@polkadot/types/interfaces';
-import type {GenericEventData} from '@polkadot/types';
-import privateKey from '../../substrate/privateKey';
-import {NftIdTuple, getChildren, getOwnedNfts, getCollectionProperties, getNftProperties, getResources} from './fetch';
-import chaiAsPromised from 'chai-as-promised';
-import chai from 'chai';
-import {getApiConnection} from '../../substrate/substrate-api';
-import {Context} from 'mocha';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-interface TxResult<T> {
- success: boolean;
- successData: T | null;
-}
-
-export enum Pallets {
- Inflation = 'inflation',
- RmrkCore = 'rmrkcore',
- RmrkEquip = 'rmrkequip',
- ReFungible = 'refungible',
- Fungible = 'fungible',
- NFT = 'nonfungible',
- Scheduler = 'scheduler',
- AppPromotion = 'apppromotion',
-}
-
-let modulesNames: any;
-export function getModuleNames(api: ApiPromise): string[] {
- if (typeof modulesNames === 'undefined')
- modulesNames = api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());
- return modulesNames;
-}
-
-export async function missingRequiredPallets(requiredPallets: string[]): Promise<string[]> {
- const api = await getApiConnection();
- const pallets = getModuleNames(api);
- await api.disconnect();
-
- return requiredPallets.filter(p => !pallets.includes(p));
-}
-
-export async function requirePallets(mocha: Context, requiredPallets: string[]) {
- const missingPallets = await missingRequiredPallets(requiredPallets);
-
- if (missingPallets.length > 0) {
- const skippingTestMsg = `\tSkipping test "${mocha.test?.title}".`;
- const missingPalletsMsg = `\tThe following pallets are missing:\n\t- ${missingPallets.join('\n\t- ')}`;
- const skipMsg = `${skippingTestMsg}\n${missingPalletsMsg}`;
-
- console.error('\x1b[38:5:208m%s\x1b[0m', skipMsg);
-
- mocha.skip();
- }
-}
-
-export function makeNftOwner(api: ApiPromise, owner: string | NftIdTuple): NftOwner {
- const isNftSending = (typeof owner !== 'string');
-
- if (isNftSending) {
- return api.createType('RmrkTraitsNftAccountIdOrCollectionNftTuple', {
- 'CollectionAndNftTuple': owner,
- });
- } else {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- return api.createType('RmrkTraitsNftAccountIdOrCollectionNftTuple', {
- AccountId: privateKey(owner, Number(ss58Format)).address,
- });
- }
-}
-
-export async function isNftOwnedBy(
- api: ApiPromise,
- owner: string | NftIdTuple,
- collectionId: number,
- nftId: number,
-): Promise<boolean> {
- if (typeof owner === 'string') {
- return (await getOwnedNfts(api, owner, collectionId))
- .find(ownedNftId => {
- return ownedNftId === nftId;
- }) !== undefined;
- } else {
- return (await getChildren(api, owner[0], owner[1]))
- .find(child => {
- return collectionId === child.collectionId.toNumber()
- && nftId === child.nftId.toNumber();
- }) !== undefined;
- }
-}
-
-export function isPropertyExists(
- key: string,
- value: string,
- props: Property[],
-): boolean {
- let isPropFound = false;
- for (let i = 0; i < props.length && !isPropFound; i++) {
- const fetchedProp = props[i];
-
- isPropFound = fetchedProp.key.eq(key)
- && fetchedProp.value.eq(value);
- }
-
- return isPropFound;
-}
-
-export async function isCollectionPropertyExists(
- api: ApiPromise,
- collectionId: number,
- key: string,
- value: string,
-): Promise<boolean> {
- const fetchedProps = await getCollectionProperties(api, collectionId);
- return isPropertyExists(key, value, fetchedProps);
-}
-
-export async function isNftPropertyExists(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
- key: string,
- value: string,
-): Promise<boolean> {
- const fetchedProps = await getNftProperties(api, collectionId, nftId);
- return isPropertyExists(key, value, fetchedProps);
-}
-
-export async function isNftChildOfAnother(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
- parentNft: NftIdTuple,
-): Promise<boolean> {
- return (await getChildren(api, parentNft[0], parentNft[1]))
- .find((childNft) => {
- return childNft.collectionId.toNumber() === collectionId
- && childNft.nftId.toNumber() === nftId;
- }) !== undefined;
-}
-
-export function isTxResultSuccess(events: EventRecord[]): boolean {
- let success = false;
-
- events.forEach(({event: {method}}) => {
- if (method == 'ExtrinsicSuccess') {
- success = true;
- }
- });
-
- return success;
-}
-
-export async function expectTxFailure(expectedError: RegExp, promise: Promise<any>) {
- await expect(promise).to.be.rejectedWith(expectedError);
-}
-
-export function extractTxResult<T>(
- events: EventRecord[],
- expectSection: string,
- expectMethod: string,
- extractAction: (data: any) => T,
-): TxResult<T> {
- let success = false;
- let successData = null;
- events.forEach(({event: {data, method, section}}) => {
- if (method == 'ExtrinsicSuccess') {
- success = true;
- } else if ((expectSection == section) && (expectMethod == method)) {
- successData = extractAction(data);
- }
- });
- const result: TxResult<T> = {
- success,
- successData,
- };
- return result;
-}
-
-export function extractRmrkCoreTxResult<T>(
- events: EventRecord[],
- expectMethod: string,
- extractAction: (data: GenericEventData) => T,
-): TxResult<T> {
- return extractTxResult(events, 'rmrkCore', expectMethod, extractAction);
-}
-
-export function extractRmrkEquipTxResult<T>(
- events: EventRecord[],
- expectMethod: string,
- extractAction: (data: GenericEventData) => T,
-): TxResult<T> {
- return extractTxResult(events, 'rmrkEquip', expectMethod, extractAction);
-}
-
-export async function findResourceById(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
- resourceId: number,
-): Promise<ResourceInfo> {
- const resources = await getResources(api, collectionId, nftId);
-
- let resource = null;
-
- for (let i = 0; i < resources.length; i++) {
- const res = resources[i];
-
- if (res.id.eq(resourceId)) {
- resource = res;
- break;
- }
- }
-
- return resource!;
-}
-
-export async function getResourceById(
- api: ApiPromise,
- collectionId: number,
- nftId: number,
- resourceId: number,
-): Promise<ResourceInfo> {
- const resource = await findResourceById(
- api,
- collectionId,
- nftId,
- resourceId,
- );
-
- expect(resource !== null, 'Error: resource was not found').to.be.true;
-
- return resource!;
-}
-
-export function checkResourceStatus(
- resource: ResourceInfo,
- expectedStatus: 'pending' | 'added',
-) {
- expect(resource.pending.isTrue, `Error: added resource should be ${expectedStatus}`)
- .to.be.equal(expectedStatus === 'pending');
-}
tests/src/.outdated/rmrk/util/tx.tsdiffbeforeafterboth--- a/tests/src/.outdated/rmrk/util/tx.ts
+++ /dev/null
@@ -1,1132 +0,0 @@
-import {ApiPromise} from '@polkadot/api';
-import {Bytes, Option, u32, Vec} from '@polkadot/types-codec';
-import {
- RmrkTraitsNftAccountIdOrCollectionNftTuple as NftOwner, RmrkTraitsPartEquippableList as EquippableList,
- RmrkTraitsPartPartType as PartType, RmrkTraitsResourceBasicResource as BasicResource,
- RmrkTraitsResourceComposableResource as ComposableResource, RmrkTraitsResourceResourceInfo as ResourceInfo, RmrkTraitsResourceSlotResource as SlotResource, RmrkTraitsTheme as Theme,
-} from '@polkadot/types/lookup';
-import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import '../../../interfaces/augment-api';
-import privateKey from '../../substrate/privateKey';
-import {executeTransaction} from '../../substrate/substrate-api';
-import {
- getBase,
- getCollection,
- getCollectionsCount,
- getEquippableList,
- getNft,
- getParts,
- getResources,
- getResourcePriority,
- getTheme,
- NftIdTuple,
-} from './fetch';
-import {
- extractRmrkCoreTxResult,
- extractRmrkEquipTxResult, isCollectionPropertyExists, isNftOwnedBy, isNftPropertyExists, isTxResultSuccess, makeNftOwner,
- findResourceById, getResourceById, checkResourceStatus,
-} from './helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-export async function createCollection(
- api: ApiPromise,
- issuerUri: string,
- metadata: string,
- max: number | null,
- symbol: string,
-): Promise<number> {
- let collectionId = 0;
-
- const oldCollectionCount = await getCollectionsCount(api);
- const maxOptional = max ? max.toString() : null;
- const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const tx = api.tx.rmrkCore.createCollection(metadata, maxOptional, symbol);
- const events = await executeTransaction(api, issuer, tx);
-
- const collectionResult = extractRmrkCoreTxResult(events, 'CollectionCreated', (data) => {
- return parseInt(data[1].toString(), 10);
- });
- expect(collectionResult.success, 'Error: unable to create a collection').to.be.true;
-
- collectionId = collectionResult.successData!;
-
- const newCollectionCount = await getCollectionsCount(api);
- const collectionOption = await getCollection(api, collectionId);
-
- expect(newCollectionCount).to.be.equal(oldCollectionCount + 1, 'Error: NFT collection count should increase');
- expect(collectionOption.isSome, 'Error: unable to fetch created NFT collection').to.be.true;
-
- const collection = collectionOption.unwrap();
-
- expect(collection.metadata.toUtf8()).to.be.equal(metadata, 'Error: Invalid NFT collection metadata');
- expect(collection.max.isSome).to.be.equal(max !== null, 'Error: Invalid NFT collection max');
-
- if (collection.max.isSome) {
- expect(collection.max.unwrap().toNumber()).to.be.equal(max, 'Error: Invalid NFT collection max');
- }
- expect(collection.symbol.toUtf8()).to.be.equal(symbol, "Error: Invalid NFT collection's symbol");
- expect(collection.nftsCount.toNumber()).to.be.equal(0, "Error: NFT collection shoudn't have any tokens");
- expect(collection.issuer.toString()).to.be.equal(issuer.address, 'Error: Invalid NFT collection issuer');
-
- return collectionId;
-}
-
-export async function changeIssuer(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- newIssuer: string,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const alice = privateKey(issuerUri, Number(ss58Format));
- const bob = privateKey(newIssuer, Number(ss58Format));
-
- // This is only needed when RMRK uses `uniques` pallet by Parity
- // let tx = api.tx.uniques.setAcceptOwnership(
- // api.createType('Option<u32>', collectionId)
- // );
- // let events = await executeTransaction(api, bob, tx);
- // expect(isTxResultSuccess(events), 'Error: Unable to accept ownership').to.be.true;
-
- const tx = api.tx.rmrkCore.changeCollectionIssuer(collectionId, bob.address);
- const events = await executeTransaction(api, alice, tx);
- const changeIssuerResult = extractRmrkCoreTxResult(events, 'IssuerChanged', (data) => {
- return parseInt(data[2].toString(), 10);
- });
- expect(changeIssuerResult.success, 'Error: Unable to change NFT collection issuer').to.be.true;
- expect(changeIssuerResult.successData!, 'Error: Invalid collection id after changing the issuer')
- .to.be.eq(collectionId);
-
- await getCollection(api, collectionId).then((collectionOption) => {
- const collection = collectionOption.unwrap();
- expect(collection.issuer.toString())
- .to.be.deep.eq(bob.address, 'Error: Invalid NFT collection issuer');
- });
-}
-
-export async function deleteCollection(
- api: ApiPromise,
- issuerUri: string,
- collectionId: string,
-): Promise<number> {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const tx = api.tx.rmrkCore.destroyCollection(collectionId);
- const events = await executeTransaction(api, issuer, tx);
-
- const collectionTxResult = extractRmrkCoreTxResult(
- events,
- 'CollectionDestroy',
- (data) => {
- return parseInt(data[1].toString(), 10);
- },
- );
- expect(collectionTxResult.success, 'Error: Unable to delete NFT collection').to.be.true;
-
- const collection = await getCollection(
- api,
- parseInt(collectionId, 10),
- );
- expect(collection.isEmpty, 'Error: NFT collection should be deleted').to.be.true;
-
- return 0;
-}
-
-export async function negativeDeleteCollection(
- api: ApiPromise,
- issuerUri: string,
- collectionId: string,
-): Promise<number> {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const tx = api.tx.rmrkCore.destroyCollection(collectionId);
- await expect(executeTransaction(api, issuer, tx)).to.be.rejected;
-
- return 0;
-}
-
-export async function setNftProperty(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
- key: string,
- value: string,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const nftIdOpt = api.createType('Option<u32>', nftId);
- const tx = api.tx.rmrkCore.setProperty(
- collectionId,
- nftIdOpt,
- key,
- value,
- );
- const events = await executeTransaction(api, issuer, tx);
-
- const propResult = extractRmrkCoreTxResult(events, 'PropertySet', (data) => {
- return {
- collectionId: parseInt(data[0].toString(), 10),
- nftId: data[1] as Option<u32>,
- key: data[2] as Bytes,
- value: data[3] as Bytes,
- };
- });
-
- expect(propResult.success, 'Error: Unable to set NFT property').to.be.true;
- const eventData = propResult.successData!;
- const eventDescription = 'from set NFT property event';
-
- expect(eventData.collectionId, 'Error: Invalid collection ID ' + eventDescription)
- .to.be.equal(collectionId);
-
- expect(eventData.nftId.eq(nftIdOpt), 'Error: Invalid NFT ID ' + eventDescription)
- .to.be.true;
-
- expect(eventData.key.eq(key), 'Error: Invalid property key ' + eventDescription)
- .to.be.true;
-
- expect(eventData.value.eq(value), 'Error: Invalid property value ' + eventDescription)
- .to.be.true;
-
- expect(
- await isNftPropertyExists(api, collectionId, nftId, key, value),
- 'Error: NFT property is not found',
- ).to.be.true;
-}
-
-export async function mintNft(
- api: ApiPromise,
- issuerUri: string,
- ownerUri: string | null,
- collectionId: number,
- metadata: string,
- recipientUri: string | null = null,
- royalty: number | null = null,
- transferable = true,
- resources: {basic?: any, composable?: any, slot?: any}[] | null = null,
-): Promise<number> {
- let nftId = 0;
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const owner = ownerUri ? privateKey(ownerUri, Number(ss58Format)).address : null;
- const recipient = recipientUri ? privateKey(recipientUri, Number(ss58Format)).address : null;
- const royaltyOptional = royalty ? royalty.toString() : null;
-
- const actualOwnerUri = ownerUri ? ownerUri : issuerUri;
- const actualOwnerAddress = ownerUri ? owner : issuer.address;
-
- const collectionOpt = await getCollection(api, collectionId);
-
- const tx = api.tx.rmrkCore.mintNft(
- owner,
- collectionId,
- recipient,
- royaltyOptional,
- metadata,
- transferable,
- resources as any,
- );
-
- const events = await executeTransaction(api, issuer, tx);
- const nftResult = extractRmrkCoreTxResult(events, 'NftMinted', (data) => {
- return parseInt(data[2].toString(), 10);
- });
-
- expect(nftResult.success, 'Error: Unable to mint NFT').to.be.true;
-
- const newCollectionNftsCount = (await getCollection(api, collectionId))
- .unwrap()
- .nftsCount
- .toNumber();
-
- const oldCollectionNftsCount = collectionOpt
- .unwrap()
- .nftsCount.toNumber();
-
- expect(newCollectionNftsCount, 'Error: NFTs count should increase')
- .to.be.equal(oldCollectionNftsCount + 1);
-
- nftId = nftResult.successData!;
-
- const nftOption = await getNft(api, collectionId, nftId);
-
- expect(nftOption.isSome, 'Error: Unable to fetch created NFT').to.be.true;
-
- const nft = nftOption.unwrap();
-
- expect(nft.owner.isAccountId, 'Error: NFT owner should be some user').to.be.true;
- expect(nft.owner.asAccountId.toString()).to.be.equal(actualOwnerAddress, 'Error: Invalid NFT owner');
-
- const isOwnedInUniques = await isNftOwnedBy(api, actualOwnerUri, collectionId, nftId);
- expect(isOwnedInUniques, `Error: created NFT is not actually owned by ${ownerUri}`)
- .to.be.true;
-
- if (recipient === null && royalty === null) {
- expect(nft.royalty.isNone, 'Error: Invalid NFT recipient')
- .to.be.true;
- } else {
- expect(nft.royalty.isSome, 'Error: NFT royalty not found')
- .to.be.true;
-
- const nftRoyalty = nft.royalty.unwrap();
- expect(nftRoyalty.recipient.eq(recipient), 'Error: Invalid NFT recipient')
- .to.be.true;
-
- expect(nftRoyalty.amount.eq(royalty), 'Error: Invalid NFT royalty')
- .to.be.true;
- }
-
- expect(nft.metadata.toUtf8()).to.be.equal(metadata, 'Error: Invalid NFT metadata');
-
- const nftResources = await getResources(api, collectionId, nftId);
- if (resources == null) {
- expect(nftResources, 'Error: Invalid NFT resources').to.be.empty;
- } else {
- expect(nftResources.length).to.be.equal(resources.length);
-
- for (let i = 0; i < resources.length; i++) {
- let successFindingResource = false;
- const resource = resources[i];
- // try to find the matching resource from the query
- for (let j = 0; j < nftResources.length && !successFindingResource; j++) {
- const nftResourceData = nftResources[j].toHuman();
- expect(
- Object.prototype.hasOwnProperty.call(nftResourceData, 'resource'),
- `Error: Corrupted resource data on resource #${i}`,
- ).to.be.true;
- const nftResource = nftResourceData.resource!;
- type NftResourceKey = keyof typeof nftResource;
-
- let typedResource = null;
- let typedNftResource = null;
-
- if (resource.basic && Object.prototype.hasOwnProperty.call(nftResource, 'Basic')) {
- typedResource = resource.basic!;
- typedNftResource = nftResource['Basic' as NftResourceKey]!;
- } else if (resource.composable && Object.prototype.hasOwnProperty.call(nftResource, 'Composable')) {
- typedResource = resource.composable!;
- typedNftResource = nftResource['Composable' as NftResourceKey]! as any;
- if (typedResource.parts != undefined && typedResource.parts.toString() != typedNftResource.parts.toString()
- || typedResource.base != typedNftResource.base && typedResource.base != undefined) {
- continue;
- }
- } else if (resource.slot && Object.prototype.hasOwnProperty.call(nftResource, 'Slot')) {
- typedResource = resource.slot!;
- typedNftResource = nftResource['Slot' as NftResourceKey]! as any;
- if (typedResource.slot != typedNftResource.slot && typedResource.slot != undefined
- || typedResource.base != typedNftResource.base && typedResource.base != undefined) {
- continue;
- }
- } else {
- continue;
- }
-
- if (typedResource.src != typedNftResource.src
- || typedResource.metadata != typedNftResource.metadata
- || typedResource.thumb != typedNftResource.thumb
- || typedResource.license != typedNftResource.license
- ) {
- continue;
- }
-
- // do final checks since this is now established to be the resource we seek
- expect(nftResourceData.pending, `Error: Resource #${i} is pending`).to.be.false;
- expect(nftResourceData.pendingRemoval, `Error: Resource #${i} is pending removal`).to.be.false;
-
- // remove the matching resource from the resources we check
- nftResources.splice(j, 1);
- successFindingResource = true;
- }
-
- expect(successFindingResource, `Error: Couldn't find resource #${i}'s counterpart among the returned`).to.be.true;
- }
- }
-
- return nftId;
-}
-
-export async function sendNft(
- api: ApiPromise,
- expectedStatus: 'pending' | 'sent',
- originalOwnerUri: string,
- collectionId: number,
- nftId: number,
- newOwner: string | NftIdTuple,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const originalOwner = privateKey(originalOwnerUri, Number(ss58Format));
- const newOwnerObj = makeNftOwner(api, newOwner);
-
- const nftBeforeSendingOpt = await getNft(api, collectionId, nftId);
-
- const tx = api.tx.rmrkCore.send(collectionId, nftId, newOwnerObj);
- const events = await executeTransaction(api, originalOwner, tx);
-
- const sendResult = extractRmrkCoreTxResult(events, 'NFTSent', (data) => {
- return {
- dstOwner: data[1] as NftOwner,
- collectionId: parseInt(data[2].toString(), 10),
- nftId: parseInt(data[3].toString(), 10),
- };
- });
-
- expect(sendResult.success, 'Error: Unable to send NFT').to.be.true;
- const sendData = sendResult.successData!;
-
- expect(sendData.dstOwner.eq(newOwnerObj), 'Error: Invalid target user (from event data)')
- .to.be.true;
-
- expect(sendData.collectionId)
- .to.be.equal(collectionId, 'Error: Invalid collection ID (from event data)');
-
- expect(sendData.nftId).to.be.equal(nftId, 'Error: Invalid NFT ID (from event data)');
-
- expect(nftBeforeSendingOpt.isSome, 'Error: Unable to fetch NFT before sending').to.be.true;
-
- const nftBeforeSending = nftBeforeSendingOpt.unwrap();
-
- const nftAfterSendingOpt = await getNft(api, collectionId, nftId);
-
- expect(nftAfterSendingOpt.isSome, 'Error: Unable to fetch NFT after sending').to.be.true;
-
- const nftAfterSending = nftAfterSendingOpt.unwrap();
-
- const isOwnedByNewOwner = await isNftOwnedBy(api, newOwner, collectionId, nftId);
- const isPending = expectedStatus === 'pending';
-
- expect(
- isOwnedByNewOwner,
- `Error: The NFT should be owned by ${newOwner.toString()}`,
- ).to.be.true;
-
- expect(nftAfterSending.royalty.eq(nftBeforeSending.royalty), 'Error: Invalid NFT royalty after sending')
- .to.be.true;
-
- expect(nftAfterSending.metadata.eq(nftBeforeSending.metadata), 'Error: Invalid NFT metadata after sending')
- .to.be.true;
-
- expect(nftAfterSending.equipped.eq(nftBeforeSending.equipped), 'Error: Invalid NFT equipped status after sending')
- .to.be.true;
-
- expect(nftAfterSending.pending.eq(isPending), 'Error: Invalid NFT pending state')
- .to.be.true;
-}
-
-export async function acceptNft(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
- newOwner: string | [number, number],
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const newOwnerObj = makeNftOwner(api, newOwner);
-
- const nftBeforeOpt = await getNft(api, collectionId, nftId);
-
- const tx = api.tx.rmrkCore.acceptNft(collectionId, nftId, newOwnerObj);
- const events = await executeTransaction(api, issuer, tx);
-
- const acceptResult = extractRmrkCoreTxResult(events, 'NFTAccepted', (data) => {
- return {
- recipient: data[1] as NftOwner,
- collectionId: parseInt(data[2].toString(), 10),
- nftId: parseInt(data[3].toString(), 10),
- };
- });
-
- expect(acceptResult.success, 'Error: Unable to accept NFT').to.be.true;
- const acceptData = acceptResult.successData!;
-
- expect(acceptData.recipient.eq(newOwnerObj), 'Error: Invalid NFT recipient (from event data)')
- .to.be.true;
-
- expect(acceptData.collectionId)
- .to.be.equal(collectionId, 'Error: Invalid collection ID (from event data)');
-
- expect(acceptData.nftId)
- .to.be.equal(nftId, 'Error: Invalid NFT ID (from event data)');
-
- const nftBefore = nftBeforeOpt.unwrap();
-
- const isPendingBeforeAccept = nftBefore.pending.isTrue;
-
- const nftAfter = (await getNft(api, collectionId, nftId)).unwrap();
- const isPendingAfterAccept = nftAfter.pending.isTrue;
-
- expect(isPendingBeforeAccept, 'Error: NFT should be pending to be accepted')
- .to.be.true;
-
- expect(isPendingAfterAccept, 'Error: NFT should NOT be pending after accept')
- .to.be.false;
-
- const isOwnedInUniques = await isNftOwnedBy(api, newOwner, collectionId, nftId);
- expect(isOwnedInUniques, `Error: created NFT is not actually owned by ${newOwner.toString()}`)
- .to.be.true;
-}
-
-export async function rejectNft(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const nftBeforeOpt = await getNft(api, collectionId, nftId);
-
- const tx = api.tx.rmrkCore.rejectNft(collectionId, nftId);
- const events = await executeTransaction(api, issuer, tx);
- const rejectResult = extractRmrkCoreTxResult(events, 'NFTRejected', (data) => {
- return {
- collectionId: parseInt(data[1].toString(), 10),
- nftId: parseInt(data[2].toString(), 10),
- };
- });
-
- const rejectData = rejectResult.successData!;
-
- expect(rejectData.collectionId)
- .to.be.equal(collectionId, 'Error: Invalid collection ID (from event data)');
-
- expect(rejectData.nftId)
- .to.be.equal(nftId, 'Error: Invalid NFT ID (from event data)');
-
- const nftBefore = nftBeforeOpt.unwrap();
-
- const isPendingBeforeReject = nftBefore.pending.isTrue;
-
- const nftAfter = await getNft(api, collectionId, nftId);
-
- expect(isPendingBeforeReject, 'Error: NFT should be pending to be rejected')
- .to.be.true;
-
- expect(nftAfter.isNone, 'Error: NFT should be burned after reject')
- .to.be.true;
-}
-
-export async function createBase(
- api: ApiPromise,
- issuerUri: string,
- baseType: string,
- symbol: string,
- parts: object[],
-): Promise<number> {
- let baseId = 0;
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const partTypes = api.createType('Vec<RmrkTraitsPartPartType>', parts) as Vec<PartType>;
-
- const tx = api.tx.rmrkEquip.createBase(baseType, symbol, partTypes);
- const events = await executeTransaction(api, issuer, tx);
-
- const baseResult = extractRmrkEquipTxResult(events, 'BaseCreated', (data) => {
- return parseInt(data[1].toString(), 10);
- });
-
- expect(baseResult.success, 'Error: Unable to create Base')
- .to.be.true;
-
- baseId = baseResult.successData!;
- const baseOptional = await getBase(api, baseId);
-
- expect(baseOptional.isSome, 'Error: Unable to fetch created Base')
- .to.be.true;
-
- const base = baseOptional.unwrap();
- const baseParts = await getParts(api, baseId);
-
- expect(base.issuer.toString()).to.be.equal(issuer.address, 'Error: Invalid Base issuer');
- expect(base.baseType.toUtf8()).to.be.equal(baseType, 'Error: Invalid Base type');
- expect(base.symbol.toUtf8()).to.be.equal(symbol, 'Error: Invalid Base symbol');
- expect(partTypes.eq(baseParts), 'Error: Received invalid base parts').to.be.true;
-
- return baseId;
-}
-
-export async function setResourcePriorities(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
- priorities: number[],
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const prioritiesVec = api.createType('Vec<u32>', priorities);
- const tx = api.tx.rmrkCore.setPriority(collectionId, nftId, prioritiesVec);
- const events = await executeTransaction(api, issuer, tx);
-
- const prioResult = extractRmrkCoreTxResult(events, 'PrioritySet', (data) => {
- return {
- collectionId: parseInt(data[0].toString(), 10),
- nftId: parseInt(data[1].toString(), 10),
- };
- });
-
- expect(prioResult.success, 'Error: Unable to set resource priorities').to.be.true;
- const eventData = prioResult.successData!;
-
- expect(eventData.collectionId)
- .to.be.equal(collectionId, 'Error: Invalid collection ID (set priorities event data)');
-
- expect(eventData.nftId).to.be.equal(nftId, 'Error: Invalid NFT ID (set priorities event data');
-
- for (let i = 0; i < priorities.length; i++) {
- const resourceId = priorities[i];
-
- const fetchedPrio = await getResourcePriority(api, collectionId, nftId, resourceId);
- expect(fetchedPrio).to.be.equal(i, 'Error: Invalid priorities are set');
- }
-
-}
-
-export async function setEquippableList(
- api: ApiPromise,
- issuerUri: string,
- baseId: number,
- slotId: number,
- equippableList: 'All' | 'Empty' | { 'Custom': number[] },
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const equippable = api.createType('RmrkTraitsPartEquippableList', equippableList) as EquippableList;
-
- const tx = api.tx.rmrkEquip.equippable(baseId, slotId, equippable);
- const events = await executeTransaction(api, issuer, tx);
-
- const equipListResult = extractRmrkEquipTxResult(events, 'EquippablesUpdated', (data) => {
- return {
- baseId: parseInt(data[0].toString(), 10),
- slotId: parseInt(data[1].toString(), 10),
- };
- });
-
- expect(equipListResult.success, 'Error: unable to update equippable list').to.be.true;
- const updateEvent = equipListResult.successData!;
-
- expect(updateEvent.baseId)
- .to.be.equal(baseId, 'Error: invalid base ID from update equippable event');
-
- expect(updateEvent.slotId)
- .to.be.equal(slotId, 'Error: invalid base ID from update equippable event');
-
- const fetchedEquippableList = await getEquippableList(api, baseId, slotId);
-
- expect(fetchedEquippableList, 'Error: unable to fetch equippable list').to.be.not.null;
- if (fetchedEquippableList) {
- expect(fetchedEquippableList)
- .to.be.deep.equal(equippableList, 'Error: invalid equippable list was set');
- }
-}
-
-export async function addTheme(
- api: ApiPromise,
- issuerUri: string,
- baseId: number,
- themeObj: object,
- filterKeys: string[] | null = null,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const theme = api.createType('RmrkTraitsTheme', themeObj) as Theme;
-
- const tx = api.tx.rmrkEquip.themeAdd(baseId, theme);
- const events = await executeTransaction(api, issuer, tx);
-
- expect(isTxResultSuccess(events), 'Error: Unable to add Theme').to.be.true;
-
- const fetchedThemeOpt = await getTheme(api, baseId, theme.name.toUtf8(), null);
-
- expect(fetchedThemeOpt.isSome, 'Error: Unable to fetch theme').to.be.true;
-
- const fetchedTheme = fetchedThemeOpt.unwrap();
-
- expect(theme.name.eq(fetchedTheme.name), 'Error: Invalid theme name').to.be.true;
-
- for (let i = 0; i < theme.properties.length; i++) {
- const property = theme.properties[i];
- const propertyKey = property.key.toUtf8();
-
- const propertyFoundCount = fetchedTheme.properties.filter((fetchedProp) => property.key.eq(fetchedProp.key)).length;
-
- expect(propertyFoundCount > 1, `Error: Too many properties with key ${propertyKey} found`)
- .to.be.false;
-
- if (filterKeys) {
- const isFiltered = fetchedTheme.properties.find((fetchedProp) => fetchedProp.key.eq(property.key)) === undefined;
-
- if (isFiltered) {
- expect(propertyFoundCount === 0, `Error: Unexpected filtered key ${propertyKey}`)
- .to.be.true;
- continue;
- }
- }
-
- expect(propertyFoundCount === 1, `Error: The property with key ${propertyKey} is not found`)
- .to.be.true;
- }
-}
-
-export async function lockCollection(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- max = 0,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const tx = api.tx.rmrkCore.lockCollection(collectionId);
- const events = await executeTransaction(api, issuer, tx);
- const lockResult = extractRmrkCoreTxResult(events, 'CollectionLocked', (data) => {
- return parseInt(data[1].toString(), 10);
- });
- expect(lockResult.success, 'Error: Unable to lock a collection').to.be.true;
- expect(lockResult.successData!, 'Error: Invalid collection was locked')
- .to.be.eq(collectionId);
-
- await getCollection(api, collectionId).then((collectionOption) => {
- const collection = collectionOption.unwrap();
- expect(collection.max.unwrap().toNumber()).to.be.equal(max);
- });
-}
-
-export async function setPropertyCollection(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- key: string,
- value: string,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const alice = privateKey(issuerUri, Number(ss58Format));
-
- const tx = api.tx.rmrkCore.setProperty(collectionId, null, key, value);
- const events = await executeTransaction(api, alice, tx);
- const propResult = extractRmrkCoreTxResult(events, 'PropertySet', (data) => {
- return {
- collectionId: parseInt(data[0].toString(), 10),
- nftId: data[1] as Option<u32>,
- key: data[2] as Bytes,
- value: data[3] as Bytes,
- };
- });
-
- expect(propResult.success, 'Error: Unable to set collection property').to.be.true;
- const eventData = propResult.successData!;
- const eventDescription = 'from set collection property event';
-
- expect(eventData.collectionId, 'Error: Invalid collection ID ' + eventDescription)
- .to.be.equal(collectionId);
-
- expect(eventData.nftId.eq(null), 'Error: Unexpected NFT ID ' + eventDescription)
- .to.be.true;
-
- expect(eventData.key.eq(key), 'Error: Invalid property key ' + eventDescription)
- .to.be.true;
-
- expect(eventData.value.eq(value), 'Error: Invalid property value ' + eventDescription)
- .to.be.true;
-
- expect(await isCollectionPropertyExists(api, collectionId, key, value))
- .to.be.true;
-}
-
-export async function burnNft(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const maxBurns = 10;
- const tx = api.tx.rmrkCore.burnNft(collectionId, nftId, maxBurns);
- const events = await executeTransaction(api, issuer, tx);
- const burnResult = extractRmrkCoreTxResult(events, 'NFTBurned', (data) => {
- return parseInt(data[1].toString(), 10);
- });
-
- expect(burnResult.success, 'Error: Unable to burn an NFT').to.be.true;
- expect(burnResult.successData!, 'Error: Invalid NFT was burned')
- .to.be.eq(nftId);
-
- const nftBurned = await getNft(api, collectionId, nftId);
- expect(nftBurned.isSome).to.be.false;
-}
-
-export async function acceptNftResource(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
- resourceId: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const tx = api.tx.rmrkCore.acceptResource(
- collectionId,
- nftId,
- resourceId,
- );
-
- const events = await executeTransaction(api, issuer, tx);
- const acceptResult = extractRmrkCoreTxResult(events, 'ResourceAccepted', (data) => {
- return {
- nftId: parseInt(data[0].toString(), 10),
- resourceId: parseInt(data[1].toString(), 10),
- };
- });
-
- expect(acceptResult.success, 'Error: Unable to accept a resource').to.be.true;
- expect(acceptResult.successData!.nftId, 'Error: Invalid NFT ID while accepting a resource')
- .to.be.eq(nftId);
- expect(acceptResult.successData!.resourceId, 'Error: Invalid resource ID while accepting a resource')
- .to.be.eq(resourceId);
-
- const resource = await getResourceById(api, collectionId, nftId, resourceId);
- checkResourceStatus(resource, 'added');
-}
-
-async function executeResourceCreation(
- api: ApiPromise,
- issuer: IKeyringPair,
- tx: any,
- collectionId: number,
- nftId: number,
- expectedStatus: 'pending' | 'added',
-): Promise<ResourceInfo> {
- const events = await executeTransaction(api, issuer, tx);
-
- const resourceResult = extractRmrkCoreTxResult(events, 'ResourceAdded', (data) => {
- return parseInt(data[1].toString(), 10);
- });
- expect(resourceResult.success, 'Error: Unable to add resource').to.be.true;
- const resourceId = resourceResult.successData!;
-
- const resource = await getResourceById(api, collectionId, nftId, resourceId);
- checkResourceStatus(resource, expectedStatus);
-
- return resource;
-}
-
-export async function addNftBasicResource(
- api: ApiPromise,
- issuerUri: string,
- expectedStatus: 'pending' | 'added',
- collectionId: number,
- nftId: number,
- src: string | null,
- metadata: string | null,
- license: string | null,
- thumb: string | null,
-): Promise<number> {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const basicResource = api.createType('RmrkTraitsResourceBasicResource', {
- src: src,
- metadata: metadata,
- license: license,
- thumb: thumb,
- }) as BasicResource;
-
- const tx = api.tx.rmrkCore.addBasicResource(
- collectionId,
- nftId,
- basicResource,
- );
-
- const resource = await executeResourceCreation(api, issuer, tx, collectionId, nftId, expectedStatus);
-
- // FIXME A workaround. It seems it is a PolkadotJS bug.
- // All of the following are `false`.
- //
- // console.log('>>> basic:', resource.resource.isBasic);
- // console.log('>>> composable:', resource.resource.isComposable);
- // console.log('>>> slot:', resource.resource.isSlot);
- const resourceJson = resource.resource.toHuman() as any;
-
- expect(Object.prototype.hasOwnProperty.call(resourceJson, 'Basic'), 'Error: Expected basic resource type')
- .to.be.true;
-
- const recvBasicRes = resourceJson['Basic'];
-
- expect(recvBasicRes.src, 'Error: Invalid basic resource src')
- .to.be.eq(src);
- expect(recvBasicRes.metadata, 'Error: basic first resource metadata')
- .to.be.eq(metadata);
- expect(recvBasicRes.license, 'Error: basic first resource license')
- .to.be.eq(license);
- expect(recvBasicRes.thumb, 'Error: basic first resource thumb')
- .to.be.eq(thumb);
-
- return resource.id.toNumber();
-}
-
-export async function addNftComposableResource(
- api: ApiPromise,
- issuerUri: string,
- expectedStatus: 'pending' | 'added',
- collectionId: number,
- nftId: number,
- parts: number[],
- baseId: number,
- src: string | null,
- metadata: string | null,
- license: string | null,
- thumb: string | null,
-): Promise<number> {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const composableResource = api.createType('RmrkTraitsResourceComposableResource', {
- parts: parts, // api.createType('Vec<u32>', parts),
- base: baseId,
- src: src,
- metadata: metadata,
- license: license,
- thumb: thumb,
- }) as ComposableResource;
-
- const tx = api.tx.rmrkCore.addComposableResource(
- collectionId,
- nftId,
- composableResource,
- );
-
- const resource = await executeResourceCreation(api, issuer, tx, collectionId, nftId, expectedStatus);
-
- // FIXME A workaround. It seems it is a PolkadotJS bug.
- // All of the following are `false`.
- //
- // console.log('>>> basic:', resource.resource.isBasic);
- // console.log('>>> composable:', resource.resource.isComposable);
- // console.log('>>> slot:', resource.resource.isSlot);
- const resourceJson = resource.resource.toHuman() as any;
-
- expect(Object.prototype.hasOwnProperty.call(resourceJson, 'Composable'), 'Error: Expected composable resource type')
- .to.be.true;
-
- const recvComposableRes = resourceJson['Composable'];
-
- expect(recvComposableRes.parts.toString(), 'Error: Invalid composable resource parts')
- .to.be.eq(parts.toString());
- expect(recvComposableRes.base, 'Error: Invalid composable resource base id')
- .to.be.eq(baseId.toString());
- expect(recvComposableRes.src, 'Error: Invalid composable resource src')
- .to.be.eq(src);
- expect(recvComposableRes.metadata, 'Error: Invalid composable resource metadata')
- .to.be.eq(metadata);
- expect(recvComposableRes.license, 'Error: Invalid composable resource license')
- .to.be.eq(license);
- expect(recvComposableRes.thumb, 'Error: Invalid composable resource thumb')
- .to.be.eq(thumb);
-
- return resource.id.toNumber();
-}
-
-export async function addNftSlotResource(
- api: ApiPromise,
- issuerUri: string,
- expectedStatus: 'pending' | 'added',
- collectionId: number,
- nftId: number,
- baseId: number,
- slotId: number,
- src: string | null,
- metadata: string | null,
- license: string | null,
- thumb: string | null,
-): Promise<number> {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const slotResource = api.createType('RmrkTraitsResourceSlotResource', {
- base: baseId,
- src: src,
- metadata,
- slot: slotId,
- license: license,
- thumb: thumb,
- }) as SlotResource;
-
- const tx = api.tx.rmrkCore.addSlotResource(
- collectionId,
- nftId,
- slotResource,
- );
-
- const resource = await executeResourceCreation(api, issuer, tx, collectionId, nftId, expectedStatus);
-
- // FIXME A workaround. It seems it is a PolkadotJS bug.
- // All of the following are `false`.
- //
- // console.log('>>> basic:', resource.resource.isBasic);
- // console.log('>>> composable:', resource.resource.isComposable);
- // console.log('>>> slot:', resource.resource.isSlot);
- const resourceJson = resource.resource.toHuman() as any;
-
- expect(Object.prototype.hasOwnProperty.call(resourceJson, 'Slot'), 'Error: Expected slot resource type')
- .to.be.true;
-
- const recvSlotRes = resourceJson['Slot'];
-
- expect(recvSlotRes.base, 'Error: Invalid slot resource base id')
- .to.be.eq(baseId.toString());
- expect(recvSlotRes.slot, 'Error: Invalid slot resource slot id')
- .to.be.eq(slotId.toString());
- expect(recvSlotRes.src, 'Error: Invalid slot resource src')
- .to.be.eq(src);
- expect(recvSlotRes.metadata, 'Error: Invalid slot resource metadata')
- .to.be.eq(metadata);
- expect(recvSlotRes.license, 'Error: Invalid slot resource license')
- .to.be.eq(license);
- expect(recvSlotRes.thumb, 'Error: Invalid slot resource thumb')
- .to.be.eq(thumb);
-
- return resource.id.toNumber();
-}
-
-export async function equipNft(
- api: ApiPromise,
- issuerUri: string,
- item: NftIdTuple,
- equipper: NftIdTuple,
- resource: number,
- base: number,
- slot: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const tx = api.tx.rmrkEquip.equip(item, equipper, resource, base, slot);
- const events = await executeTransaction(api, issuer, tx);
- const equipResult = extractRmrkEquipTxResult(events, 'SlotEquipped', (data) => {
- return {
- item_collection: parseInt(data[0].toString(), 10),
- item_nft: parseInt(data[1].toString(), 10),
- base_id: parseInt(data[2].toString(), 10),
- slot_id: parseInt(data[3].toString(), 10),
- };
- });
- expect(equipResult.success, 'Error: Unable to equip an item').to.be.true;
- expect(equipResult.successData!.item_collection, 'Error: Invalid item collection id')
- .to.be.eq(item[0]);
- expect(equipResult.successData!.item_nft, 'Error: Invalid item NFT id')
- .to.be.eq(item[1]);
- expect(equipResult.successData!.base_id, 'Error: Invalid base id')
- .to.be.eq(base);
- expect(equipResult.successData!.slot_id, 'Error: Invalid slot id')
- .to.be.eq(slot);
-}
-
-export async function unequipNft(
- api: ApiPromise,
- issuerUri: string,
- item: any,
- equipper: any,
- resource: number,
- base: number,
- slot: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
- const tx = api.tx.rmrkEquip.equip(item, equipper, resource, base, slot);
- const events = await executeTransaction(api, issuer, tx);
-
- const unEquipResult = extractRmrkEquipTxResult(
- events,
- 'SlotUnequipped',
- (data) => {
- return {
- item_collection: parseInt(data[0].toString(), 10),
- item_nft: parseInt(data[1].toString(), 10),
- base_id: parseInt(data[2].toString(), 10),
- slot_id: parseInt(data[3].toString(), 10),
- };
- },
- );
-
- expect(unEquipResult.success, 'Error: Unable to unequip an item').to.be.true;
- expect(unEquipResult.successData!.item_collection, 'Error: Invalid item collection id')
- .to.be.eq(item[0]);
- expect(unEquipResult.successData!.item_nft, 'Error: Invalid item NFT id')
- .to.be.eq(item[1]);
- expect(unEquipResult.successData!.base_id, 'Error: Invalid base id')
- .to.be.eq(base);
- expect(unEquipResult.successData!.slot_id, 'Error: Invalid slot id')
- .to.be.eq(slot);
-}
-
-export async function removeNftResource(
- api: ApiPromise,
- expectedStatus: 'pending' | 'removed',
- issuerUri: string,
- collectionId: number,
- nftId: number,
- resourceId: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const tx = api.tx.rmrkCore.removeResource(collectionId, nftId, resourceId);
- const events = await executeTransaction(api, issuer, tx);
- const removeResult = extractRmrkCoreTxResult(events, 'ResourceRemoval', (data) => {
- return {
- nftId: parseInt(data[0].toString(), 10),
- resourceId: parseInt(data[1].toString(), 10),
- };
- });
- expect(removeResult.success, 'Error: Unable to remove a resource').to.be.true;
- expect(removeResult.successData!.nftId, 'Error: Invalid NFT Id while removing a resource')
- .to.be.eq(nftId);
- expect(removeResult.successData!.resourceId, 'Error: Invalid resource Id while removing a resource')
- .to.be.eq(resourceId);
-
- const afterDeleting = await findResourceById(api, collectionId, nftId, resourceId);
-
- if (expectedStatus === 'pending') {
- expect(afterDeleting).not.to.be.null;
- expect(afterDeleting?.pendingRemoval.isTrue).to.be.equal(true);
- } else {
- expect(afterDeleting).to.be.null;
- }
-}
-
-export async function acceptResourceRemoval(
- api: ApiPromise,
- issuerUri: string,
- collectionId: number,
- nftId: number,
- resourceId: number,
-) {
- const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
- const issuer = privateKey(issuerUri, Number(ss58Format));
-
- const tx = api.tx.rmrkCore.acceptResourceRemoval(collectionId, nftId, resourceId);
- const events = await executeTransaction(api, issuer, tx);
- const acceptResult = extractRmrkCoreTxResult(events, 'ResourceRemovalAccepted', (data) => {
- return {
- nftId: parseInt(data[0].toString(), 10),
- resourceId: parseInt(data[1].toString(), 10),
- };
- });
- expect(acceptResult.success, 'Error: Unable to accept a resource').to.be.true;
- expect(acceptResult.successData!.nftId, 'Error: Invalid NFT Id while accepting a resource')
- .to.be.eq(nftId);
- expect(acceptResult.successData!.resourceId, 'Error: Invalid resource Id while accepting a resource')
- .to.be.eq(resourceId);
-
- const afterDeleting = await findResourceById(api, collectionId, nftId, resourceId);
- expect(afterDeleting, 'Error: resource deleting failed').to.be.null;
-}
tests/src/.outdated/substrate/substrate-api.tsdiffbeforeafterboth--- a/tests/src/.outdated/substrate/substrate-api.ts
+++ b/tests/src/.outdated/substrate/substrate-api.ts
@@ -53,7 +53,6 @@
rpc: {
unique: defs.unique.rpc,
appPromotion: defs.appPromotion.rpc,
- rmrk: defs.rmrk.rpc,
eth: {
feeHistory: {
description: 'Dummy',
tests/src/interfaces/definitions.tsdiffbeforeafterboth--- a/tests/src/interfaces/definitions.ts
+++ b/tests/src/interfaces/definitions.ts
@@ -16,6 +16,5 @@
export {default as unique} from './unique/definitions';
export {default as appPromotion} from './appPromotion/definitions';
-export {default as rmrk} from './rmrk/definitions';
export {default as povinfo} from './povinfo/definitions';
export {default as default} from './default/definitions';
tests/src/interfaces/rmrk/definitions.tsdiffbeforeafterboth--- a/tests/src/interfaces/rmrk/definitions.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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 atParam = {name: 'at', type: 'Hash', isOptional: true};
-const fn = (description: string, params: RpcParam[], type: string) => ({
- description,
- params: [...params, atParam],
- type,
-});
-
-export default {
- types: {},
- rpc: {
- lastCollectionIdx: fn('Get the latest created collection id', [], 'u32'),
- collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<RmrkTraitsCollectionCollectionInfo>'),
- nftById: fn(
- 'Get NFT by collection id and NFT id',
- [
- {name: 'collectionId', type: 'u32'},
- {name: 'nftId', type: 'u32'},
- ],
- 'Option<RmrkTraitsNftNftInfo>',
- ),
- accountTokens: fn(
- 'Get tokens owned by an account in a collection',
- [
- {name: 'accountId', type: 'AccountId32'},
- {name: 'collectionId', type: 'u32'},
- ],
- 'Vec<u32>',
- ),
- nftChildren: fn(
- 'Get NFT children',
- [
- {name: 'collectionId', type: 'u32'},
- {name: 'nftId', type: 'u32'},
- ],
- 'Vec<RmrkTraitsNftNftChild>',
- ),
- collectionProperties: fn(
- 'Get collection properties',
- [
- {name: 'collectionId', type: 'u32'},
- {name: 'filterKeys', type: 'Vec<String>', isOptional: true},
- ],
- 'Vec<RmrkTraitsPropertyPropertyInfo>',
- ),
- nftProperties: fn(
- 'Get NFT properties',
- [
- {name: 'collectionId', type: 'u32'},
- {name: 'nftId', type: 'u32'},
- {name: 'filterKeys', type: 'Vec<String>', isOptional: true},
- ],
- 'Vec<RmrkTraitsPropertyPropertyInfo>',
- ),
- nftResources: fn(
- 'Get NFT resources',
- [
- {name: 'collectionId', type: 'u32'},
- {name: 'nftId', type: 'u32'},
- ],
- 'Vec<RmrkTraitsResourceResourceInfo>',
- ),
- nftResourcePriority: fn(
- 'Get NFT resource priorities',
- [
- {name: 'collectionId', type: 'u32'},
- {name: 'nftId', type: 'u32'},
- {name: 'resourceId', type: 'u32'},
- ],
- 'Option<u32>',
- ),
- base: fn(
- 'Get base info',
- [{name: 'baseId', type: 'u32'}],
- 'Option<RmrkTraitsBaseBaseInfo>',
- ),
- baseParts: fn(
- 'Get all Base\'s parts',
- [{name: 'baseId', type: 'u32'}],
- 'Vec<RmrkTraitsPartPartType>',
- ),
- themeNames: fn(
- 'Get Base\'s theme names',
- [{name: 'baseId', type: 'u32'}],
- 'Vec<Bytes>',
- ),
- themes: fn(
- 'Get Theme\'s keys values',
- [
- {name: 'baseId', type: 'u32'},
- {name: 'themeName', type: 'String'},
- {name: 'keys', type: 'Option<Vec<String>>'},
- ],
- 'Option<RmrkTraitsTheme>',
- ),
- },
-};
tests/src/interfaces/rmrk/index.tsdiffbeforeafterboth--- a/tests/src/interfaces/rmrk/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
-/* eslint-disable */
-
-export * from './types';
tests/src/interfaces/rmrk/types.tsdiffbeforeafterboth--- a/tests/src/interfaces/rmrk/types.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
-/* eslint-disable */
-
-export type PHANTOM_RMRK = 'rmrk';
tests/src/pallet-presence.test.tsdiffbeforeafterboth--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -64,7 +64,6 @@
const refungible = 'refungible';
const foreignAssets = 'foreignassets';
- const _rmrkPallets = ['rmrkcore', 'rmrkequip'];
const appPromotion = 'apppromotion';
const collatorSelection = ['authorship', 'session', 'collatorselection', 'identity'];
const testUtils = 'testutils';
tests/src/util/index.tsdiffbeforeafterboth--- a/tests/src/util/index.ts
+++ b/tests/src/util/index.ts
@@ -106,8 +106,6 @@
export enum Pallets {
Inflation = 'inflation',
- RmrkCore = 'rmrkcore',
- RmrkEquip = 'rmrkequip',
ReFungible = 'refungible',
Fungible = 'fungible',
NFT = 'nonfungible',
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -106,7 +106,6 @@
unique: defs.unique.rpc,
appPromotion: defs.appPromotion.rpc,
povinfo: defs.povinfo.rpc,
- rmrk: defs.rmrk.rpc,
eth: {
feeHistory: {
description: 'Dummy',