difftreelog
Merge branch 'develop' into CI-41-forckless-update-parachain-relay-nodata
in: master
155 files changed
.docker/Dockerfile-parachaindiffbeforeafterboth--- a/.docker/Dockerfile-parachain
+++ b/.docker/Dockerfile-parachain
@@ -9,7 +9,6 @@
ENV PATH="/cargo-home/bin:$PATH"
-
RUN apt-get update && \
apt-get install -y curl cmake pkg-config libssl-dev git clang && \
apt-get clean && \
@@ -23,11 +22,11 @@
rustup target list --installed && \
rustup show
RUN rustup target add wasm32-unknown-unknown --toolchain $RUST_TOOLCHAIN
-
RUN mkdir /unique_parachain
WORKDIR /unique_parachain
+
# ===== BUILD ======
FROM rust-builder as builder-unique
@@ -42,6 +41,7 @@
RUN git clone $REPO_URL -b $BRANCH && \
cargo build --features=$FEATURE --$PROFILE
+
# ===== BUILD POLKADOT =====
FROM rust-builder as builder-polkadot
@@ -60,7 +60,6 @@
FROM ubuntu:20.04
RUN apt-get -y update && \
- apt-get -y upgrade && \
apt-get -y install curl git && \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \
export NVM_DIR="$HOME/.nvm" && \
.docker/docker-compose-master.yamldiffbeforeafterboth--- /dev/null
+++ b/.docker/docker-compose-master.yaml
@@ -0,0 +1,19 @@
+version: "3.5"
+
+services:
+ blockchain_nodes:
+ build:
+ context: ../
+ dockerfile: .docker/Dockerfile-parachain
+ image: blockchain_nodes
+ container_name: blockchain_nodes
+ expose:
+ - 9944
+ - 9933
+ ports:
+ - 127.0.0.1:9944:9944
+ - 127.0.0.1:9933:9933
+ logging:
+ options:
+ max-size: "1m"
+ max-file: "3"
.docker/docker-compose.tmp-master.j2diffbeforeafterboth--- /dev/null
+++ b/.docker/docker-compose.tmp-master.j2
@@ -0,0 +1,11 @@
+version: "3.5"
+
+services:
+ blockchain_nodes:
+ build:
+ args:
+ - "RUST_TOOLCHAIN={{ RUST_TOOLCHAIN }}"
+ - "BRANCH={{ BRANCH }}"
+ - "REPO_URL={{ REPO_URL }}"
+ - "FEATURE={{ FEATURE }}"
+ - "POLKADOT_BUILD_BRANCH={{ POLKADOT_BUILD_BRANCH }}"
.gitattributesdiffbeforeafterboth--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,3 @@
* text=auto
*.sh text eol=lf
+*.ts linguist-detectable=false
\ No newline at end of file
.github/workflows/build-test-master.ymldiffbeforeafterboth--- /dev/null
+++ b/.github/workflows/build-test-master.yml
@@ -0,0 +1,122 @@
+name: MASTER - Build & Test
+
+# Controls when the action will run.
+on:
+ # Triggers the workflow on push or pull request events but only for the master branch
+ pull_request:
+ branches:
+ - master
+ types:
+ - opened
+ - reopened
+ - synchronize #commit(s) pushed to the pull request
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+#Define Workflow variables
+env:
+ REPO_URL: ${{ github.server_url }}/${{ github.repository }}
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+
+ build:
+ # The type of runner that the job will run on
+ runs-on: self-hosted-ci
+
+
+ name: Build Container, Spin it Up an test
+
+ continue-on-error: true #Do not stop testing of matrix runs failed.
+
+ strategy:
+ matrix:
+ include:
+ - network: "Opal"
+ features: " "
+ - network: "Quartz"
+ features: "--features=quartz-runtime"
+ - network: "Unique"
+ features: "--features=unique-runtime"
+
+ steps:
+ - name: Skip if pull request is in Draft
+ # `if: github.event.pull_request.draft == true` should be kept here, at
+ # the step level, rather than at the job level. The latter is not
+ # recommended because when the PR is moved from "Draft" to "Ready to
+ # review" the workflow will immediately be passing (since it was skipped),
+ # even though it hasn't actually ran, since it takes a few seconds for
+ # the workflow to start. This is also disclosed in:
+ # https://github.community/t/dont-run-actions-on-draft-pull-requests/16817/17
+ # That scenario would open an opportunity for the check to be bypassed:
+ # 1. Get your PR approved
+ # 2. Move it to Draft
+ # 3. Push whatever commits you want
+ # 4. Move it to "Ready for review"; now the workflow is passing (it was
+ # skipped) and "Check reviews" is also passing (it won't be updated
+ # until the workflow is finished)
+ if: github.event.pull_request.draft == true
+ run: exit 1
+
+ - name: Clean Workspace
+ uses: AutoModality/action-clean@v1.1.0
+
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v3
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Read .env file
+ uses: xom9ikk/dotenv@v1.0.2
+
+ - name: Generate ENV related extend file for docker-compose
+ uses: cuchi/jinja2-action@v1.2.0
+ with:
+ template: .docker/docker-compose.tmp-master.j2
+ output_file: .docker/docker-compose.${{ matrix.network }}.yml
+ variables: |
+ REPO_URL=${{ github.server_url }}/${{ github.repository }}.git
+ RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
+ POLKADOT_BUILD_BRANCH=${{ env.POLKADOT_BUILD_BRANCH }}
+ FEATURE=${{ matrix.features }}
+ BRANCH=${{ github.head_ref }}
+
+ - name: Show build configuration
+ run: cat .docker/docker-compose.${{ matrix.network }}.yml
+
+ - name: Build the stack
+ run: docker-compose -f ".docker/docker-compose-master.yml" -f ".docker/docker-compose.${{ matrix.network }}.yml" up -d --build
+
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 16
+
+ - name: Run tests
+ run: |
+ cd tests
+ yarn install
+ yarn add mochawesome
+ echo "Ready to start tests"
+ node scripts/readyness.js
+ NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-${NOW}
+ env:
+ RPC_URL: http://127.0.0.1:9933/
+
+ - name: Test Report
+ uses: phoenix-actions/test-reporting@v8
+ id: test-report
+ if: success() || failure() # run this step even if previous step failed
+ with:
+ name: Tests ${{ matrix.network }} # Name of the check run which will be created
+ path: tests/mochawesome-report/test-*.json # Path to test results
+ reporter: mochawesome-json
+ fail-on-error: 'false'
+
+ - name: Read output variables
+ run: |
+ echo "url is ${{ steps.test-report.outputs.runHtmlUrl }}"
+
+ - name: Stop running containers
+ if: always() # run this step always
+ run: docker-compose -f ".docker/docker-compose-master.yml" -f ".docker/docker-compose.${{ matrix.network }}.yml" down
.github/workflows/node_build_test.ymldiffbeforeafterboth--- a/.github/workflows/node_build_test.yml
+++ b/.github/workflows/node_build_test.yml
@@ -32,7 +32,7 @@
matrix:
include:
- network: "Opal"
- features: "--features=opal-runtime"
+ features: " "
- network: "Quartz"
features: "--features=quartz-runtime"
- network: "Unique"
@@ -57,6 +57,9 @@
if: github.event.pull_request.draft == true
run: exit 1
+ - name: Clean Workspace
+ uses: AutoModality/action-clean@v1.1.0
+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
with:
@@ -74,7 +77,7 @@
REPO_URL=${{ github.server_url }}/${{ github.repository }}.git
RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
POLKADOT_BUILD_BRANCH=${{ env.POLKADOT_BUILD_BRANCH }}
- FEATURE='${{ matrix.features }}'
+ FEATURE=${{ matrix.features }}
BRANCH=${{ github.head_ref }}
- name: Show build configuration
@@ -100,6 +103,7 @@
- name: Test Report
uses: phoenix-actions/test-reporting@v8
+ id: test-report
if: success() || failure() # run this step even if previous step failed
with:
name: Tests ${{ matrix.network }} # Name of the check run which will be created
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5291,6 +5291,7 @@
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"derivative",
+ "evm-coder",
"fp-evm-mapping",
"fp-rpc",
"fp-self-contained",
@@ -5352,9 +5353,10 @@
"sp-transaction-pool",
"sp-version",
"substrate-wasm-builder",
- "unique-runtime-common",
+ "up-common",
"up-data-structs",
"up-rpc",
+ "up-sponsorship",
"xcm",
"xcm-builder",
"xcm-executor",
@@ -8605,6 +8607,7 @@
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"derivative",
+ "evm-coder",
"fp-evm-mapping",
"fp-rpc",
"fp-self-contained",
@@ -8666,9 +8669,10 @@
"sp-transaction-pool",
"sp-version",
"substrate-wasm-builder",
- "unique-runtime-common",
+ "up-common",
"up-data-structs",
"up-rpc",
+ "up-sponsorship",
"xcm",
"xcm-builder",
"xcm-executor",
@@ -11881,6 +11885,7 @@
name = "tests"
version = "0.1.0"
dependencies = [
+ "evm-coder",
"fp-evm-mapping",
"frame-support",
"frame-system",
@@ -11902,8 +11907,8 @@
"sp-io",
"sp-runtime",
"sp-std",
- "unique-runtime-common",
"up-data-structs",
+ "up-sponsorship",
]
[[package]]
@@ -12387,7 +12392,6 @@
"sp-core",
"sp-rpc",
"sp-runtime",
- "unique-runtime-common",
"up-data-structs",
"up-rpc",
]
@@ -12541,7 +12545,7 @@
"try-runtime-cli",
"unique-rpc",
"unique-runtime",
- "unique-runtime-common",
+ "up-common",
"up-data-structs",
"up-rpc",
]
@@ -12590,7 +12594,7 @@
"substrate-frame-rpc-system",
"tokio 0.2.25",
"uc-rpc",
- "unique-runtime-common",
+ "up-common",
"up-data-structs",
"up-rpc",
]
@@ -12608,6 +12612,7 @@
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"derivative",
+ "evm-coder",
"fp-evm-mapping",
"fp-rpc",
"fp-self-contained",
@@ -12669,41 +12674,16 @@
"sp-transaction-pool",
"sp-version",
"substrate-wasm-builder",
- "unique-runtime-common",
+ "up-common",
"up-data-structs",
"up-rpc",
+ "up-sponsorship",
"xcm",
"xcm-builder",
"xcm-executor",
]
[[package]]
-name = "unique-runtime-common"
-version = "0.9.24"
-dependencies = [
- "evm-coder",
- "fp-rpc",
- "frame-support",
- "frame-system",
- "pallet-common",
- "pallet-evm",
- "pallet-fungible",
- "pallet-nonfungible",
- "pallet-refungible",
- "pallet-unique",
- "pallet-unique-scheduler",
- "parity-scale-codec 3.1.5",
- "rmrk-rpc",
- "scale-info",
- "sp-consensus-aura",
- "sp-core",
- "sp-runtime",
- "sp-std",
- "up-data-structs",
- "up-sponsorship",
-]
-
-[[package]]
name = "universal-hash"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12732,6 +12712,19 @@
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
+name = "up-common"
+version = "0.9.24"
+dependencies = [
+ "fp-rpc",
+ "frame-support",
+ "pallet-evm",
+ "sp-consensus-aura",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "up-data-structs"
version = "0.2.1"
dependencies = [
README.mddiffbeforeafterboth--- a/README.md
+++ b/README.md
@@ -23,8 +23,8 @@
Wider Unique Ecosystem (most of it was developed during Hackusama):
-- [SubstraPunks Game hosted on IPFS](https://github.com/usetech-llc/substrapunks)
-- [Unique Wallet and UI](https://uniqueapps.usetech.com/#/nft)
+- [SubstraPunks Game hosted on IPFS](https://github.com/UniqueNetwork/substrapunks)
+- [Unique Wallet and UI](https://wallet.unique.network)
- [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)
Please see our [walk-through instructions](doc/hackusama_walk_through.md) to try everything out!
client/rpc/Cargo.tomldiffbeforeafterboth--- a/client/rpc/Cargo.toml
+++ b/client/rpc/Cargo.toml
@@ -5,7 +5,6 @@
edition = "2021"
[dependencies]
-unique-runtime-common = { default-features = false, path = "../../runtime/common" }
pallet-common = { default-features = false, path = '../../pallets/common' }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
up-rpc = { path = "../../primitives/rpc" }
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -253,9 +253,8 @@
################################################################################
# Local dependencies
-[dependencies.unique-runtime-common]
-default-features = false
-path = "../../runtime/common"
+[dependencies.up-common]
+path = "../../primitives/common"
[dependencies.unique-runtime]
path = '../../runtime/unique'
node/cli/src/chain_spec.rsdiffbeforeafterboth--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -23,7 +23,7 @@
use serde::{Deserialize, Serialize};
use serde_json::map::Map;
-use unique_runtime_common::types::*;
+use up_common::types::opaque::*;
#[cfg(feature = "unique-runtime")]
pub use unique_runtime as default_runtime;
node/cli/src/command.rsdiffbeforeafterboth--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -64,7 +64,7 @@
use sp_runtime::traits::{AccountIdConversion, Block as BlockT};
use std::{io::Write, net::SocketAddr, time::Duration};
-use unique_runtime_common::types::Block;
+use up_common::types::opaque::Block;
macro_rules! no_runtime_err {
($chain_name:expr) => {
node/cli/src/service.rsdiffbeforeafterboth--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -63,7 +63,7 @@
use fc_rpc_core::types::FilterPool;
use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};
-use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};
+use up_common::types::opaque::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};
// RMRK
use up_data_structs::{
node/rpc/Cargo.tomldiffbeforeafterboth--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -49,7 +49,7 @@
fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
pallet-common = { default-features = false, path = "../../pallets/common" }
-unique-runtime-common = { default-features = false, path = "../../runtime/common" }
+up-common = { path = "../../primitives/common" }
pallet-unique = { path = "../../pallets/unique" }
uc-rpc = { path = "../../client/rpc" }
up-rpc = { path = "../../primitives/rpc" }
node/rpc/src/lib.rsdiffbeforeafterboth--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -40,9 +40,8 @@
use sc_service::TransactionPool;
use std::{collections::BTreeMap, sync::Arc};
-use unique_runtime_common::types::{
- Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,
-};
+use up_common::types::opaque::{Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance};
+
// RMRK
use up_data_structs::{
RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -25,7 +25,8 @@
use pallet_evm_coder_substrate::dispatch_to_evm;
use sp_std::vec::Vec;
use up_data_structs::{
- Property, SponsoringRateLimit, OwnerRestrictedSet, AccessMode, CollectionPermissions,
+ AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,
+ SponsoringRateLimit,
};
use alloc::format;
@@ -408,6 +409,28 @@
save(self)
}
+
+ /// Check that account is the owner or admin of the collection
+ ///
+ /// @param user account to verify
+ /// @return "true" if account is the owner or admin
+ fn verify_owner_or_admin(&self, user: address) -> Result<bool> {
+ Ok(check_is_owner_or_admin(user, self)
+ .map(|_| true)
+ .unwrap_or(false))
+ }
+
+ /// Returns collection type
+ ///
+ /// @return `Fungible` or `NFT` or `ReFungible`
+ fn unique_collection_type(&mut self) -> Result<string> {
+ let mode = match self.collection.mode {
+ CollectionMode::Fungible(_) => "Fungible",
+ CollectionMode::NFT => "NFT",
+ CollectionMode::ReFungible => "ReFungible",
+ };
+ Ok(mode.into())
+ }
}
fn check_is_owner_or_admin<T: Config>(
@@ -462,6 +485,11 @@
pub fn suffix() -> up_data_structs::PropertyKey {
property_key_from_bytes(b"suffix").expect(EXPECT_CONVERT_ERROR)
}
+
+ /// Key "parentNft".
+ pub fn parent_nft() -> up_data_structs::PropertyKey {
+ property_key_from_bytes(b"parentNft").expect(EXPECT_CONVERT_ERROR)
+ }
}
/// Values.
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -535,7 +535,8 @@
/// Can't transfer tokens to ethereum zero address
AddressIsZero,
- /// Target collection doesn't support this operation
+
+ /// The oprtation is not supported
UnsupportedOperation,
/// Insufficient funds to perform an action
@@ -1112,6 +1113,26 @@
sender: &T::CrossAccountId,
property_permission: PropertyKeyPermission,
) -> DispatchResult {
+ Self::set_scoped_property_permission(
+ collection,
+ sender,
+ PropertyScope::None,
+ property_permission,
+ )
+ }
+
+ /// Set collection property permission with scope.
+ ///
+ /// * `collection` - Collection handler.
+ /// * `sender` - The owner or administrator of the collection.
+ /// * `scope` - Property scope.
+ /// * `property_permission` - Property permission.
+ pub fn set_scoped_property_permission(
+ collection: &CollectionHandle<T>,
+ sender: &T::CrossAccountId,
+ scope: PropertyScope,
+ property_permission: PropertyKeyPermission,
+ ) -> DispatchResult {
collection.check_is_owner_or_admin(sender)?;
let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);
@@ -1125,7 +1146,11 @@
CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {
let property_permission = property_permission.clone();
- permissions.try_set(property_permission.key, property_permission.permission)
+ permissions.try_scoped_set(
+ scope,
+ property_permission.key,
+ property_permission.permission,
+ )
})
.map_err(<Error<T>>::from)?;
@@ -1148,8 +1173,29 @@
sender: &T::CrossAccountId,
property_permissions: Vec<PropertyKeyPermission>,
) -> DispatchResult {
+ Self::set_scoped_token_property_permissions(
+ collection,
+ sender,
+ PropertyScope::None,
+ property_permissions,
+ )
+ }
+
+ /// Set token property permission with scope.
+ ///
+ /// * `collection` - Collection handler.
+ /// * `sender` - The owner or administrator of the collection.
+ /// * `scope` - Property scope.
+ /// * `property_permissions` - Property permissions.
+ #[transactional]
+ pub fn set_scoped_token_property_permissions(
+ collection: &CollectionHandle<T>,
+ sender: &T::CrossAccountId,
+ scope: PropertyScope,
+ property_permissions: Vec<PropertyKeyPermission>,
+ ) -> DispatchResult {
for prop_pemission in property_permissions {
- Self::set_property_permission(collection, sender, prop_pemission)?;
+ Self::set_scoped_property_permission(collection, sender, scope, prop_pemission)?;
}
Ok(())
@@ -1353,8 +1399,8 @@
/// Indicates unsupported methods by returning [Error::UnsupportedOperation].
#[macro_export]
macro_rules! unsupported {
- () => {
- Err(<Error<T>>::UnsupportedOperation.into())
+ ($runtime:path) => {
+ Err($crate::Error::<$runtime>::UnsupportedOperation.into())
};
}
@@ -1429,6 +1475,9 @@
.saturating_mul(max_selfs.max(1) as u64)
.saturating_add(Self::burn_recursively_breadth_raw(max_breadth))
}
+
+ /// The price of retrieving token owner
+ fn token_owner() -> Weight;
}
/// Weight info extension trait for refungible pallet.
@@ -1567,7 +1616,7 @@
///
/// * `sender` - Must be either the owner of the token or its admin.
/// * `token_id` - The token for which the properties are being set.
- /// * `properties` - Properties to be set.
+ /// * `property_permissions` - Property permissions to be set.
/// * `budget` - Budget for setting properties.
fn set_token_property_permissions(
&self,
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -103,6 +103,10 @@
// Fungible tokens can't have children
0
}
+
+ fn token_owner() -> Weight {
+ 0
+ }
}
/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -31,19 +31,7 @@
);
}
-// Selector: 79cc6790
-contract ERC20UniqueExtensions is Dummy, ERC165 {
- // Selector: burnFrom(address,uint256) 79cc6790
- function burnFrom(address from, uint256 amount) public returns (bool) {
- require(false, stub_error);
- from;
- amount;
- dummy = 0;
- return false;
- }
-}
-
-// Selector: 7d9262e6
+// Selector: 6cf113cd
contract Collection is Dummy, ERC165 {
// Set collection property.
//
@@ -268,6 +256,42 @@
mode;
dummy = 0;
}
+
+ // Check that account is the owner or admin of the collection
+ //
+ // @param user account to verify
+ // @return "true" if account is the owner or admin
+ //
+ // Selector: verifyOwnerOrAdmin(address) c2282493
+ function verifyOwnerOrAdmin(address user) public view returns (bool) {
+ require(false, stub_error);
+ user;
+ dummy;
+ return false;
+ }
+
+ // Returns collection type
+ //
+ // @return `Fungible` or `NFT` or `ReFungible`
+ //
+ // Selector: uniqueCollectionType() d34b55b8
+ function uniqueCollectionType() public returns (string memory) {
+ require(false, stub_error);
+ dummy = 0;
+ return "";
+ }
+}
+
+// Selector: 79cc6790
+contract ERC20UniqueExtensions is Dummy, ERC165 {
+ // Selector: burnFrom(address,uint256) 79cc6790
+ function burnFrom(address from, uint256 amount) public returns (bool) {
+ require(false, stub_error);
+ from;
+ amount;
+ dummy = 0;
+ return false;
+ }
}
// Selector: 942e8b22
pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -17,11 +17,14 @@
use super::*;
use crate::{Pallet, Config, NonfungibleHandle};
-use sp_std::prelude::*;
-use pallet_common::benchmarking::{create_collection_raw, property_key, property_value};
use frame_benchmarking::{benchmarks, account};
+use pallet_common::{
+ bench_init,
+ benchmarking::{create_collection_raw, property_key, property_value},
+ CommonCollectionOperations,
+};
+use sp_std::prelude::*;
use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};
-use pallet_common::bench_init;
const SEED: u32 = 1;
@@ -208,4 +211,13 @@
<Pallet<T>>::set_token_properties(&collection, &owner, item, props.into_iter(), false, &Unlimited)?;
let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();
}: {<Pallet<T>>::delete_token_properties(&collection, &owner, item, to_delete.into_iter(), &Unlimited)?}
+
+ token_owner {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ owner: cross_from_sub;
+ };
+ let item = create_max_item(&collection, &owner, owner.clone())?;
+
+ }: {collection.token_owner(item)}
}
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -118,6 +118,10 @@
<SelfWeightOf<T>>::burn_recursively_breadth_plus_self_plus_self_per_each_raw(amount)
.saturating_sub(Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1))
}
+
+ fn token_owner() -> Weight {
+ <SelfWeightOf<T>>::token_owner()
+ }
}
fn map_create_data<T: Config>(
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -784,6 +784,23 @@
<PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
}
+ /// Set property permissions for the token with scope.
+ ///
+ /// Sender should be the owner or admin of token's collection.
+ pub fn set_scoped_token_property_permissions(
+ collection: &CollectionHandle<T>,
+ sender: &T::CrossAccountId,
+ scope: PropertyScope,
+ property_permissions: Vec<PropertyKeyPermission>,
+ ) -> DispatchResult {
+ <PalletCommon<T>>::set_scoped_token_property_permissions(
+ collection,
+ sender,
+ scope,
+ property_permissions,
+ )
+ }
+
/// Set property permissions for the collection.
///
/// Sender should be the owner or admin of the collection.
pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -373,49 +373,7 @@
}
}
-// Selector: 780e9d63
-contract ERC721Enumerable is Dummy, ERC165 {
- // @notice Enumerate valid NFTs
- // @param index A counter less than `totalSupply()`
- // @return The token identifier for the `index`th NFT,
- // (sort order not specified)
- //
- // Selector: tokenByIndex(uint256) 4f6ccce7
- function tokenByIndex(uint256 index) public view returns (uint256) {
- require(false, stub_error);
- index;
- dummy;
- return 0;
- }
-
- // @dev Not implemented
- //
- // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
- function tokenOfOwnerByIndex(address owner, uint256 index)
- public
- view
- returns (uint256)
- {
- require(false, stub_error);
- owner;
- index;
- dummy;
- return 0;
- }
-
- // @notice Count NFTs tracked by this contract
- // @return A count of valid NFTs tracked by this contract, where each one of
- // them has an assigned and queryable owner not equal to the zero address
- //
- // Selector: totalSupply() 18160ddd
- function totalSupply() public view returns (uint256) {
- require(false, stub_error);
- dummy;
- return 0;
- }
-}
-
-// Selector: 7d9262e6
+// Selector: 6cf113cd
contract Collection is Dummy, ERC165 {
// Set collection property.
//
@@ -640,6 +598,72 @@
mode;
dummy = 0;
}
+
+ // Check that account is the owner or admin of the collection
+ //
+ // @param user account to verify
+ // @return "true" if account is the owner or admin
+ //
+ // Selector: verifyOwnerOrAdmin(address) c2282493
+ function verifyOwnerOrAdmin(address user) public view returns (bool) {
+ require(false, stub_error);
+ user;
+ dummy;
+ return false;
+ }
+
+ // Returns collection type
+ //
+ // @return `Fungible` or `NFT` or `ReFungible`
+ //
+ // Selector: uniqueCollectionType() d34b55b8
+ function uniqueCollectionType() public returns (string memory) {
+ require(false, stub_error);
+ dummy = 0;
+ return "";
+ }
+}
+
+// Selector: 780e9d63
+contract ERC721Enumerable is Dummy, ERC165 {
+ // @notice Enumerate valid NFTs
+ // @param index A counter less than `totalSupply()`
+ // @return The token identifier for the `index`th NFT,
+ // (sort order not specified)
+ //
+ // Selector: tokenByIndex(uint256) 4f6ccce7
+ function tokenByIndex(uint256 index) public view returns (uint256) {
+ require(false, stub_error);
+ index;
+ dummy;
+ return 0;
+ }
+
+ // @dev Not implemented
+ //
+ // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
+ function tokenOfOwnerByIndex(address owner, uint256 index)
+ public
+ view
+ returns (uint256)
+ {
+ require(false, stub_error);
+ owner;
+ index;
+ dummy;
+ return 0;
+ }
+
+ // @notice Count NFTs tracked by this contract
+ // @return A count of valid NFTs tracked by this contract, where each one of
+ // them has an assigned and queryable owner not equal to the zero address
+ //
+ // Selector: totalSupply() 18160ddd
+ function totalSupply() public view returns (uint256) {
+ require(false, stub_error);
+ dummy;
+ return 0;
+ }
}
// Selector: d74d154f
pallets/nonfungible/src/weights.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -3,7 +3,7 @@
//! Autogenerated weights for pallet_nonfungible
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-07-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2022-08-01, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
// Executed Command:
@@ -46,6 +46,7 @@
fn set_token_property_permissions(b: u32, ) -> Weight;
fn set_token_properties(b: u32, ) -> Weight;
fn delete_token_properties(b: u32, ) -> Weight;
+ fn token_owner() -> Weight;
}
/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.
@@ -56,7 +57,7 @@
// Storage: Nonfungible TokenData (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:1)
fn create_item() -> Weight {
- (20_328_000 as Weight)
+ (20_909_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
@@ -65,9 +66,9 @@
// Storage: Nonfungible TokenData (r:0 w:4)
// Storage: Nonfungible Owned (r:0 w:4)
fn create_multiple_items(b: u32, ) -> Weight {
- (10_134_000 as Weight)
- // Standard Error: 3_000
- .saturating_add((4_927_000 as Weight).saturating_mul(b as Weight))
+ (12_601_000 as Weight)
+ // Standard Error: 1_000
+ .saturating_add((4_920_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
.saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))
@@ -77,9 +78,9 @@
// Storage: Nonfungible TokenData (r:0 w:4)
// Storage: Nonfungible Owned (r:0 w:4)
fn create_multiple_items_ex(b: u32, ) -> Weight {
- (5_710_000 as Weight)
- // Standard Error: 4_000
- .saturating_add((7_578_000 as Weight).saturating_mul(b as Weight))
+ (0 as Weight)
+ // Standard Error: 3_000
+ .saturating_add((7_734_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
@@ -93,7 +94,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Nonfungible TokenProperties (r:0 w:1)
fn burn_item() -> Weight {
- (28_433_000 as Weight)
+ (29_746_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -105,7 +106,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Nonfungible TokenProperties (r:0 w:1)
fn burn_recursively_self_raw() -> Weight {
- (34_435_000 as Weight)
+ (36_077_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -119,8 +120,8 @@
// Storage: Common CollectionById (r:1 w:0)
fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_539_000
- .saturating_add((304_456_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_605_000
+ .saturating_add((312_391_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(7 as Weight))
.saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
@@ -131,14 +132,14 @@
// Storage: Nonfungible Allowance (r:1 w:0)
// Storage: Nonfungible Owned (r:0 w:2)
fn transfer() -> Weight {
- (24_376_000 as Weight)
+ (25_248_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
// Storage: Nonfungible TokenData (r:1 w:0)
// Storage: Nonfungible Allowance (r:1 w:1)
fn approve() -> Weight {
- (15_890_000 as Weight)
+ (16_321_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -147,7 +148,7 @@
// Storage: Nonfungible AccountBalance (r:2 w:2)
// Storage: Nonfungible Owned (r:0 w:2)
fn transfer_from() -> Weight {
- (28_634_000 as Weight)
+ (29_325_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
@@ -159,15 +160,15 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Nonfungible TokenProperties (r:0 w:1)
fn burn_from() -> Weight {
- (32_201_000 as Weight)
+ (33_323_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
// Storage: Common CollectionPropertyPermissions (r:1 w:1)
fn set_token_property_permissions(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 57_000
- .saturating_add((15_232_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 62_000
+ .saturating_add((16_222_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -175,8 +176,8 @@
// Storage: Nonfungible TokenProperties (r:1 w:1)
fn set_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_648_000
- .saturating_add((288_654_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_750_000
+ .saturating_add((304_476_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -184,11 +185,16 @@
// Storage: Nonfungible TokenProperties (r:1 w:1)
fn delete_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_632_000
- .saturating_add((289_190_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_638_000
+ .saturating_add((294_096_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Nonfungible TokenData (r:1 w:0)
+ fn token_owner() -> Weight {
+ (2_986_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(1 as Weight))
+ }
}
// For backwards compatibility and tests
@@ -198,7 +204,7 @@
// Storage: Nonfungible TokenData (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:1)
fn create_item() -> Weight {
- (20_328_000 as Weight)
+ (20_909_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
@@ -207,9 +213,9 @@
// Storage: Nonfungible TokenData (r:0 w:4)
// Storage: Nonfungible Owned (r:0 w:4)
fn create_multiple_items(b: u32, ) -> Weight {
- (10_134_000 as Weight)
- // Standard Error: 3_000
- .saturating_add((4_927_000 as Weight).saturating_mul(b as Weight))
+ (12_601_000 as Weight)
+ // Standard Error: 1_000
+ .saturating_add((4_920_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
.saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))
@@ -219,9 +225,9 @@
// Storage: Nonfungible TokenData (r:0 w:4)
// Storage: Nonfungible Owned (r:0 w:4)
fn create_multiple_items_ex(b: u32, ) -> Weight {
- (5_710_000 as Weight)
- // Standard Error: 4_000
- .saturating_add((7_578_000 as Weight).saturating_mul(b as Weight))
+ (0 as Weight)
+ // Standard Error: 3_000
+ .saturating_add((7_734_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
@@ -235,7 +241,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Nonfungible TokenProperties (r:0 w:1)
fn burn_item() -> Weight {
- (28_433_000 as Weight)
+ (29_746_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
@@ -247,7 +253,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Nonfungible TokenProperties (r:0 w:1)
fn burn_recursively_self_raw() -> Weight {
- (34_435_000 as Weight)
+ (36_077_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
@@ -261,8 +267,8 @@
// Storage: Common CollectionById (r:1 w:0)
fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_539_000
- .saturating_add((304_456_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_605_000
+ .saturating_add((312_391_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(7 as Weight))
.saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
@@ -273,14 +279,14 @@
// Storage: Nonfungible Allowance (r:1 w:0)
// Storage: Nonfungible Owned (r:0 w:2)
fn transfer() -> Weight {
- (24_376_000 as Weight)
+ (25_248_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
// Storage: Nonfungible TokenData (r:1 w:0)
// Storage: Nonfungible Allowance (r:1 w:1)
fn approve() -> Weight {
- (15_890_000 as Weight)
+ (16_321_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -289,7 +295,7 @@
// Storage: Nonfungible AccountBalance (r:2 w:2)
// Storage: Nonfungible Owned (r:0 w:2)
fn transfer_from() -> Weight {
- (28_634_000 as Weight)
+ (29_325_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
@@ -301,15 +307,15 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Nonfungible TokenProperties (r:0 w:1)
fn burn_from() -> Weight {
- (32_201_000 as Weight)
+ (33_323_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
// Storage: Common CollectionPropertyPermissions (r:1 w:1)
fn set_token_property_permissions(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 57_000
- .saturating_add((15_232_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 62_000
+ .saturating_add((16_222_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -317,8 +323,8 @@
// Storage: Nonfungible TokenProperties (r:1 w:1)
fn set_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_648_000
- .saturating_add((288_654_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_750_000
+ .saturating_add((304_476_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -326,9 +332,14 @@
// Storage: Nonfungible TokenProperties (r:1 w:1)
fn delete_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_632_000
- .saturating_add((289_190_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_638_000
+ .saturating_add((294_096_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Nonfungible TokenData (r:1 w:0)
+ fn token_owner() -> Weight {
+ (2_986_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(1 as Weight))
+ }
}
pallets/refungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -17,25 +17,26 @@
use super::*;
use crate::{Pallet, Config, RefungibleHandle};
+use core::convert::TryInto;
+use core::iter::IntoIterator;
+use frame_benchmarking::{benchmarks, account};
+use pallet_common::{
+ bench_init,
+ benchmarking::{create_collection_raw, property_key, property_value, create_data},
+};
+use sp_core::H160;
use sp_std::prelude::*;
-use pallet_common::benchmarking::{create_collection_raw, property_key, property_value, create_data};
-use frame_benchmarking::{benchmarks, account};
use up_data_structs::{
CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,
budget::Unlimited,
};
-use pallet_common::bench_init;
-use core::convert::TryInto;
-use core::iter::IntoIterator;
const SEED: u32 = 1;
fn create_max_item_data<CrossAccountId: Ord>(
users: impl IntoIterator<Item = (CrossAccountId, u128)>,
) -> CreateRefungibleExData<CrossAccountId> {
- let const_data = create_data::<CUSTOM_DATA_LIMIT>();
CreateRefungibleExData {
- const_data,
users: users
.into_iter()
.collect::<BTreeMap<_, _>>()
@@ -44,6 +45,7 @@
properties: Default::default(),
}
}
+
fn create_max_item<T: Config>(
collection: &RefungibleHandle<T>,
sender: &T::CrossAccountId,
@@ -59,11 +61,12 @@
) -> Result<RefungibleHandle<T>, DispatchError> {
create_collection_raw(
owner,
- CollectionMode::NFT,
+ CollectionMode::ReFungible,
<Pallet<T>>::init_collection,
RefungibleHandle::cast,
)
}
+
benchmarks! {
create_item {
bench_init!{
@@ -277,4 +280,21 @@
};
let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
}: {<Pallet<T>>::repartition(&collection, &owner, item, 200)?}
+
+ set_parent_nft_unchecked {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ sender: cross_from_sub(owner); owner: cross_sub;
+ };
+ let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
+
+ }: {<Pallet<T>>::set_parent_nft_unchecked(&collection, item, owner, T::CrossAccountId::from_eth(H160::default()))?}
+
+ token_owner {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ sender: cross_from_sub(owner); owner: cross_sub;
+ };
+ let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
+ }: {<Pallet<T>>::token_owner(collection.id, item)}
}
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -148,6 +148,10 @@
// Refungible token can't have children
0
}
+
+ fn token_owner() -> Weight {
+ <SelfWeightOf<T>>::token_owner()
+ }
}
fn map_create_data<T: Config>(
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -41,8 +41,8 @@
use sp_core::H160;
use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
use up_data_structs::{
- CollectionId, CollectionPropertiesVec, Property, PropertyKey, PropertyKeyPermission,
- PropertyPermission, TokenId,
+ CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey,
+ PropertyKeyPermission, PropertyPermission, TokenId,
};
use crate::{
@@ -413,7 +413,7 @@
}
/// Returns amount of pieces of `token` that `owner` have
-fn balance<T: Config>(
+pub fn balance<T: Config>(
collection: &RefungibleHandle<T>,
token: TokenId,
owner: &T::CrossAccountId,
@@ -424,7 +424,7 @@
}
/// Throws if `owner_balance` is lower than total amount of `token` pieces
-fn ensure_single_owner<T: Config>(
+pub fn ensure_single_owner<T: Config>(
collection: &RefungibleHandle<T>,
token: TokenId,
owner_balance: u128,
@@ -788,6 +788,16 @@
.map_err(dispatch_to_evm::<T>)?;
Ok(true)
}
+
+ /// Returns EVM address for refungible token
+ ///
+ /// @param token ID of the token
+ fn token_contract_address(&self, token: uint256) -> Result<address> {
+ Ok(T::EvmTokenAddressMapping::token_to_address(
+ self.id,
+ token.try_into().map_err(|_| "token id overflow")?,
+ ))
+ }
}
#[solidity_interface(
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -20,29 +20,95 @@
//! Method implementations are mostly doing parameter conversion and calling Nonfungible Pallet methods.
extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::format;
+
use core::{
char::{REPLACEMENT_CHARACTER, decode_utf16},
convert::TryInto,
ops::Deref,
};
-use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};
+use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight};
use pallet_common::{
CommonWeightInfo,
- erc::{CommonEvmHandler, PrecompileResult},
+ erc::{CommonEvmHandler, PrecompileResult, static_property::key},
+ eth::map_eth_to_id,
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
+use sp_core::H160;
use sp_std::vec::Vec;
-use up_data_structs::TokenId;
+use up_data_structs::{mapping::TokenAddressMapping, PropertyScope, TokenId};
use crate::{
Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,
- weights::WeightInfo, TotalSupply,
+ TokenProperties, TotalSupply, weights::WeightInfo,
};
pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);
+#[solidity_interface(name = "ERC1633")]
+impl<T: Config> RefungibleTokenHandle<T> {
+ fn parent_token(&self) -> Result<address> {
+ self.consume_store_reads(2)?;
+ let props = <TokenProperties<T>>::get((self.id, self.1));
+ let key = key::parent_nft();
+
+ let key_scoped = PropertyScope::Eth
+ .apply(key)
+ .expect("property key shouldn't exceed length limit");
+ if let Some(value) = props.get(&key_scoped) {
+ Ok(H160::from_slice(value.as_slice()))
+ } else {
+ Ok(*T::CrossTokenAddressMapping::token_to_address(self.id, self.1).as_eth())
+ }
+ }
+
+ fn parent_token_id(&self) -> Result<uint256> {
+ self.consume_store_reads(2)?;
+ let props = <TokenProperties<T>>::get((self.id, self.1));
+ let key = key::parent_nft();
+
+ let key_scoped = PropertyScope::Eth
+ .apply(key)
+ .expect("property key shouldn't exceed length limit");
+ if let Some(value) = props.get(&key_scoped) {
+ let nft_token_address = H160::from_slice(value.as_slice());
+ let nft_token_account = T::CrossAccountId::from_eth(nft_token_address);
+ let (_, token_id) = T::CrossTokenAddressMapping::address_to_token(&nft_token_account)
+ .ok_or("parent NFT should contain NFT token address")?;
+
+ Ok(token_id.into())
+ } else {
+ Ok(self.1.into())
+ }
+ }
+}
+
+#[solidity_interface(name = "ERC1633UniqueExtensions")]
+impl<T: Config> RefungibleTokenHandle<T> {
+ #[solidity(rename_selector = "setParentNFT")]
+ #[weight(<CommonWeights<T>>::token_owner() + <SelfWeightOf<T>>::set_parent_nft_unchecked())]
+ fn set_parent_nft(
+ &mut self,
+ caller: caller,
+ collection: address,
+ nft_id: uint256,
+ ) -> Result<bool> {
+ self.consume_store_reads(1)?;
+ let caller = T::CrossAccountId::from_eth(caller);
+ let nft_collection = map_eth_to_id(&collection).ok_or("collection not found")?;
+ let nft_token = nft_id.try_into()?;
+
+ <Pallet<T>>::set_parent_nft(&self.0, self.1, caller, nft_collection, nft_token)
+ .map_err(dispatch_to_evm::<T>)?;
+
+ Ok(true)
+ }
+}
+
#[derive(ToLog)]
pub enum ERC20Events {
/// @dev This event is emitted when the amount of tokens (value) is sent
@@ -120,7 +186,7 @@
.weight_calls_budget(<StructureWeight<T>>::find_parent());
<Pallet<T>>::transfer(self, &caller, &to, self.1, amount, &budget)
- .map_err(|_| "transfer error")?;
+ .map_err(dispatch_to_evm::<T>)?;
Ok(true)
}
@@ -239,7 +305,10 @@
}
}
-#[solidity_interface(name = "UniqueRefungibleToken", is(ERC20, ERC20UniqueExtensions,))]
+#[solidity_interface(
+ name = "UniqueRefungibleToken",
+ is(ERC20, ERC20UniqueExtensions, ERC1633, ERC1633UniqueExtensions)
+)]
impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}
generate_stubgen!(gen_impl, UniqueRefungibleTokenCall<()>, true);
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -99,8 +99,12 @@
use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
use pallet_evm_coder_substrate::WithRecorder;
use pallet_common::{
- CommonCollectionOperations, Error as CommonError, Event as CommonEvent,
- eth::collection_id_to_address, Pallet as PalletCommon,
+ CollectionHandle, CommonCollectionOperations,
+ dispatch::CollectionDispatch,
+ erc::static_property::{key, property_value_from_bytes},
+ Error as CommonError,
+ eth::collection_id_to_address,
+ Event as CommonEvent, Pallet as PalletCommon,
};
use pallet_structure::Pallet as PalletStructure;
use scale_info::TypeInfo;
@@ -108,10 +112,10 @@
use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};
use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
use up_data_structs::{
- AccessMode, budget::Budget, CollectionId, CreateCollectionData, CustomDataLimit,
- mapping::TokenAddressMapping, MAX_REFUNGIBLE_PIECES, MAX_ITEMS_PER_BATCH, TokenId, Property,
- PropertyKey, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,
- TrySetProperty, CollectionPropertiesVec,
+ AccessMode, budget::Budget, CollectionId, CollectionMode, CollectionPropertiesVec,
+ CreateCollectionData, CustomDataLimit, mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH,
+ MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyPermission,
+ PropertyScope, PropertyValue, TokenId, TrySetProperty,
};
use frame_support::BoundedBTreeMap;
use derivative::Derivative;
@@ -1341,6 +1345,20 @@
<PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
}
+ pub fn set_scoped_token_property_permissions(
+ collection: &RefungibleHandle<T>,
+ sender: &T::CrossAccountId,
+ scope: PropertyScope,
+ property_permissions: Vec<PropertyKeyPermission>,
+ ) -> DispatchResult {
+ <PalletCommon<T>>::set_scoped_token_property_permissions(
+ collection,
+ sender,
+ scope,
+ property_permissions,
+ )
+ }
+
/// Returns 10 token in no particular order.
///
/// There is no direct way to get token holders in ascending order,
@@ -1362,4 +1380,68 @@
Some(res)
}
}
+
+ /// Sets the NFT token as a parent for the RFT token
+ ///
+ /// Throws if `sender` is not the owner of the NFT token.
+ /// Throws if `sender` is not the owner of all of the RFT token pieces.
+ pub fn set_parent_nft(
+ collection: &RefungibleHandle<T>,
+ rft_token_id: TokenId,
+ sender: T::CrossAccountId,
+ nft_collection: CollectionId,
+ nft_token: TokenId,
+ ) -> DispatchResult {
+ let handle = <CollectionHandle<T>>::try_get(nft_collection)?;
+ if handle.mode != CollectionMode::NFT {
+ return Err("Only NFT token could be parent to RFT".into());
+ }
+ let dispatch = T::CollectionDispatch::dispatch(handle);
+ let dispatch = dispatch.as_dyn();
+
+ let owner = dispatch.token_owner(nft_token).ok_or("owner not found")?;
+ if owner != sender {
+ return Err("Only owned token could be set as parent".into());
+ }
+
+ let nft_token_address =
+ T::CrossTokenAddressMapping::token_to_address(nft_collection, nft_token);
+
+ Self::set_parent_nft_unchecked(collection, rft_token_id, sender, nft_token_address)
+ }
+
+ /// Sets the NFT token as a parent for the RFT token
+ ///
+ /// `sender` should be the owner of the NFT token.
+ /// Throws if `sender` is not the owner of all of the RFT token pieces.
+ pub fn set_parent_nft_unchecked(
+ collection: &RefungibleHandle<T>,
+ rft_token_id: TokenId,
+ sender: T::CrossAccountId,
+ nft_token_address: T::CrossAccountId,
+ ) -> DispatchResult {
+ let owner_balance = <Balance<T>>::get((collection.id, rft_token_id, &sender));
+ let total_supply = <TotalSupply<T>>::get((collection.id, rft_token_id));
+ if total_supply != owner_balance {
+ return Err("token has multiple owners".into());
+ }
+
+ let parent_nft_property_key = key::parent_nft();
+
+ let parent_nft_property_value =
+ property_value_from_bytes(&nft_token_address.as_eth().to_fixed_bytes())
+ .expect("address should fit in value length limit");
+
+ <Pallet<T>>::set_scoped_token_property(
+ collection.id,
+ rft_token_id,
+ PropertyScope::Eth,
+ Property {
+ key: parent_nft_property_key,
+ value: parent_nft_property_value,
+ },
+ )?;
+
+ Ok(())
+ }
}
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -371,49 +371,7 @@
}
}
-// Selector: 780e9d63
-contract ERC721Enumerable is Dummy, ERC165 {
- // @notice Enumerate valid RFTs
- // @param index A counter less than `totalSupply()`
- // @return The token identifier for the `index`th NFT,
- // (sort order not specified)
- //
- // Selector: tokenByIndex(uint256) 4f6ccce7
- function tokenByIndex(uint256 index) public view returns (uint256) {
- require(false, stub_error);
- index;
- dummy;
- return 0;
- }
-
- // Not implemented
- //
- // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
- function tokenOfOwnerByIndex(address owner, uint256 index)
- public
- view
- returns (uint256)
- {
- require(false, stub_error);
- owner;
- index;
- dummy;
- return 0;
- }
-
- // @notice Count RFTs tracked by this contract
- // @return A count of valid RFTs tracked by this contract, where each one of
- // them has an assigned and queryable owner not equal to the zero address
- //
- // Selector: totalSupply() 18160ddd
- function totalSupply() public view returns (uint256) {
- require(false, stub_error);
- dummy;
- return 0;
- }
-}
-
-// Selector: 7d9262e6
+// Selector: 6cf113cd
contract Collection is Dummy, ERC165 {
// Set collection property.
//
@@ -638,9 +596,75 @@
mode;
dummy = 0;
}
+
+ // Check that account is the owner or admin of the collection
+ //
+ // @param user account to verify
+ // @return "true" if account is the owner or admin
+ //
+ // Selector: verifyOwnerOrAdmin(address) c2282493
+ function verifyOwnerOrAdmin(address user) public view returns (bool) {
+ require(false, stub_error);
+ user;
+ dummy;
+ return false;
+ }
+
+ // Returns collection type
+ //
+ // @return `Fungible` or `NFT` or `ReFungible`
+ //
+ // Selector: uniqueCollectionType() d34b55b8
+ function uniqueCollectionType() public returns (string memory) {
+ require(false, stub_error);
+ dummy = 0;
+ return "";
+ }
+}
+
+// Selector: 780e9d63
+contract ERC721Enumerable is Dummy, ERC165 {
+ // @notice Enumerate valid RFTs
+ // @param index A counter less than `totalSupply()`
+ // @return The token identifier for the `index`th NFT,
+ // (sort order not specified)
+ //
+ // Selector: tokenByIndex(uint256) 4f6ccce7
+ function tokenByIndex(uint256 index) public view returns (uint256) {
+ require(false, stub_error);
+ index;
+ dummy;
+ return 0;
+ }
+
+ // Not implemented
+ //
+ // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
+ function tokenOfOwnerByIndex(address owner, uint256 index)
+ public
+ view
+ returns (uint256)
+ {
+ require(false, stub_error);
+ owner;
+ index;
+ dummy;
+ return 0;
+ }
+
+ // @notice Count RFTs tracked by this contract
+ // @return A count of valid RFTs tracked by this contract, where each one of
+ // them has an assigned and queryable owner not equal to the zero address
+ //
+ // Selector: totalSupply() 18160ddd
+ function totalSupply() public view returns (uint256) {
+ require(false, stub_error);
+ dummy;
+ return 0;
+ }
}
-// Selector: d74d154f
+// Selector: 7c3bef89
contract ERC721UniqueExtensions is Dummy, ERC165 {
// @notice Transfer ownership of an RFT
// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
@@ -719,6 +743,18 @@
dummy = 0;
return false;
}
+
+ // Returns EVM address for refungible token
+ //
+ // @param token ID of the token
+ //
+ // Selector: tokenContractAddress(uint256) ab76fac6
+ function tokenContractAddress(uint256 token) public view returns (address) {
+ require(false, stub_error);
+ token;
+ dummy;
+ return 0x0000000000000000000000000000000000000000;
+ }
}
contract UniqueRefungible is
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
@@ -31,6 +31,38 @@
);
}
+// Selector: 042f1106
+contract ERC1633UniqueExtensions is Dummy, ERC165 {
+ // Selector: setParentNFT(address,uint256) 042f1106
+ function setParentNFT(address collection, uint256 nftId)
+ public
+ returns (bool)
+ {
+ require(false, stub_error);
+ collection;
+ nftId;
+ dummy = 0;
+ return false;
+ }
+}
+
+// Selector: 5755c3f2
+contract ERC1633 is Dummy, ERC165 {
+ // Selector: parentToken() 80a54001
+ function parentToken() public view returns (address) {
+ require(false, stub_error);
+ dummy;
+ return 0x0000000000000000000000000000000000000000;
+ }
+
+ // Selector: parentTokenId() d7f083f3
+ function parentTokenId() public view returns (uint256) {
+ require(false, stub_error);
+ dummy;
+ return 0;
+ }
+}
+
// Selector: 942e8b22
contract ERC20 is Dummy, ERC165, ERC20Events {
// @return the name of the token.
@@ -178,4 +210,11 @@
}
}
-contract UniqueRefungibleToken is Dummy, ERC165, ERC20, ERC20UniqueExtensions {}
+contract UniqueRefungibleToken is
+ Dummy,
+ ERC165,
+ ERC20,
+ ERC20UniqueExtensions,
+ ERC1633,
+ ERC1633UniqueExtensions
+{}
pallets/refungible/src/weights.rsdiffbeforeafterboth--- a/pallets/refungible/src/weights.rs
+++ b/pallets/refungible/src/weights.rs
@@ -3,7 +3,7 @@
//! Autogenerated weights for pallet_refungible
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-07-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2022-08-01, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
// Executed Command:
@@ -53,6 +53,8 @@
fn set_token_properties(b: u32, ) -> Weight;
fn delete_token_properties(b: u32, ) -> Weight;
fn repartition_item() -> Weight;
+ fn set_parent_nft_unchecked() -> Weight;
+ fn token_owner() -> Weight;
}
/// Weights for pallet_refungible using the Substrate node and recommended hardware.
@@ -65,7 +67,7 @@
// Storage: Refungible TokenData (r:0 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn create_item() -> Weight {
- (21_310_000 as Weight)
+ (25_197_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
@@ -76,9 +78,9 @@
// Storage: Refungible TokenData (r:0 w:4)
// Storage: Refungible Owned (r:0 w:4)
fn create_multiple_items(b: u32, ) -> Weight {
- (9_552_000 as Weight)
+ (10_852_000 as Weight)
// Standard Error: 2_000
- .saturating_add((7_056_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add((8_087_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
.saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
@@ -90,9 +92,9 @@
// Storage: Refungible TokenData (r:0 w:4)
// Storage: Refungible Owned (r:0 w:4)
fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {
- (4_857_000 as Weight)
+ (9_978_000 as Weight)
// Standard Error: 2_000
- .saturating_add((9_838_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add((10_848_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
@@ -105,9 +107,9 @@
// Storage: Refungible Balance (r:0 w:4)
// Storage: Refungible Owned (r:0 w:4)
fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {
- (11_335_000 as Weight)
+ (15_419_000 as Weight)
// Standard Error: 2_000
- .saturating_add((6_784_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add((7_813_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
.saturating_add(T::DbWeight::get().writes(3 as Weight))
@@ -118,7 +120,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn burn_item_partial() -> Weight {
- (21_239_000 as Weight)
+ (25_578_000 as Weight)
.saturating_add(T::DbWeight::get().reads(3 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
@@ -130,13 +132,13 @@
// Storage: Refungible Owned (r:0 w:1)
// Storage: Refungible TokenProperties (r:0 w:1)
fn burn_item_fully() -> Weight {
- (29_426_000 as Weight)
+ (33_593_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
}
// Storage: Refungible Balance (r:2 w:2)
fn transfer_normal() -> Weight {
- (17_743_000 as Weight)
+ (21_049_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
}
@@ -144,7 +146,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_creating() -> Weight {
- (20_699_000 as Weight)
+ (24_646_000 as Weight)
.saturating_add(T::DbWeight::get().reads(3 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
@@ -152,7 +154,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_removing() -> Weight {
- (22_833_000 as Weight)
+ (26_570_000 as Weight)
.saturating_add(T::DbWeight::get().reads(3 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
@@ -160,21 +162,21 @@
// Storage: Refungible AccountBalance (r:2 w:2)
// Storage: Refungible Owned (r:0 w:2)
fn transfer_creating_removing() -> Weight {
- (24_936_000 as Weight)
+ (28_906_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
// Storage: Refungible Balance (r:1 w:0)
// Storage: Refungible Allowance (r:0 w:1)
fn approve() -> Weight {
- (13_446_000 as Weight)
+ (16_451_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
// Storage: Refungible Allowance (r:1 w:1)
// Storage: Refungible Balance (r:2 w:2)
fn transfer_from_normal() -> Weight {
- (24_777_000 as Weight)
+ (29_545_000 as Weight)
.saturating_add(T::DbWeight::get().reads(3 as Weight))
.saturating_add(T::DbWeight::get().writes(3 as Weight))
}
@@ -183,7 +185,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_from_creating() -> Weight {
- (28_483_000 as Weight)
+ (33_392_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -192,7 +194,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_from_removing() -> Weight {
- (29_896_000 as Weight)
+ (35_446_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -201,7 +203,7 @@
// Storage: Refungible AccountBalance (r:2 w:2)
// Storage: Refungible Owned (r:0 w:2)
fn transfer_from_creating_removing() -> Weight {
- (32_070_000 as Weight)
+ (37_762_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
}
@@ -214,15 +216,15 @@
// Storage: Refungible Owned (r:0 w:1)
// Storage: Refungible TokenProperties (r:0 w:1)
fn burn_from() -> Weight {
- (36_789_000 as Weight)
+ (42_620_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(8 as Weight))
}
// Storage: Common CollectionPropertyPermissions (r:1 w:1)
fn set_token_property_permissions(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 62_000
- .saturating_add((15_803_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 65_000
+ .saturating_add((16_513_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -230,8 +232,8 @@
// Storage: Refungible TokenProperties (r:1 w:1)
fn set_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_668_000
- .saturating_add((302_308_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_583_000
+ .saturating_add((291_392_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -239,18 +241,31 @@
// Storage: Refungible TokenProperties (r:1 w:1)
fn delete_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_619_000
- .saturating_add((294_574_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_699_000
+ .saturating_add((293_270_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
// Storage: Refungible TotalSupply (r:1 w:1)
// Storage: Refungible Balance (r:1 w:1)
fn repartition_item() -> Weight {
- (8_325_000 as Weight)
+ (19_206_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
}
+ // Storage: Refungible Balance (r:1 w:0)
+ // Storage: Refungible TotalSupply (r:1 w:0)
+ // Storage: Refungible TokenProperties (r:1 w:1)
+ fn set_parent_nft_unchecked() -> Weight {
+ (10_189_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(3 as Weight))
+ .saturating_add(T::DbWeight::get().writes(1 as Weight))
+ }
+ // Storage: Refungible Balance (r:2 w:0)
+ fn token_owner() -> Weight {
+ (8_205_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(2 as Weight))
+ }
}
// For backwards compatibility and tests
@@ -262,7 +277,7 @@
// Storage: Refungible TokenData (r:0 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn create_item() -> Weight {
- (21_310_000 as Weight)
+ (25_197_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
@@ -273,9 +288,9 @@
// Storage: Refungible TokenData (r:0 w:4)
// Storage: Refungible Owned (r:0 w:4)
fn create_multiple_items(b: u32, ) -> Weight {
- (9_552_000 as Weight)
+ (10_852_000 as Weight)
// Standard Error: 2_000
- .saturating_add((7_056_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add((8_087_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
.saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
@@ -287,9 +302,9 @@
// Storage: Refungible TokenData (r:0 w:4)
// Storage: Refungible Owned (r:0 w:4)
fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {
- (4_857_000 as Weight)
+ (9_978_000 as Weight)
// Standard Error: 2_000
- .saturating_add((9_838_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add((10_848_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
@@ -302,9 +317,9 @@
// Storage: Refungible Balance (r:0 w:4)
// Storage: Refungible Owned (r:0 w:4)
fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {
- (11_335_000 as Weight)
+ (15_419_000 as Weight)
// Standard Error: 2_000
- .saturating_add((6_784_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add((7_813_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
@@ -315,7 +330,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn burn_item_partial() -> Weight {
- (21_239_000 as Weight)
+ (25_578_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
@@ -327,13 +342,13 @@
// Storage: Refungible Owned (r:0 w:1)
// Storage: Refungible TokenProperties (r:0 w:1)
fn burn_item_fully() -> Weight {
- (29_426_000 as Weight)
+ (33_593_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
}
// Storage: Refungible Balance (r:2 w:2)
fn transfer_normal() -> Weight {
- (17_743_000 as Weight)
+ (21_049_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
}
@@ -341,7 +356,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_creating() -> Weight {
- (20_699_000 as Weight)
+ (24_646_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
@@ -349,7 +364,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_removing() -> Weight {
- (22_833_000 as Weight)
+ (26_570_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
@@ -357,21 +372,21 @@
// Storage: Refungible AccountBalance (r:2 w:2)
// Storage: Refungible Owned (r:0 w:2)
fn transfer_creating_removing() -> Weight {
- (24_936_000 as Weight)
+ (28_906_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
// Storage: Refungible Balance (r:1 w:0)
// Storage: Refungible Allowance (r:0 w:1)
fn approve() -> Weight {
- (13_446_000 as Weight)
+ (16_451_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
// Storage: Refungible Allowance (r:1 w:1)
// Storage: Refungible Balance (r:2 w:2)
fn transfer_from_normal() -> Weight {
- (24_777_000 as Weight)
+ (29_545_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
}
@@ -380,7 +395,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_from_creating() -> Weight {
- (28_483_000 as Weight)
+ (33_392_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
@@ -389,7 +404,7 @@
// Storage: Refungible AccountBalance (r:1 w:1)
// Storage: Refungible Owned (r:0 w:1)
fn transfer_from_removing() -> Weight {
- (29_896_000 as Weight)
+ (35_446_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
@@ -398,7 +413,7 @@
// Storage: Refungible AccountBalance (r:2 w:2)
// Storage: Refungible Owned (r:0 w:2)
fn transfer_from_creating_removing() -> Weight {
- (32_070_000 as Weight)
+ (37_762_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
}
@@ -411,15 +426,15 @@
// Storage: Refungible Owned (r:0 w:1)
// Storage: Refungible TokenProperties (r:0 w:1)
fn burn_from() -> Weight {
- (36_789_000 as Weight)
+ (42_620_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
}
// Storage: Common CollectionPropertyPermissions (r:1 w:1)
fn set_token_property_permissions(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 62_000
- .saturating_add((15_803_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 65_000
+ .saturating_add((16_513_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -427,8 +442,8 @@
// Storage: Refungible TokenProperties (r:1 w:1)
fn set_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_668_000
- .saturating_add((302_308_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_583_000
+ .saturating_add((291_392_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -436,16 +451,29 @@
// Storage: Refungible TokenProperties (r:1 w:1)
fn delete_token_properties(b: u32, ) -> Weight {
(0 as Weight)
- // Standard Error: 1_619_000
- .saturating_add((294_574_000 as Weight).saturating_mul(b as Weight))
+ // Standard Error: 1_699_000
+ .saturating_add((293_270_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
// Storage: Refungible TotalSupply (r:1 w:1)
// Storage: Refungible Balance (r:1 w:1)
fn repartition_item() -> Weight {
- (8_325_000 as Weight)
+ (19_206_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
}
+ // Storage: Refungible Balance (r:1 w:0)
+ // Storage: Refungible TotalSupply (r:1 w:0)
+ // Storage: Refungible TokenProperties (r:1 w:1)
+ fn set_parent_nft_unchecked() -> Weight {
+ (10_189_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(3 as Weight))
+ .saturating_add(RocksDbWeight::get().writes(1 as Weight))
+ }
+ // Storage: Refungible Balance (r:2 w:0)
+ fn token_owner() -> Weight {
+ (8_205_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(2 as Weight))
+ }
}
pallets/unique/src/eth/mod.rsdiffbeforeafterboth--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -17,26 +17,29 @@
//! Implementation of CollectionHelpers contract.
use core::marker::PhantomData;
-use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};
use ethereum as _;
-use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
-use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId, PrecompileHandle};
-use up_data_structs::{
- CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,
- CollectionMode, PropertyValue,
-};
+use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};
use frame_support::traits::Get;
use pallet_common::{
- CollectionById,
+ CollectionById, CollectionHandle,
+ dispatch::CollectionDispatch,
erc::{
+ CollectionHelpersEvents,
static_property::{key, value as property_value},
- CollectionHelpersEvents,
},
- dispatch::CollectionDispatch,
+ Pallet as PalletCommon,
};
-use crate::{SelfWeightOf, Config, weights::WeightInfo};
+use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
+use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
+use pallet_evm_coder_substrate::dispatch_to_evm;
+use up_data_structs::{
+ CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,
+ CollectionMode, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,
+};
+
+use crate::{Config, SelfWeightOf, weights::WeightInfo};
-use sp_std::vec::Vec;
+use sp_std::{vec, vec::Vec};
use alloc::format;
/// See [`CollectionHelpersCall`]
@@ -151,6 +154,54 @@
Ok(data)
}
+fn parent_nft_property_permissions() -> PropertyKeyPermission {
+ PropertyKeyPermission {
+ key: key::parent_nft(),
+ permission: PropertyPermission {
+ mutable: false,
+ collection_admin: false,
+ token_owner: true,
+ },
+ }
+}
+
+fn create_refungible_collection_internal<
+ T: Config + pallet_nonfungible::Config + pallet_refungible::Config,
+>(
+ caller: caller,
+ name: string,
+ description: string,
+ token_prefix: string,
+ base_uri: string,
+ add_properties: bool,
+) -> Result<address> {
+ let (caller, name, description, token_prefix, base_uri_value) =
+ convert_data::<T>(caller, name, description, token_prefix, base_uri)?;
+ let data = make_data::<T>(
+ name,
+ CollectionMode::ReFungible,
+ description,
+ token_prefix,
+ base_uri_value,
+ add_properties,
+ )?;
+
+ let collection_id = T::CollectionDispatch::create(caller.clone(), data)
+ .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
+
+ let handle = <CollectionHandle<T>>::try_get(collection_id).map_err(dispatch_to_evm::<T>)?;
+ <PalletCommon<T>>::set_scoped_token_property_permissions(
+ &handle,
+ &caller,
+ PropertyScope::Eth,
+ vec![parent_nft_property_permissions()],
+ )
+ .map_err(dispatch_to_evm::<T>)?;
+
+ let address = pallet_common::eth::collection_id_to_address(collection_id);
+ Ok(address)
+}
+
/// @title Contract, which allows users to operate with collections
#[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]
impl<T> EvmCollectionHelpers<T>
@@ -216,27 +267,20 @@
#[weight(<SelfWeightOf<T>>::create_collection())]
fn create_refungible_collection(
- &self,
+ &mut self,
caller: caller,
name: string,
description: string,
token_prefix: string,
) -> Result<address> {
- let (caller, name, description, token_prefix, _base_uri) =
- convert_data::<T>(caller, name, description, token_prefix, "".into())?;
- let data = make_data::<T>(
+ create_refungible_collection_internal::<T>(
+ caller,
name,
- CollectionMode::ReFungible,
description,
token_prefix,
Default::default(),
false,
- )?;
- let collection_id = T::CollectionDispatch::create(caller, data)
- .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
-
- let address = pallet_common::eth::collection_id_to_address(collection_id);
- Ok(address)
+ )
}
#[weight(<SelfWeightOf<T>>::create_collection())]
@@ -249,21 +293,14 @@
token_prefix: string,
base_uri: string,
) -> Result<address> {
- let (caller, name, description, token_prefix, base_uri_value) =
- convert_data::<T>(caller, name, description, token_prefix, base_uri)?;
- let data = make_data::<T>(
+ create_refungible_collection_internal::<T>(
+ caller,
name,
- CollectionMode::NFT,
description,
token_prefix,
- base_uri_value,
+ base_uri,
true,
- )?;
- let collection_id = T::CollectionDispatch::create(caller, data)
- .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
-
- let address = pallet_common::eth::collection_id_to_address(collection_id);
- Ok(address)
+ )
}
/// Check if a collection exists
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth--- a/pallets/unique/src/eth/stubs/CollectionHelpers.sol
+++ b/pallets/unique/src/eth/stubs/CollectionHelpers.sol
@@ -72,12 +72,12 @@
string memory name,
string memory description,
string memory tokenPrefix
- ) public view returns (address) {
+ ) public returns (address) {
require(false, stub_error);
name;
description;
tokenPrefix;
- dummy;
+ dummy = 0;
return 0x0000000000000000000000000000000000000000;
}
primitives/common/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/primitives/common/Cargo.toml
@@ -0,0 +1,56 @@
+[package]
+authors = ['Unique Network <support@uniquenetwork.io>']
+description = 'Unique Runtime Common Primitives'
+edition = '2021'
+homepage = 'https://unique.network'
+license = 'All Rights Reserved'
+name = 'up-common'
+repository = 'https://github.com/UniqueNetwork/unique-chain'
+version = '0.9.24'
+
+[features]
+default = ['std']
+std = [
+ 'sp-std/std',
+ 'frame-support/std',
+ 'sp-runtime/std',
+ 'sp-core/std',
+ 'sp-consensus-aura/std',
+ 'fp-rpc/std',
+ 'pallet-evm/std',
+]
+
+[dependencies.sp-std]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.frame-support]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.sp-runtime]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.sp-core]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.sp-consensus-aura]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.fp-rpc]
+default-features = false
+git = "https://github.com/uniquenetwork/frontier"
+branch = "unique-polkadot-v0.9.24"
+
+[dependencies.pallet-evm]
+default-features = false
+git = "https://github.com/uniquenetwork/frontier"
+branch = "unique-polkadot-v0.9.24"
primitives/common/src/constants.rsdiffbeforeafterboth--- /dev/null
+++ b/primitives/common/src/constants.rs
@@ -0,0 +1,55 @@
+// 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_runtime::Perbill;
+use frame_support::{
+ parameter_types,
+ weights::{Weight, constants::WEIGHT_PER_SECOND},
+};
+use crate::types::{BlockNumber, Balance};
+
+pub const MILLISECS_PER_BLOCK: u64 = 12000;
+
+pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
+
+// These time units are defined in number of blocks.
+pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
+pub const HOURS: BlockNumber = MINUTES * 60;
+pub const DAYS: BlockNumber = HOURS * 24;
+
+pub const MICROUNIQUE: Balance = 1_000_000_000_000;
+pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE;
+pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;
+pub const UNIQUE: Balance = 100 * CENTIUNIQUE;
+
+// Targeting 0.1 UNQ per transfer
+pub const WEIGHT_TO_FEE_COEFF: u32 = 207_890_902;
+
+// Targeting 0.15 UNQ per transfer via ETH
+pub const MIN_GAS_PRICE: u64 = 1_019_493_469_850;
+
+/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
+/// This is used to limit the maximal weight of a single extrinsic.
+pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
+/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
+/// by Operational extrinsics.
+pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
+/// We allow for 2 seconds of compute with a 6 second average block time.
+pub const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2;
+
+parameter_types! {
+ pub const TransactionByteFee: Balance = 501 * MICROUNIQUE;
+}
primitives/common/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/primitives/common/src/lib.rs
@@ -0,0 +1,20 @@
+// 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)]
+
+pub mod constants;
+pub mod types;
primitives/common/src/types.rsdiffbeforeafterboth--- /dev/null
+++ b/primitives/common/src/types.rs
@@ -0,0 +1,81 @@
+// 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_runtime::{
+ generic,
+ traits::{Verify, IdentifyAccount},
+ MultiSignature,
+};
+
+/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
+/// the specifics of the runtime. They can then be made to be agnostic over specific formats
+/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
+/// to even the core data structures.
+pub mod opaque {
+ pub use sp_runtime::{generic, traits::BlakeTwo256, OpaqueExtrinsic as UncheckedExtrinsic};
+
+ pub use super::{BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId};
+
+ /// Opaque block header type.
+ pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+
+ /// Opaque block type.
+ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+
+ pub trait RuntimeInstance {
+ type CrossAccountId: pallet_evm::account::CrossAccountId<sp_runtime::AccountId32>
+ + Send
+ + Sync
+ + 'static;
+
+ type TransactionConverter: fp_rpc::ConvertTransaction<UncheckedExtrinsic>
+ + Send
+ + Sync
+ + 'static;
+
+ fn get_transaction_converter() -> Self::TransactionConverter;
+ }
+}
+
+pub type SessionHandlers = ();
+
+/// An index to a block.
+pub type BlockNumber = u32;
+
+/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
+pub type Signature = MultiSignature;
+
+/// Some way of identifying an account on the chain. We intentionally make it equivalent
+/// to the public key of our transaction signing scheme.
+pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
+
+/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
+/// never know...
+pub type AccountIndex = u32;
+
+/// Balance of an account.
+pub type Balance = u128;
+
+/// Index of a transaction in the chain.
+pub type Index = u32;
+
+/// A hash of some data used by the chain.
+pub type Hash = sp_core::H256;
+
+/// Digest item type.
+pub type DigestItem = generic::DigestItem;
+
+pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -1050,6 +1050,7 @@
pub enum PropertyScope {
None,
Rmrk,
+ Eth,
}
impl PropertyScope {
@@ -1058,6 +1059,7 @@
let scope_str: &[u8] = match self {
Self::None => return Ok(key),
Self::Rmrk => b"rmrk",
+ Self::Eth => b"eth",
};
[scope_str, b":", key.as_slice()]
runtime/common/Cargo.tomldiffbeforeafterboth--- a/runtime/common/Cargo.toml
+++ /dev/null
@@ -1,115 +0,0 @@
-[package]
-authors = ['Unique Network <support@uniquenetwork.io>']
-description = 'Unique Runtime Common'
-edition = '2021'
-homepage = 'https://unique.network'
-license = 'All Rights Reserved'
-name = 'unique-runtime-common'
-repository = 'https://github.com/UniqueNetwork/unique-chain'
-version = '0.9.24'
-
-[features]
-default = ['std']
-std = [
- 'sp-core/std',
- 'sp-std/std',
- 'sp-runtime/std',
- 'codec/std',
- 'frame-support/std',
- 'frame-system/std',
- 'sp-consensus-aura/std',
- 'pallet-common/std',
- 'pallet-unique/std',
- 'pallet-fungible/std',
- 'pallet-nonfungible/std',
- 'pallet-refungible/std',
- 'up-data-structs/std',
- 'pallet-evm/std',
- 'fp-rpc/std',
-]
-runtime-benchmarks = [
- 'sp-runtime/runtime-benchmarks',
- 'frame-support/runtime-benchmarks',
- 'frame-system/runtime-benchmarks',
-]
-
-[dependencies.sp-core]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.sp-std]
-default-features = false
-git = 'https://github.com/paritytech/substrate'
-branch = 'polkadot-v0.9.24'
-
-[dependencies.sp-runtime]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '3.1.2'
-
-[dependencies.scale-info]
-default-features = false
-features = ["derive"]
-version = "2.0.1"
-
-[dependencies.frame-support]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.frame-system]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.pallet-common]
-default-features = false
-path = "../../pallets/common"
-
-[dependencies.pallet-unique]
-default-features = false
-path = "../../pallets/unique"
-
-[dependencies.pallet-fungible]
-default-features = false
-path = "../../pallets/fungible"
-
-[dependencies.pallet-nonfungible]
-default-features = false
-path = "../../pallets/nonfungible"
-
-[dependencies.pallet-refungible]
-default-features = false
-path = "../../pallets/refungible"
-
-[dependencies.pallet-unique-scheduler]
-default-features = false
-path = "../../pallets/scheduler"
-
-[dependencies.up-data-structs]
-default-features = false
-path = "../../primitives/data-structs"
-
-[dependencies.sp-consensus-aura]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.fp-rpc]
-default-features = false
-git = "https://github.com/uniquenetwork/frontier"
-branch = "unique-polkadot-v0.9.24"
-
-[dependencies]
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
-evm-coder = { default-features = false, path = '../../crates/evm-coder' }
-up-sponsorship = { default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
-
-rmrk-rpc = { default-features = false, path = "../../primitives/rmrk-rpc" }
runtime/common/config/ethereum.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/ethereum.rs
@@ -0,0 +1,131 @@
+use sp_core::{U256, H160};
+use frame_support::{
+ weights::{Weight, constants::WEIGHT_PER_SECOND},
+ traits::{FindAuthor},
+ parameter_types, ConsensusEngineId,
+};
+use sp_runtime::{RuntimeAppPublic, Perbill};
+use crate::{
+ runtime_common::{
+ dispatch::CollectionDispatchT, ethereum::sponsoring::EvmSponsorshipHandler,
+ config::sponsoring::DefaultSponsoringRateLimit, DealWithFees,
+ },
+ Runtime, Aura, Balances, Event, ChainId,
+};
+use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping};
+use up_common::constants::*;
+
+pub type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
+
+impl pallet_evm::account::Config for Runtime {
+ type CrossAccountId = CrossAccountId;
+ type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
+ type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
+}
+
+// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
+// (contract, which only writes a lot of data),
+// approximating on top of our real store write weight
+parameter_types! {
+ pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
+ pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
+ pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
+}
+
+/// Limiting EVM execution to 50% of block for substrate users and management tasks
+/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
+/// scheduled fairly
+const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
+parameter_types! {
+ pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
+}
+
+pub enum FixedGasWeightMapping {}
+impl pallet_evm::GasWeightMapping for FixedGasWeightMapping {
+ fn gas_to_weight(gas: u64) -> Weight {
+ gas.saturating_mul(WeightPerGas::get())
+ }
+ fn weight_to_gas(weight: Weight) -> u64 {
+ weight / WeightPerGas::get()
+ }
+}
+
+pub struct FixedFee;
+impl pallet_evm::FeeCalculator for FixedFee {
+ fn min_gas_price() -> (U256, u64) {
+ (MIN_GAS_PRICE.into(), 0)
+ }
+}
+
+pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
+impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
+ fn find_author<'a, I>(digests: I) -> Option<H160>
+ where
+ I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
+ {
+ if let Some(author_index) = F::find_author(digests) {
+ let authority_id = Aura::authorities()[author_index as usize].clone();
+ return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
+ }
+ None
+ }
+}
+
+impl pallet_evm::Config for Runtime {
+ type BlockGasLimit = BlockGasLimit;
+ type FeeCalculator = FixedFee;
+ type GasWeightMapping = FixedGasWeightMapping;
+ type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
+ type CallOrigin = EnsureAddressTruncated<Self>;
+ type WithdrawOrigin = EnsureAddressTruncated<Self>;
+ type AddressMapping = HashedAddressMapping<Self::Hashing>;
+ type PrecompilesType = ();
+ type PrecompilesValue = ();
+ type Currency = Balances;
+ type Event = Event;
+ type OnMethodCall = (
+ pallet_evm_migration::OnMethodCall<Self>,
+ pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
+ CollectionDispatchT<Self>,
+ pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
+ );
+ type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
+ type ChainId = ChainId;
+ type Runner = pallet_evm::runner::stack::Runner<Self>;
+ type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
+ type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
+ type FindAuthor = EthereumFindAuthor<Aura>;
+}
+
+impl pallet_evm_migration::Config for Runtime {
+ type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
+}
+
+impl pallet_ethereum::Config for Runtime {
+ type Event = Event;
+ type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
+}
+
+parameter_types! {
+ // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
+ pub const HelpersContractAddress: H160 = H160([
+ 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
+ ]);
+
+ // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
+ pub const EvmCollectionHelpersAddress: H160 = H160([
+ 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
+ ]);
+}
+
+impl pallet_evm_contract_helpers::Config for Runtime {
+ type ContractAddress = HelpersContractAddress;
+ type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
+}
+
+impl pallet_evm_coder_substrate::Config for Runtime {}
+
+impl pallet_evm_transaction_payment::Config for Runtime {
+ type EvmSponsorshipHandler = EvmSponsorshipHandler;
+ type Currency = Balances;
+}
runtime/common/config/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/mod.rs
@@ -0,0 +1,23 @@
+// 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/>.
+
+pub mod ethereum;
+pub mod orml;
+pub mod pallets;
+pub mod parachain;
+pub mod sponsoring;
+pub mod substrate;
+pub mod xcm;
runtime/common/config/orml.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/orml.rs
@@ -0,0 +1,38 @@
+// 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 frame_support::parameter_types;
+use frame_system::EnsureSigned;
+use crate::{Runtime, Event, RelayChainBlockNumberProvider};
+use up_common::{
+ types::{AccountId, Balance},
+ constants::*,
+};
+
+parameter_types! {
+ pub const MinVestedTransfer: Balance = 10 * UNIQUE;
+ pub const MaxVestingSchedules: u32 = 28;
+}
+
+impl orml_vesting::Config for Runtime {
+ type Event = Event;
+ type Currency = pallet_balances::Pallet<Runtime>;
+ type MinVestedTransfer = MinVestedTransfer;
+ type VestedTransferOrigin = EnsureSigned<AccountId>;
+ type WeightInfo = ();
+ type MaxVestingSchedules = MaxVestingSchedules;
+ type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
+}
runtime/common/config/pallets/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/mod.rs
@@ -0,0 +1,93 @@
+// 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 frame_support::parameter_types;
+use sp_runtime::traits::AccountIdConversion;
+use crate::{
+ runtime_common::{
+ dispatch::CollectionDispatchT,
+ config::{substrate::TreasuryModuleId, ethereum::EvmCollectionHelpersAddress},
+ weights::CommonWeights,
+ RelayChainBlockNumberProvider,
+ },
+ Runtime, Event, Call, Balances,
+};
+use up_common::{
+ types::{AccountId, Balance, BlockNumber},
+ constants::*,
+};
+use up_data_structs::{
+ mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
+};
+
+#[cfg(feature = "rmrk")]
+pub mod rmrk;
+
+#[cfg(feature = "scheduler")]
+pub mod scheduler;
+
+parameter_types! {
+ pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
+ pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
+}
+
+impl pallet_common::Config for Runtime {
+ type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
+ type Event = Event;
+ type Currency = Balances;
+ type CollectionCreationPrice = CollectionCreationPrice;
+ type TreasuryAccountId = TreasuryAccountId;
+ type CollectionDispatch = CollectionDispatchT<Self>;
+
+ type EvmTokenAddressMapping = EvmTokenAddressMapping;
+ type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
+ type ContractAddress = EvmCollectionHelpersAddress;
+}
+
+impl pallet_structure::Config for Runtime {
+ type Event = Event;
+ type Call = Call;
+ type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
+}
+
+impl pallet_fungible::Config for Runtime {
+ type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
+}
+impl pallet_refungible::Config for Runtime {
+ type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
+}
+impl pallet_nonfungible::Config for Runtime {
+ type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
+}
+
+parameter_types! {
+ pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
+}
+
+/// Used for the pallet inflation
+impl pallet_inflation::Config for Runtime {
+ type Currency = Balances;
+ type TreasuryAccountId = TreasuryAccountId;
+ type InflationBlockInterval = InflationBlockInterval;
+ type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
+}
+
+impl pallet_unique::Config for Runtime {
+ type Event = Event;
+ type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
+ type CommonWeightInfo = CommonWeights<Self>;
+ type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
+}
runtime/common/config/pallets/rmrk.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/rmrk.rs
@@ -0,0 +1,27 @@
+// 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, Event};
+
+impl pallet_proxy_rmrk_core::Config for Runtime {
+ type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
+ type Event = Event;
+}
+
+impl pallet_proxy_rmrk_equip::Config for Runtime {
+ type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
+ type Event = Event;
+}
runtime/common/config/pallets/scheduler.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/scheduler.rs
@@ -0,0 +1,59 @@
+// 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 frame_support::{traits::PrivilegeCmp, weights::Weight, parameter_types};
+use frame_system::EnsureSigned;
+use sp_runtime::Perbill;
+use sp_std::cmp::Ordering;
+use crate::{
+ runtime_common::{scheduler::SchedulerPaymentExecutor, config::substrate::RuntimeBlockWeights},
+ Runtime, Call, Event, Origin, OriginCaller, Balances,
+};
+use up_common::types::AccountId;
+
+parameter_types! {
+ pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
+ RuntimeBlockWeights::get().max_block;
+ pub const MaxScheduledPerBlock: u32 = 50;
+
+ pub const NoPreimagePostponement: Option<u32> = Some(10);
+ pub const Preimage: Option<u32> = Some(10);
+}
+
+/// Used the compare the privilege of an origin inside the scheduler.
+pub struct OriginPrivilegeCmp;
+
+impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
+ fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
+ Some(Ordering::Equal)
+ }
+}
+
+impl pallet_unique_scheduler::Config for Runtime {
+ type Event = Event;
+ type Origin = Origin;
+ type Currency = Balances;
+ type PalletsOrigin = OriginCaller;
+ type Call = Call;
+ type MaximumWeight = MaximumSchedulerWeight;
+ type ScheduleOrigin = EnsureSigned<AccountId>;
+ type MaxScheduledPerBlock = MaxScheduledPerBlock;
+ type WeightInfo = ();
+ type CallExecutor = SchedulerPaymentExecutor;
+ type OriginPrivilegeCmp = OriginPrivilegeCmp;
+ type PreimageProvider = ();
+ type NoPreimagePostponement = NoPreimagePostponement;
+}
runtime/common/config/parachain.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/parachain.rs
@@ -0,0 +1,44 @@
+// 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 frame_support::{weights::Weight, parameter_types};
+use crate::{Runtime, Event, XcmpQueue, DmpQueue};
+use up_common::constants::*;
+
+parameter_types! {
+ pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
+ pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
+}
+
+impl cumulus_pallet_parachain_system::Config for Runtime {
+ type Event = Event;
+ type SelfParaId = parachain_info::Pallet<Self>;
+ type OnSystemEvent = ();
+ // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
+ // MaxDownwardMessageWeight,
+ // XcmExecutor<XcmConfig>,
+ // Call,
+ // >;
+ type OutboundXcmpMessageSource = XcmpQueue;
+ type DmpMessageHandler = DmpQueue;
+ type ReservedDmpWeight = ReservedDmpWeight;
+ type ReservedXcmpWeight = ReservedXcmpWeight;
+ type XcmpMessageHandler = XcmpQueue;
+}
+
+impl parachain_info::Config for Runtime {}
+
+impl cumulus_pallet_aura_ext::Config for Runtime {}
runtime/common/config/sponsoring.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/sponsoring.rs
@@ -0,0 +1,35 @@
+// 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 frame_support::parameter_types;
+use crate::{
+ runtime_common::{sponsoring::UniqueSponsorshipHandler},
+ Runtime,
+};
+use up_common::{types::BlockNumber, constants::*};
+
+parameter_types! {
+ pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;
+}
+
+type SponsorshipHandler = (
+ UniqueSponsorshipHandler<Runtime>,
+ pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
+);
+
+impl pallet_charge_transaction::Config for Runtime {
+ type SponsorshipHandler = SponsorshipHandler;
+}
runtime/common/config/substrate.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/substrate.rs
@@ -0,0 +1,237 @@
+// 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 frame_support::{
+ traits::{Everything, ConstU32},
+ weights::{
+ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight},
+ DispatchClass, WeightToFeePolynomial, WeightToFeeCoefficients, ConstantMultiplier,
+ WeightToFeeCoefficient,
+ },
+ parameter_types, PalletId,
+};
+use sp_runtime::{
+ generic,
+ traits::{BlakeTwo256, AccountIdLookup},
+ Perbill, Permill, Percent,
+};
+use frame_system::{
+ limits::{BlockLength, BlockWeights},
+ EnsureRoot,
+};
+use sp_arithmetic::traits::{BaseArithmetic, Unsigned};
+use smallvec::smallvec;
+use crate::{
+ runtime_common::DealWithFees, Runtime, Event, Call, Origin, PalletInfo, System, Balances,
+ Treasury, SS58Prefix, Version,
+};
+use up_common::{types::*, constants::*};
+
+parameter_types! {
+ pub const BlockHashCount: BlockNumber = 2400;
+ pub RuntimeBlockLength: BlockLength =
+ BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
+ pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
+ pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
+ pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
+ .base_block(BlockExecutionWeight::get())
+ .for_class(DispatchClass::all(), |weights| {
+ weights.base_extrinsic = ExtrinsicBaseWeight::get();
+ })
+ .for_class(DispatchClass::Normal, |weights| {
+ weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
+ })
+ .for_class(DispatchClass::Operational, |weights| {
+ weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
+ // Operational transactions have some extra reserved space, so that they
+ // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
+ weights.reserved = Some(
+ MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
+ );
+ })
+ .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
+ .build_or_panic();
+}
+
+impl frame_system::Config for Runtime {
+ /// The data to be stored in an account.
+ type AccountData = pallet_balances::AccountData<Balance>;
+ /// The identifier used to distinguish between accounts.
+ type AccountId = AccountId;
+ /// The basic call filter to use in dispatchable.
+ type BaseCallFilter = Everything;
+ /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
+ type BlockHashCount = BlockHashCount;
+ /// The maximum length of a block (in bytes).
+ type BlockLength = RuntimeBlockLength;
+ /// The index type for blocks.
+ type BlockNumber = BlockNumber;
+ /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
+ type BlockWeights = RuntimeBlockWeights;
+ /// The aggregated dispatch type that is available for extrinsics.
+ type Call = Call;
+ /// The weight of database operations that the runtime can invoke.
+ type DbWeight = RocksDbWeight;
+ /// The ubiquitous event type.
+ type Event = Event;
+ /// The type for hashing blocks and tries.
+ type Hash = Hash;
+ /// The hashing algorithm used.
+ type Hashing = BlakeTwo256;
+ /// The header type.
+ type Header = generic::Header<BlockNumber, BlakeTwo256>;
+ /// The index type for storing how many extrinsics an account has signed.
+ type Index = Index;
+ /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
+ type Lookup = AccountIdLookup<AccountId, ()>;
+ /// What to do if an account is fully reaped from the system.
+ type OnKilledAccount = ();
+ /// What to do if a new account is created.
+ type OnNewAccount = ();
+ type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
+ /// The ubiquitous origin type.
+ type Origin = Origin;
+ /// This type is being generated by `construct_runtime!`.
+ type PalletInfo = PalletInfo;
+ /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
+ type SS58Prefix = SS58Prefix;
+ /// Weight information for the extrinsics of this pallet.
+ type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
+ /// Version of the runtime.
+ type Version = Version;
+ type MaxConsumers = ConstU32<16>;
+}
+
+impl pallet_randomness_collective_flip::Config for Runtime {}
+
+parameter_types! {
+ pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
+}
+
+impl pallet_timestamp::Config for Runtime {
+ /// A timestamp: milliseconds since the unix epoch.
+ type Moment = u64;
+ type OnTimestampSet = ();
+ type MinimumPeriod = MinimumPeriod;
+ type WeightInfo = ();
+}
+
+parameter_types! {
+ // pub const ExistentialDeposit: u128 = 500;
+ pub const ExistentialDeposit: u128 = 0;
+ pub const MaxLocks: u32 = 50;
+ pub const MaxReserves: u32 = 50;
+}
+
+impl pallet_balances::Config for Runtime {
+ type MaxLocks = MaxLocks;
+ type MaxReserves = MaxReserves;
+ type ReserveIdentifier = [u8; 16];
+ /// The type for recording an account's balance.
+ type Balance = Balance;
+ /// The ubiquitous event type.
+ type Event = Event;
+ type DustRemoval = Treasury;
+ type ExistentialDeposit = ExistentialDeposit;
+ type AccountStore = System;
+ type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
+}
+
+parameter_types! {
+ /// This value increases the priority of `Operational` transactions by adding
+ /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
+ pub const OperationalFeeMultiplier: u8 = 5;
+}
+
+/// Linear implementor of `WeightToFeePolynomial`
+pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
+
+impl<T> WeightToFeePolynomial for LinearFee<T>
+where
+ T: BaseArithmetic + From<u32> + Copy + Unsigned,
+{
+ type Balance = T;
+
+ fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
+ smallvec!(WeightToFeeCoefficient {
+ coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
+ coeff_frac: Perbill::zero(),
+ negative: false,
+ degree: 1,
+ })
+ }
+}
+
+impl pallet_transaction_payment::Config for Runtime {
+ type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
+ type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
+ type OperationalFeeMultiplier = OperationalFeeMultiplier;
+ type WeightToFee = LinearFee<Balance>;
+ type FeeMultiplierUpdate = ();
+}
+
+parameter_types! {
+ pub const ProposalBond: Permill = Permill::from_percent(5);
+ pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
+ pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
+ pub const SpendPeriod: BlockNumber = 5 * MINUTES;
+ pub const Burn: Permill = Permill::from_percent(0);
+ pub const TipCountdown: BlockNumber = 1 * DAYS;
+ pub const TipFindersFee: Percent = Percent::from_percent(20);
+ pub const TipReportDepositBase: Balance = 1 * UNIQUE;
+ pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
+ pub const BountyDepositBase: Balance = 1 * UNIQUE;
+ pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
+ pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
+ pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
+ pub const MaximumReasonLength: u32 = 16384;
+ pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
+ pub const BountyValueMinimum: Balance = 5 * UNIQUE;
+ pub const MaxApprovals: u32 = 100;
+}
+
+impl pallet_treasury::Config for Runtime {
+ type PalletId = TreasuryModuleId;
+ type Currency = Balances;
+ type ApproveOrigin = EnsureRoot<AccountId>;
+ type RejectOrigin = EnsureRoot<AccountId>;
+ type Event = Event;
+ type OnSlash = ();
+ type ProposalBond = ProposalBond;
+ type ProposalBondMinimum = ProposalBondMinimum;
+ type ProposalBondMaximum = ProposalBondMaximum;
+ type SpendPeriod = SpendPeriod;
+ type Burn = Burn;
+ type BurnDestination = ();
+ type SpendFunds = ();
+ type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
+ type MaxApprovals = MaxApprovals;
+}
+
+impl pallet_sudo::Config for Runtime {
+ type Event = Event;
+ type Call = Call;
+}
+
+parameter_types! {
+ pub const MaxAuthorities: u32 = 100_000;
+}
+
+impl pallet_aura::Config for Runtime {
+ type AuthorityId = AuraId;
+ type DisabledValidators = ();
+ type MaxAuthorities = MaxAuthorities;
+}
runtime/common/config/xcm.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/xcm.rs
@@ -0,0 +1,295 @@
+// 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 frame_support::{
+ traits::{
+ tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Get, Everything,
+ },
+ weights::{Weight, WeightToFeePolynomial, WeightToFee},
+ parameter_types, match_types,
+};
+use frame_system::EnsureRoot;
+use sp_runtime::{
+ traits::{Saturating, CheckedConversion, Zero},
+ SaturatedConversion,
+};
+use pallet_xcm::XcmPassthrough;
+use polkadot_parachain::primitives::Sibling;
+use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
+use xcm::latest::{
+ AssetId::{Concrete},
+ Fungibility::Fungible as XcmFungible,
+ MultiAsset, Error as XcmError,
+};
+use xcm_executor::traits::{MatchesFungible, WeightTrader};
+use xcm_builder::{
+ AccountId32Aliases, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,
+ FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser, RelayChainAsNative,
+ SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
+ SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, ParentIsPreset,
+};
+use xcm_executor::{Config, XcmExecutor, Assets};
+use sp_std::marker::PhantomData;
+use crate::{
+ runtime_common::config::substrate::LinearFee, Runtime, Call, Event, Origin, Balances,
+ ParachainInfo, ParachainSystem, PolkadotXcm, XcmpQueue,
+};
+use up_common::{
+ types::{AccountId, Balance},
+ constants::*,
+};
+
+parameter_types! {
+ pub const RelayLocation: MultiLocation = MultiLocation::parent();
+ pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
+ pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
+ pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
+}
+
+/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
+/// when determining ownership of accounts for asset transacting and when attempting to use XCM
+/// `Transact` in order to determine the dispatch Origin.
+pub type LocationToAccountId = (
+ // The parent (Relay-chain) origin converts to the default `AccountId`.
+ ParentIsPreset<AccountId>,
+ // Sibling parachain origins convert to AccountId via the `ParaId::into`.
+ SiblingParachainConvertsVia<Sibling, AccountId>,
+ // Straight up local `AccountId32` origins just alias directly to `AccountId`.
+ AccountId32Aliases<RelayNetwork, AccountId>,
+);
+
+pub struct OnlySelfCurrency;
+impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
+ fn matches_fungible(a: &MultiAsset) -> Option<B> {
+ match (&a.id, &a.fun) {
+ (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
+ _ => None,
+ }
+ }
+}
+
+/// Means for transacting assets on this chain.
+pub type LocalAssetTransactor = CurrencyAdapter<
+ // Use this currency:
+ Balances,
+ // Use this currency when it is a fungible asset matching the given location or name:
+ OnlySelfCurrency,
+ // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
+ LocationToAccountId,
+ // Our chain's account ID type (we can't get away without mentioning it explicitly):
+ AccountId,
+ // We don't track any teleports.
+ (),
+>;
+
+/// No local origins on this chain are allowed to dispatch XCM sends/executions.
+pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
+
+/// The means for routing XCM messages which are not for local execution into the right message
+/// queues.
+pub type XcmRouter = (
+ // Two routers - use UMP to communicate with the relay chain:
+ cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
+ // ..and XCMP to communicate with the sibling chains.
+ XcmpQueue,
+);
+
+/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
+/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
+/// biases the kind of local `Origin` it will become.
+pub type XcmOriginToTransactDispatchOrigin = (
+ // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
+ // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
+ // foreign chains who want to have a local sovereign account on this chain which they control.
+ SovereignSignedViaLocation<LocationToAccountId, Origin>,
+ // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
+ // recognised.
+ RelayChainAsNative<RelayOrigin, Origin>,
+ // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
+ // recognised.
+ SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
+ // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
+ // transaction from the Root origin.
+ ParentAsSuperuser<Origin>,
+ // Native signed account converter; this just converts an `AccountId32` origin into a normal
+ // `Origin::Signed` origin of the same 32-byte value.
+ SignedAccountId32AsNative<RelayNetwork, Origin>,
+ // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
+ XcmPassthrough<Origin>,
+);
+
+parameter_types! {
+ // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
+ pub UnitWeightCost: Weight = 1_000_000;
+ // 1200 UNIQUEs buy 1 second of weight.
+ pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
+ pub const MaxInstructions: u32 = 100;
+}
+
+match_types! {
+ pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
+ MultiLocation { parents: 1, interior: Here } |
+ MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
+ };
+}
+
+pub type Barrier = (
+ TakeWeightCredit,
+ AllowTopLevelPaidExecutionFrom<Everything>,
+ // ^^^ Parent & its unit plurality gets free execution
+);
+
+pub struct UsingOnlySelfCurrencyComponents<
+ WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+ AssetId: Get<MultiLocation>,
+ AccountId,
+ Currency: CurrencyT<AccountId>,
+ OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+>(
+ Weight,
+ Currency::Balance,
+ PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
+);
+impl<
+ WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+ AssetId: Get<MultiLocation>,
+ AccountId,
+ Currency: CurrencyT<AccountId>,
+ OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+ > WeightTrader
+ for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+ fn new() -> Self {
+ Self(0, Zero::zero(), PhantomData)
+ }
+
+ fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
+ let amount = WeightToFee::weight_to_fee(&weight);
+ let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
+
+ // location to this parachain through relay chain
+ let option1: xcm::v1::AssetId = Concrete(MultiLocation {
+ parents: 1,
+ interior: X1(Parachain(ParachainInfo::parachain_id().into())),
+ });
+ // direct location
+ let option2: xcm::v1::AssetId = Concrete(MultiLocation {
+ parents: 0,
+ interior: Here,
+ });
+
+ let required = if payment.fungible.contains_key(&option1) {
+ (option1, u128_amount).into()
+ } else if payment.fungible.contains_key(&option2) {
+ (option2, u128_amount).into()
+ } else {
+ (Concrete(MultiLocation::default()), u128_amount).into()
+ };
+
+ let unused = payment
+ .checked_sub(required)
+ .map_err(|_| XcmError::TooExpensive)?;
+ self.0 = self.0.saturating_add(weight);
+ self.1 = self.1.saturating_add(amount);
+ Ok(unused)
+ }
+
+ fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
+ let weight = weight.min(self.0);
+ let amount = WeightToFee::weight_to_fee(&weight);
+ self.0 -= weight;
+ self.1 = self.1.saturating_sub(amount);
+ let amount: u128 = amount.saturated_into();
+ if amount > 0 {
+ Some((AssetId::get(), amount).into())
+ } else {
+ None
+ }
+ }
+}
+impl<
+ WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+ AssetId: Get<MultiLocation>,
+ AccountId,
+ Currency: CurrencyT<AccountId>,
+ OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+ > Drop
+ for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+ fn drop(&mut self) {
+ OnUnbalanced::on_unbalanced(Currency::issue(self.1));
+ }
+}
+
+pub struct XcmConfig;
+impl Config for XcmConfig {
+ type Call = Call;
+ type XcmSender = XcmRouter;
+ // How to withdraw and deposit an asset.
+ type AssetTransactor = LocalAssetTransactor;
+ type OriginConverter = XcmOriginToTransactDispatchOrigin;
+ type IsReserve = NativeAsset;
+ type IsTeleporter = (); // Teleportation is disabled
+ type LocationInverter = LocationInverter<Ancestry>;
+ type Barrier = Barrier;
+ type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
+ type Trader =
+ UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
+ type ResponseHandler = (); // Don't handle responses for now.
+ type SubscriptionService = PolkadotXcm;
+
+ type AssetTrap = PolkadotXcm;
+ type AssetClaims = PolkadotXcm;
+}
+
+impl pallet_xcm::Config for Runtime {
+ type Event = Event;
+ type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
+ type XcmRouter = XcmRouter;
+ type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
+ type XcmExecuteFilter = Everything;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+ type XcmTeleportFilter = Everything;
+ type XcmReserveTransferFilter = Everything;
+ type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
+ type LocationInverter = LocationInverter<Ancestry>;
+ type Origin = Origin;
+ type Call = Call;
+ const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
+ type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
+}
+
+impl cumulus_pallet_xcm::Config for Runtime {
+ type Event = Event;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+}
+
+impl cumulus_pallet_xcmp_queue::Config for Runtime {
+ type WeightInfo = ();
+ type Event = Event;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+ type ChannelInfo = ParachainSystem;
+ type VersionWrapper = ();
+ type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
+ type ControllerOrigin = EnsureRoot<AccountId>;
+ type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
+}
+
+impl cumulus_pallet_dmp_queue::Config for Runtime {
+ type Event = Event;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+ type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
+}
runtime/common/constants.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/constants.rs
@@ -0,0 +1,55 @@
+// 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_runtime::Perbill;
+use frame_support::{
+ parameter_types,
+ weights::{Weight, constants::WEIGHT_PER_SECOND},
+};
+use up_common::types::{BlockNumber, Balance};
+
+pub const MILLISECS_PER_BLOCK: u64 = 12000;
+
+pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
+
+// These time units are defined in number of blocks.
+pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
+pub const HOURS: BlockNumber = MINUTES * 60;
+pub const DAYS: BlockNumber = HOURS * 24;
+
+pub const MICROUNIQUE: Balance = 1_000_000_000_000;
+pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE;
+pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;
+pub const UNIQUE: Balance = 100 * CENTIUNIQUE;
+
+// Targeting 0.1 UNQ per transfer
+pub const WEIGHT_TO_FEE_COEFF: u32 = 207_890_902;
+
+// Targeting 0.15 UNQ per transfer via ETH
+pub const MIN_GAS_PRICE: u64 = 1_019_493_469_850;
+
+/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
+/// This is used to limit the maximal weight of a single extrinsic.
+pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
+/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
+/// by Operational extrinsics.
+pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
+/// We allow for 2 seconds of compute with a 6 second average block time.
+pub const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2;
+
+parameter_types! {
+ pub const TransactionByteFee: Balance = 501 * MICROUNIQUE;
+}
runtime/common/construct_runtime/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/construct_runtime/mod.rs
@@ -0,0 +1,90 @@
+// 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/>.
+
+mod util;
+
+#[macro_export]
+macro_rules! construct_runtime {
+ ($select_runtime:ident) => {
+ $crate::construct_runtime_impl! {
+ select_runtime($select_runtime);
+
+ pub enum Runtime where
+ Block = Block,
+ NodeBlock = opaque::Block,
+ UncheckedExtrinsic = UncheckedExtrinsic
+ {
+ ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
+ ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
+
+ Aura: pallet_aura::{Pallet, Config<T>} = 22,
+ AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
+
+ Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
+ RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
+ Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
+ TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
+ Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
+ Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
+ System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
+ Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
+ // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
+ // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
+
+ // XCM helpers.
+ XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
+ PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
+ CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
+ DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
+
+ // Unique Pallets
+ Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
+ Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
+
+ #[runtimes(opal)]
+ Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
+
+ // free = 63
+
+ Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
+ // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
+ Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
+ Fungible: pallet_fungible::{Pallet, Storage} = 67,
+
+ #[runtimes(opal)]
+ Refungible: pallet_refungible::{Pallet, Storage} = 68,
+
+ Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
+ Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
+
+ #[runtimes(opal)]
+ RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
+
+ #[runtimes(opal)]
+ RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
+
+ // Frontier
+ EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
+ Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
+
+ EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
+ EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
+ EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
+ EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
+ }
+ }
+ }
+}
runtime/common/construct_runtime/util.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/construct_runtime/util.rs
@@ -0,0 +1,222 @@
+// 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/>.
+
+#[macro_export]
+macro_rules! construct_runtime_impl {
+ (
+ select_runtime($select_runtime:ident);
+
+ pub enum Runtime where
+ $($where_ident:ident = $where_ty:ty),* $(,)?
+ {
+ $(
+ $(#[runtimes($($pallet_runtimes:ident),+ $(,)?)])?
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal
+ ),*
+ $(,)?
+ }
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime($select_runtime),
+ selected_pallets(),
+
+ where_clause($($where_ident = $where_ty),*),
+ pallets(
+ $(
+ $(#[runtimes($($pallet_runtimes),+)])?
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index
+ ),*,
+ )
+ }
+ }
+}
+
+#[macro_export]
+macro_rules! construct_runtime_helper {
+ (
+ select_runtime($select_runtime:ident),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ #[runtimes($($pallet_runtimes:ident),+)]
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::add_runtime_specific_pallets! {
+ select_runtime($select_runtime),
+ runtimes($($pallet_runtimes),+,),
+ selected_pallets($($selected_pallets)*),
+
+ where_clause($($where_clause)*),
+ pallets(
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ $($pallets_tl)*
+ )
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime($select_runtime),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets()
+ ) => {
+ frame_support::construct_runtime! {
+ pub enum Runtime where
+ $($where_clause)*
+ {
+ $($selected_pallets)*
+ }
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! add_runtime_specific_pallets {
+ (
+ select_runtime(opal),
+ runtimes(opal, $($_runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime(opal),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime(quartz),
+ runtimes(quartz, $($_runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime(quartz),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime(unique),
+ runtimes(unique, $($_runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime(unique),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ runtimes($_current_runtime:ident, $($runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets($($pallets:tt)*)
+ ) => {
+ $crate::add_runtime_specific_pallets! {
+ select_runtime($select_runtime),
+ runtimes($($runtime_tl)*),
+ selected_pallets($($selected_pallets)*),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets)*)
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ runtimes(),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $_pallet_name:ident: $_pallet_mod:ident::{$($_pallet_parts:ty),*} = $_index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime($select_runtime),
+ selected_pallets($($selected_pallets)*),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+}
runtime/common/dispatch.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/dispatch.rs
@@ -0,0 +1,189 @@
+// 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 frame_support::{dispatch::DispatchResult, ensure};
+use pallet_evm::{PrecompileHandle, PrecompileResult};
+use sp_core::H160;
+use sp_runtime::DispatchError;
+use sp_std::{borrow::ToOwned, vec::Vec};
+use pallet_common::{
+ CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,
+ eth::map_eth_to_id,
+};
+pub use pallet_common::dispatch::CollectionDispatch;
+use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};
+use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};
+use pallet_refungible::{
+ Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,
+};
+use up_data_structs::{
+ CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,
+ CollectionId,
+};
+
+#[cfg(not(feature = "refungible"))]
+use pallet_common::unsupported;
+
+pub enum CollectionDispatchT<T>
+where
+ T: pallet_fungible::Config + pallet_nonfungible::Config + pallet_refungible::Config,
+{
+ Fungible(FungibleHandle<T>),
+ Nonfungible(NonfungibleHandle<T>),
+ Refungible(RefungibleHandle<T>),
+}
+impl<T> CollectionDispatch<T> for CollectionDispatchT<T>
+where
+ T: pallet_common::Config
+ + pallet_unique::Config
+ + pallet_fungible::Config
+ + pallet_nonfungible::Config
+ + pallet_refungible::Config,
+{
+ fn create(
+ sender: T::CrossAccountId,
+ data: CreateCollectionData<T::AccountId>,
+ ) -> Result<CollectionId, DispatchError> {
+ let id = match data.mode {
+ CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data, false)?,
+ CollectionMode::Fungible(decimal_points) => {
+ // check params
+ ensure!(
+ decimal_points <= MAX_DECIMAL_POINTS,
+ pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded
+ );
+ <PalletFungible<T>>::init_collection(sender, data)?
+ }
+
+ #[cfg(feature = "refungible")]
+ CollectionMode::ReFungible => <PalletRefungible<T>>::init_collection(sender, data)?,
+
+ #[cfg(not(feature = "refungible"))]
+ CollectionMode::ReFungible => return unsupported!(T),
+ };
+ Ok(id)
+ }
+
+ fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {
+ match collection.mode {
+ CollectionMode::ReFungible => {
+ PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?
+ }
+ CollectionMode::Fungible(_) => {
+ PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?
+ }
+ CollectionMode::NFT => {
+ PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?
+ }
+ }
+ Ok(())
+ }
+
+ fn dispatch(handle: CollectionHandle<T>) -> Self {
+ match handle.mode {
+ CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),
+ CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),
+ CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),
+ }
+ }
+
+ fn into_inner(self) -> CollectionHandle<T> {
+ match self {
+ Self::Fungible(f) => f.into_inner(),
+ Self::Nonfungible(f) => f.into_inner(),
+ Self::Refungible(f) => f.into_inner(),
+ }
+ }
+
+ fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
+ match self {
+ Self::Fungible(h) => h,
+ Self::Nonfungible(h) => h,
+ Self::Refungible(h) => h,
+ }
+ }
+}
+
+impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>
+where
+ T: pallet_common::Config
+ + pallet_unique::Config
+ + pallet_fungible::Config
+ + pallet_nonfungible::Config
+ + pallet_refungible::Config,
+ T::AccountId: From<[u8; 32]>,
+{
+ fn is_reserved(target: &H160) -> bool {
+ map_eth_to_id(target).is_some()
+ }
+ fn is_used(target: &H160) -> bool {
+ map_eth_to_id(target)
+ .map(<CollectionById<T>>::contains_key)
+ .unwrap_or(false)
+ }
+ fn get_code(target: &H160) -> Option<Vec<u8>> {
+ if let Some(collection_id) = map_eth_to_id(target) {
+ let collection = <CollectionById<T>>::get(collection_id)?;
+ Some(
+ match collection.mode {
+ CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,
+ CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,
+ CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,
+ }
+ .to_owned(),
+ )
+ } else if let Some((collection_id, _token_id)) =
+ <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)
+ {
+ let collection = <CollectionById<T>>::get(collection_id)?;
+ if collection.mode != CollectionMode::ReFungible {
+ return None;
+ }
+ // TODO: check token existence
+ Some(<RefungibleTokenHandle<T>>::CODE.to_owned())
+ } else {
+ None
+ }
+ }
+ fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
+ if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {
+ let collection =
+ <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
+ let dispatched = Self::dispatch(collection);
+
+ match dispatched {
+ Self::Fungible(h) => h.call(handle),
+ Self::Nonfungible(h) => h.call(handle),
+ Self::Refungible(h) => h.call(handle),
+ }
+ } else if let Some((collection_id, token_id)) =
+ <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
+ &handle.code_address(),
+ ) {
+ let collection =
+ <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
+ if collection.mode != CollectionMode::ReFungible {
+ return None;
+ }
+
+ let h = RefungibleHandle::cast(collection);
+ // TODO: check token existence
+ RefungibleTokenHandle(h, token_id).call(handle)
+ } else {
+ None
+ }
+ }
+}
runtime/common/ethereum/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/mod.rs
@@ -0,0 +1,19 @@
+// 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/>.
+
+pub mod self_contained_call;
+pub mod sponsoring;
+pub mod transaction_converter;
runtime/common/ethereum/self_contained_call.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/self_contained_call.rs
@@ -0,0 +1,74 @@
+// 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_core::H160;
+use sp_runtime::{
+ traits::{Dispatchable, DispatchInfoOf, PostDispatchInfoOf},
+ transaction_validity::{TransactionValidityError, TransactionValidity},
+};
+use crate::{Origin, Call};
+
+impl fp_self_contained::SelfContainedCall for Call {
+ type SignedInfo = H160;
+
+ fn is_self_contained(&self) -> bool {
+ match self {
+ Call::Ethereum(call) => call.is_self_contained(),
+ _ => false,
+ }
+ }
+
+ fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
+ match self {
+ Call::Ethereum(call) => call.check_self_contained(),
+ _ => None,
+ }
+ }
+
+ fn validate_self_contained(
+ &self,
+ info: &Self::SignedInfo,
+ dispatch_info: &DispatchInfoOf<Call>,
+ len: usize,
+ ) -> Option<TransactionValidity> {
+ match self {
+ Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
+ _ => None,
+ }
+ }
+
+ fn pre_dispatch_self_contained(
+ &self,
+ info: &Self::SignedInfo,
+ ) -> Option<Result<(), TransactionValidityError>> {
+ match self {
+ Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
+ _ => None,
+ }
+ }
+
+ fn apply_self_contained(
+ self,
+ info: Self::SignedInfo,
+ ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
+ match self {
+ call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
+ Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
+ )),
+ _ => None,
+ }
+ }
+}
runtime/common/ethereum/sponsoring.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/sponsoring.rs
@@ -0,0 +1,127 @@
+// 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/>.
+
+//! Implements EVM sponsoring logic via TransactionValidityHack
+
+use evm_coder::{Call, abi::AbiReader};
+use pallet_common::{CollectionHandle, eth::map_eth_to_id};
+use sp_core::H160;
+use sp_std::prelude::*;
+use up_sponsorship::SponsorshipHandler;
+use core::marker::PhantomData;
+use core::convert::TryInto;
+use pallet_evm::account::CrossAccountId;
+use up_data_structs::{TokenId, CreateItemData, CreateNftData, CollectionMode};
+use pallet_unique::Config as UniqueConfig;
+
+use crate::{Runtime, runtime_common::sponsoring::*};
+
+use pallet_nonfungible::erc::{
+ UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call, TokenPropertiesCall,
+};
+use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
+use pallet_fungible::Config as FungibleConfig;
+use pallet_nonfungible::Config as NonfungibleConfig;
+use pallet_refungible::Config as RefungibleConfig;
+
+pub type EvmSponsorshipHandler = (
+ UniqueEthSponsorshipHandler<Runtime>,
+ pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
+);
+
+pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);
+impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>
+ SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T>
+{
+ fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {
+ let collection_id = map_eth_to_id(&call.0)?;
+ let collection = <CollectionHandle<T>>::new(collection_id)?;
+ let sponsor = collection.sponsorship.sponsor()?.clone();
+ let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
+ Some(T::CrossAccountId::from_sub(match &collection.mode {
+ CollectionMode::NFT => {
+ let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
+ match call {
+ UniqueNFTCall::TokenProperties(TokenPropertiesCall::SetProperty {
+ token_id,
+ key,
+ value,
+ ..
+ }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_set_token_property::<T>(
+ &collection,
+ &who,
+ &token_id,
+ key.len() + value.len(),
+ )
+ .map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721UniqueExtensions(
+ ERC721UniqueExtensionsCall::Transfer { token_id, .. },
+ ) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721Mintable(
+ ERC721MintableCall::Mint { token_id, .. }
+ | ERC721MintableCall::MintWithTokenUri { token_id, .. },
+ ) => {
+ let _token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_create_item::<T>(
+ &collection,
+ &who,
+ &CreateItemData::NFT(CreateNftData::default()),
+ )
+ .map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, from, .. }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ let from = T::CrossAccountId::from_eth(from);
+ withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
+ .map(|()| sponsor)
+ }
+ _ => None,
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
+ #[allow(clippy::single_match)]
+ match call {
+ UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
+ withdraw_transfer::<T>(&collection, who, &TokenId::default())
+ .map(|()| sponsor)
+ }
+ UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {
+ let from = T::CrossAccountId::from_eth(from);
+ withdraw_transfer::<T>(&collection, &from, &TokenId::default())
+ .map(|()| sponsor)
+ }
+ UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
+ withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())
+ .map(|()| sponsor)
+ }
+ _ => None,
+ }
+ }
+ _ => None,
+ }?))
+ }
+}
runtime/common/ethereum/transaction_converter.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/transaction_converter.rs
@@ -0,0 +1,42 @@
+// 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 codec::{Encode, Decode};
+use crate::{opaque, Runtime, UncheckedExtrinsic};
+
+pub struct TransactionConverter;
+
+impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
+ fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
+ UncheckedExtrinsic::new_unsigned(
+ pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
+ )
+ }
+}
+
+impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
+ fn convert_transaction(
+ &self,
+ transaction: pallet_ethereum::Transaction,
+ ) -> opaque::UncheckedExtrinsic {
+ let extrinsic = UncheckedExtrinsic::new_unsigned(
+ pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
+ );
+ let encoded = extrinsic.encode();
+ opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
+ .expect("Encoded extrinsic is always valid")
+ }
+}
runtime/common/instance.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/instance.rs
@@ -0,0 +1,16 @@
+use crate::{
+ runtime_common::{
+ config::ethereum::CrossAccountId, ethereum::transaction_converter::TransactionConverter,
+ },
+ Runtime,
+};
+use up_common::types::opaque::RuntimeInstance;
+
+impl RuntimeInstance for Runtime {
+ type CrossAccountId = CrossAccountId;
+ type TransactionConverter = TransactionConverter;
+
+ fn get_transaction_converter() -> TransactionConverter {
+ TransactionConverter
+ }
+}
runtime/common/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/mod.rs
@@ -0,0 +1,168 @@
+// 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/>.
+
+pub mod config;
+pub mod constants;
+pub mod construct_runtime;
+pub mod dispatch;
+pub mod ethereum;
+pub mod instance;
+pub mod runtime_apis;
+pub mod scheduler;
+pub mod sponsoring;
+pub mod weights;
+
+use sp_core::H160;
+use frame_support::traits::{Currency, OnUnbalanced, Imbalance};
+use sp_runtime::{
+ generic,
+ traits::{BlakeTwo256, BlockNumberProvider},
+ impl_opaque_keys,
+};
+use sp_std::vec::Vec;
+
+#[cfg(feature = "std")]
+use sp_version::NativeVersion;
+
+use crate::{
+ Runtime, Call, Balances, Treasury, Aura, Signature, AllPalletsReversedWithSystemFirst,
+ InherentDataExt,
+};
+use up_common::types::{AccountId, BlockNumber};
+
+#[macro_export]
+macro_rules! unsupported {
+ () => {
+ pallet_common::unsupported!($crate::Runtime)
+ };
+}
+
+/// The address format for describing accounts.
+pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
+/// Block header type as expected by this runtime.
+pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+/// Block type as expected by this runtime.
+pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+/// A Block signed with a Justification
+pub type SignedBlock = generic::SignedBlock<Block>;
+/// BlockId type as expected by this runtime.
+pub type BlockId = generic::BlockId<Block>;
+
+impl_opaque_keys! {
+ pub struct SessionKeys {
+ pub aura: Aura,
+ }
+}
+
+/// The version information used to identify this runtime when compiled natively.
+#[cfg(feature = "std")]
+pub fn native_version() -> NativeVersion {
+ NativeVersion {
+ runtime_version: crate::VERSION,
+ can_author_with: Default::default(),
+ }
+}
+
+pub type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
+
+pub type SignedExtra = (
+ frame_system::CheckSpecVersion<Runtime>,
+ // system::CheckTxVersion<Runtime>,
+ frame_system::CheckGenesis<Runtime>,
+ frame_system::CheckEra<Runtime>,
+ frame_system::CheckNonce<Runtime>,
+ frame_system::CheckWeight<Runtime>,
+ ChargeTransactionPayment,
+ //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
+ pallet_ethereum::FakeTransactionFinalizer<Runtime>,
+);
+
+/// Unchecked extrinsic type as expected by this runtime.
+pub type UncheckedExtrinsic =
+ fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
+
+/// Extrinsic type that has already been checked.
+pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
+
+/// Executive: handles dispatch to the various modules.
+pub type Executive = frame_executive::Executive<
+ Runtime,
+ Block,
+ frame_system::ChainContext<Runtime>,
+ Runtime,
+ AllPalletsReversedWithSystemFirst,
+>;
+
+type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
+
+pub struct DealWithFees;
+impl OnUnbalanced<NegativeImbalance> for DealWithFees {
+ fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
+ if let Some(fees) = fees_then_tips.next() {
+ // for fees, 100% to treasury
+ let mut split = fees.ration(100, 0);
+ if let Some(tips) = fees_then_tips.next() {
+ // for tips, if any, 100% to treasury
+ tips.ration_merge_into(100, 0, &mut split);
+ }
+ Treasury::on_unbalanced(split.0);
+ // Author::on_unbalanced(split.1);
+ }
+ }
+}
+
+pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
+
+impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
+ for RelayChainBlockNumberProvider<T>
+{
+ type BlockNumber = BlockNumber;
+
+ fn current_block_number() -> Self::BlockNumber {
+ cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
+ .map(|d| d.relay_parent_number)
+ .unwrap_or_default()
+ }
+}
+
+pub(crate) struct CheckInherents;
+
+impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
+ fn check_inherents(
+ block: &Block,
+ relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
+ ) -> sp_inherents::CheckInherentsResult {
+ let relay_chain_slot = relay_state_proof
+ .read_slot()
+ .expect("Could not read the relay chain slot from the proof");
+
+ let inherent_data =
+ cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
+ relay_chain_slot,
+ sp_std::time::Duration::from_secs(6),
+ )
+ .create_inherent_data()
+ .expect("Could not create the timestamp inherent data");
+
+ inherent_data.check_extrinsics(block)
+ }
+}
+
+#[derive(codec::Encode, codec::Decode)]
+pub enum XCMPMessage<XAccountId, XBalance> {
+ /// Transfer tokens to the given account from the Parachain account.
+ TransferToken(XAccountId, XBalance),
+}
runtime/common/runtime_apis.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/runtime_apis.rs
@@ -0,0 +1,724 @@
+// 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/>.
+
+#[macro_export]
+macro_rules! dispatch_unique_runtime {
+ ($collection:ident.$method:ident($($name:ident),*)) => {{
+ let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
+ let dispatch = collection.as_dyn();
+
+ Ok::<_, DispatchError>(dispatch.$method($($name),*))
+ }};
+}
+
+#[macro_export]
+macro_rules! impl_common_runtime_apis {
+ (
+ $(
+ #![custom_apis]
+
+ $($custom_apis:tt)+
+ )?
+ ) => {
+ use sp_std::prelude::*;
+ use sp_api::impl_runtime_apis;
+ use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};
+ use sp_runtime::{
+ Permill,
+ traits::Block as BlockT,
+ transaction_validity::{TransactionSource, TransactionValidity},
+ ApplyExtrinsicResult, DispatchError,
+ };
+ use fp_rpc::TransactionStatus;
+ use pallet_transaction_payment::{
+ FeeDetails, RuntimeDispatchInfo,
+ };
+ use pallet_evm::{
+ Runner, account::CrossAccountId as _,
+ Account as EVMAccount, FeeCalculator,
+ };
+ use runtime_common::{
+ sponsoring::{SponsorshipPredict, UniqueSponsorshipPredict},
+ dispatch::CollectionDispatch,
+ config::ethereum::CrossAccountId,
+ };
+ use up_data_structs::*;
+
+
+ impl_runtime_apis! {
+ $($($custom_apis)+)?
+
+ impl up_rpc::UniqueApi<Block, CrossAccountId, AccountId> for Runtime {
+ fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>, DispatchError> {
+ dispatch_unique_runtime!(collection.account_tokens(account))
+ }
+ fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>, DispatchError> {
+ dispatch_unique_runtime!(collection.collection_tokens())
+ }
+ fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool, DispatchError> {
+ dispatch_unique_runtime!(collection.token_exists(token))
+ }
+
+ fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
+ dispatch_unique_runtime!(collection.token_owner(token))
+ }
+
+ fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec::<CrossAccountId>, DispatchError> {
+ dispatch_unique_runtime!(collection.token_owners(token))
+ }
+
+ fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
+ let budget = up_data_structs::budget::Value::new(10);
+
+ Ok(Some(<pallet_structure::Pallet<Runtime>>::find_topmost_owner(collection, token, &budget)?))
+ }
+ fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>, DispatchError> {
+ Ok(<pallet_nonfungible::Pallet<Runtime>>::token_children_ids(collection, token))
+ }
+ fn collection_properties(
+ collection: CollectionId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<Vec<Property>, DispatchError> {
+ let keys = keys.map(
+ |keys| Common::bytes_keys_to_property_keys(keys)
+ ).transpose()?;
+
+ Common::filter_collection_properties(collection, keys)
+ }
+
+ fn token_properties(
+ collection: CollectionId,
+ token_id: TokenId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<Vec<Property>, DispatchError> {
+ let keys = keys.map(
+ |keys| Common::bytes_keys_to_property_keys(keys)
+ ).transpose()?;
+
+ dispatch_unique_runtime!(collection.token_properties(token_id, keys))
+ }
+
+ fn property_permissions(
+ collection: CollectionId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
+ let keys = keys.map(
+ |keys| Common::bytes_keys_to_property_keys(keys)
+ ).transpose()?;
+
+ Common::filter_property_permissions(collection, keys)
+ }
+
+ fn token_data(
+ collection: CollectionId,
+ token_id: TokenId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<TokenData<CrossAccountId>, DispatchError> {
+ let token_data = TokenData {
+ properties: Self::token_properties(collection, token_id, keys)?,
+ owner: Self::token_owner(collection, token_id)?,
+ pieces: Self::total_pieces(collection, token_id)?.unwrap_or(0),
+ };
+
+ Ok(token_data)
+ }
+
+ fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {
+ dispatch_unique_runtime!(collection.total_supply())
+ }
+ fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {
+ dispatch_unique_runtime!(collection.account_balance(account))
+ }
+ fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {
+ dispatch_unique_runtime!(collection.balance(account, token))
+ }
+ fn allowance(
+ collection: CollectionId,
+ sender: CrossAccountId,
+ spender: CrossAccountId,
+ token: TokenId,
+ ) -> Result<u128, DispatchError> {
+ dispatch_unique_runtime!(collection.allowance(sender, spender, token))
+ }
+
+ fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))
+ }
+ fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))
+ }
+ fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))
+ }
+ fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {
+ dispatch_unique_runtime!(collection.last_token_id())
+ }
+ fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::rpc_collection(collection))
+ }
+ fn collection_stats() -> Result<CollectionStats, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::collection_stats())
+ }
+ fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {
+ Ok(<UniqueSponsorshipPredict<Runtime> as SponsorshipPredict<Runtime>>::predict(
+ collection,
+ account,
+ token
+ ))
+ }
+
+ fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))
+ }
+
+ fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
+ dispatch_unique_runtime!(collection.total_pieces(token_id))
+ }
+ }
+
+ 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
+ }
+
+ fn execute_block(block: Block) {
+ Executive::execute_block(block)
+ }
+
+ fn initialize_block(header: &<Block as BlockT>::Header) {
+ Executive::initialize_block(header)
+ }
+ }
+
+ impl sp_api::Metadata<Block> for Runtime {
+ fn metadata() -> OpaqueMetadata {
+ OpaqueMetadata::new(Runtime::metadata().into())
+ }
+ }
+
+ impl sp_block_builder::BlockBuilder<Block> for Runtime {
+ fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
+ Executive::apply_extrinsic(extrinsic)
+ }
+
+ fn finalize_block() -> <Block as BlockT>::Header {
+ Executive::finalize_block()
+ }
+
+ fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
+ data.create_extrinsics()
+ }
+
+ fn check_inherents(
+ block: Block,
+ data: sp_inherents::InherentData,
+ ) -> sp_inherents::CheckInherentsResult {
+ data.check_extrinsics(&block)
+ }
+
+ // fn random_seed() -> <Block as BlockT>::Hash {
+ // RandomnessCollectiveFlip::random_seed().0
+ // }
+ }
+
+ impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
+ fn validate_transaction(
+ source: TransactionSource,
+ tx: <Block as BlockT>::Extrinsic,
+ hash: <Block as BlockT>::Hash,
+ ) -> TransactionValidity {
+ Executive::validate_transaction(source, tx, hash)
+ }
+ }
+
+ impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
+ fn offchain_worker(header: &<Block as BlockT>::Header) {
+ Executive::offchain_worker(header)
+ }
+ }
+
+ impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
+ fn chain_id() -> u64 {
+ <Runtime as pallet_evm::Config>::ChainId::get()
+ }
+
+ fn account_basic(address: H160) -> EVMAccount {
+ let (account, _) = EVM::account_basic(&address);
+ account
+ }
+
+ fn gas_price() -> U256 {
+ let (price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
+ price
+ }
+
+ fn account_code_at(address: H160) -> Vec<u8> {
+ EVM::account_codes(address)
+ }
+
+ fn author() -> H160 {
+ <pallet_evm::Pallet<Runtime>>::find_author()
+ }
+
+ fn storage_at(address: H160, index: U256) -> H256 {
+ let mut tmp = [0u8; 32];
+ index.to_big_endian(&mut tmp);
+ EVM::account_storages(address, H256::from_slice(&tmp[..]))
+ }
+
+ #[allow(clippy::redundant_closure)]
+ fn call(
+ from: H160,
+ to: H160,
+ data: Vec<u8>,
+ value: U256,
+ gas_limit: U256,
+ max_fee_per_gas: Option<U256>,
+ max_priority_fee_per_gas: Option<U256>,
+ nonce: Option<U256>,
+ estimate: bool,
+ access_list: Option<Vec<(H160, Vec<H256>)>>,
+ ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
+ let config = if estimate {
+ let mut config = <Runtime as pallet_evm::Config>::config().clone();
+ config.estimate = true;
+ Some(config)
+ } else {
+ None
+ };
+
+ let is_transactional = false;
+ <Runtime as pallet_evm::Config>::Runner::call(
+ CrossAccountId::from_eth(from),
+ to,
+ data,
+ value,
+ gas_limit.low_u64(),
+ max_fee_per_gas,
+ max_priority_fee_per_gas,
+ nonce,
+ access_list.unwrap_or_default(),
+ is_transactional,
+ config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
+ ).map_err(|err| err.error.into())
+ }
+
+ #[allow(clippy::redundant_closure)]
+ fn create(
+ from: H160,
+ data: Vec<u8>,
+ value: U256,
+ gas_limit: U256,
+ max_fee_per_gas: Option<U256>,
+ max_priority_fee_per_gas: Option<U256>,
+ nonce: Option<U256>,
+ estimate: bool,
+ access_list: Option<Vec<(H160, Vec<H256>)>>,
+ ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
+ let config = if estimate {
+ let mut config = <Runtime as pallet_evm::Config>::config().clone();
+ config.estimate = true;
+ Some(config)
+ } else {
+ None
+ };
+
+ let is_transactional = false;
+ <Runtime as pallet_evm::Config>::Runner::create(
+ CrossAccountId::from_eth(from),
+ data,
+ value,
+ gas_limit.low_u64(),
+ max_fee_per_gas,
+ max_priority_fee_per_gas,
+ nonce,
+ access_list.unwrap_or_default(),
+ is_transactional,
+ config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
+ ).map_err(|err| err.error.into())
+ }
+
+ fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {
+ Ethereum::current_transaction_statuses()
+ }
+
+ fn current_block() -> Option<pallet_ethereum::Block> {
+ Ethereum::current_block()
+ }
+
+ fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
+ Ethereum::current_receipts()
+ }
+
+ fn current_all() -> (
+ Option<pallet_ethereum::Block>,
+ Option<Vec<pallet_ethereum::Receipt>>,
+ Option<Vec<TransactionStatus>>
+ ) {
+ (
+ Ethereum::current_block(),
+ Ethereum::current_receipts(),
+ Ethereum::current_transaction_statuses()
+ )
+ }
+
+ fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {
+ xts.into_iter().filter_map(|xt| match xt.0.function {
+ Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
+ _ => None
+ }).collect()
+ }
+
+ fn elasticity() -> Option<Permill> {
+ None
+ }
+ }
+
+ impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
+ fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {
+ UncheckedExtrinsic::new_unsigned(
+ pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
+ )
+ }
+ }
+
+ impl sp_session::SessionKeys<Block> for Runtime {
+ fn decode_session_keys(
+ encoded: Vec<u8>,
+ ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
+ SessionKeys::decode_into_raw_public_keys(&encoded)
+ }
+
+ fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
+ SessionKeys::generate(seed)
+ }
+ }
+
+ impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
+ fn slot_duration() -> sp_consensus_aura::SlotDuration {
+ sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
+ }
+
+ fn authorities() -> Vec<AuraId> {
+ Aura::authorities().to_vec()
+ }
+ }
+
+ impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
+ fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
+ ParachainSystem::collect_collation_info(header)
+ }
+ }
+
+ impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
+ fn account_nonce(account: AccountId) -> Index {
+ System::account_nonce(account)
+ }
+ }
+
+ impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
+ fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
+ TransactionPayment::query_info(uxt, len)
+ }
+ fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
+ TransactionPayment::query_fee_details(uxt, len)
+ }
+ }
+
+ /*
+ impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>
+ for Runtime
+ {
+ fn call(
+ origin: AccountId,
+ dest: AccountId,
+ value: Balance,
+ gas_limit: u64,
+ input_data: Vec<u8>,
+ ) -> pallet_contracts_primitives::ContractExecResult {
+ Contracts::bare_call(origin, dest, value, gas_limit, input_data, false)
+ }
+
+ fn instantiate(
+ origin: AccountId,
+ endowment: Balance,
+ gas_limit: u64,
+ code: pallet_contracts_primitives::Code<Hash>,
+ data: Vec<u8>,
+ salt: Vec<u8>,
+ ) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>
+ {
+ Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false)
+ }
+
+ fn get_storage(
+ address: AccountId,
+ key: [u8; 32],
+ ) -> pallet_contracts_primitives::GetStorageResult {
+ Contracts::get_storage(address, key)
+ }
+
+ fn rent_projection(
+ address: AccountId,
+ ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
+ Contracts::rent_projection(address)
+ }
+ }
+ */
+
+ #[cfg(feature = "runtime-benchmarks")]
+ impl frame_benchmarking::Benchmark<Block> for Runtime {
+ fn benchmark_metadata(extra: bool) -> (
+ Vec<frame_benchmarking::BenchmarkList>,
+ Vec<frame_support::traits::StorageInfo>,
+ ) {
+ use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};
+ use frame_support::traits::StorageInfoTrait;
+
+ let mut list = Vec::<BenchmarkList>::new();
+
+ list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);
+ list_benchmark!(list, extra, pallet_common, Common);
+ list_benchmark!(list, extra, pallet_unique, Unique);
+ list_benchmark!(list, extra, pallet_structure, Structure);
+ list_benchmark!(list, extra, pallet_inflation, Inflation);
+ list_benchmark!(list, extra, pallet_fungible, Fungible);
+ list_benchmark!(list, extra, pallet_refungible, Refungible);
+ list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);
+ list_benchmark!(list, extra, pallet_unique_scheduler, Scheduler);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ list_benchmark!(list, extra, pallet_proxy_rmrk_core, RmrkCore);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ list_benchmark!(list, extra, pallet_proxy_rmrk_equip, RmrkEquip);
+
+ // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate);
+
+ let storage_info = AllPalletsReversedWithSystemFirst::storage_info();
+
+ return (list, storage_info)
+ }
+
+ fn dispatch_benchmark(
+ config: frame_benchmarking::BenchmarkConfig
+ ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
+ use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};
+
+ let allowlist: Vec<TrackedStorageKey> = vec![
+ // Total Issuance
+ hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
+
+ // Block Number
+ hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
+ // Execution Phase
+ hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),
+ // Event Count
+ hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),
+ // System Events
+ hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),
+
+ // Evm CurrentLogs
+ hex_literal::hex!("1da53b775b270400e7e61ed5cbc5a146547f210cec367e9af919603343b9cb56").to_vec().into(),
+
+ // Transactional depth
+ hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),
+ ];
+
+ let mut batches = Vec::<BenchmarkBatch>::new();
+ let params = (&config, &allowlist);
+
+ add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);
+ add_benchmark!(params, batches, pallet_common, Common);
+ add_benchmark!(params, batches, pallet_unique, Unique);
+ add_benchmark!(params, batches, pallet_structure, Structure);
+ add_benchmark!(params, batches, pallet_inflation, Inflation);
+ add_benchmark!(params, batches, pallet_fungible, Fungible);
+ add_benchmark!(params, batches, pallet_refungible, Refungible);
+ add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);
+ add_benchmark!(params, batches, pallet_unique_scheduler, Scheduler);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ add_benchmark!(params, batches, pallet_proxy_rmrk_core, RmrkCore);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ add_benchmark!(params, batches, pallet_proxy_rmrk_equip, RmrkEquip);
+
+ // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);
+
+ if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
+ Ok(batches)
+ }
+ }
+
+ #[cfg(feature = "try-runtime")]
+ impl frame_try_runtime::TryRuntime<Block> for Runtime {
+ fn on_runtime_upgrade() -> (Weight, Weight) {
+ log::info!("try-runtime::on_runtime_upgrade unique-chain.");
+ let weight = Executive::try_runtime_upgrade().unwrap();
+ (weight, RuntimeBlockWeights::get().max_block)
+ }
+
+ fn execute_block_no_check(block: Block) -> Weight {
+ Executive::execute_block_no_check(block)
+ }
+ }
+ }
+ }
+}
runtime/common/scheduler.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/scheduler.rs
@@ -0,0 +1,141 @@
+// 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 frame_support::{
+ traits::NamedReservableCurrency,
+ weights::{GetDispatchInfo, PostDispatchInfo, DispatchInfo},
+};
+use sp_runtime::{
+ traits::{Dispatchable, Applyable, Member},
+ generic::Era,
+ transaction_validity::TransactionValidityError,
+ DispatchErrorWithPostInfo, DispatchError,
+};
+use crate::{Runtime, Call, Origin, Balances, ChargeTransactionPayment};
+use up_common::types::{AccountId, Balance};
+use fp_self_contained::SelfContainedCall;
+use pallet_unique_scheduler::DispatchCall;
+
+/// The SignedExtension to the basic transaction logic.
+pub type SignedExtraScheduler = (
+ frame_system::CheckSpecVersion<Runtime>,
+ frame_system::CheckGenesis<Runtime>,
+ frame_system::CheckEra<Runtime>,
+ frame_system::CheckNonce<Runtime>,
+ frame_system::CheckWeight<Runtime>,
+);
+
+fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
+ (
+ frame_system::CheckSpecVersion::<Runtime>::new(),
+ frame_system::CheckGenesis::<Runtime>::new(),
+ frame_system::CheckEra::<Runtime>::from(Era::Immortal),
+ frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
+ from,
+ )),
+ frame_system::CheckWeight::<Runtime>::new(),
+ // sponsoring transaction logic
+ // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
+ )
+}
+
+pub struct SchedulerPaymentExecutor;
+
+impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
+ DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
+where
+ <T as frame_system::Config>::Call: Member
+ + Dispatchable<Origin = Origin, Info = DispatchInfo>
+ + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
+ + GetDispatchInfo
+ + From<frame_system::Call<Runtime>>,
+ SelfContainedSignedInfo: Send + Sync + 'static,
+ Call: From<<T as frame_system::Config>::Call>
+ + From<<T as pallet_unique_scheduler::Config>::Call>
+ + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
+ sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
+{
+ fn dispatch_call(
+ signer: <T as frame_system::Config>::AccountId,
+ call: <T as pallet_unique_scheduler::Config>::Call,
+ ) -> Result<
+ Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
+ TransactionValidityError,
+ > {
+ let dispatch_info = call.get_dispatch_info();
+ let extrinsic = fp_self_contained::CheckedExtrinsic::<
+ AccountId,
+ Call,
+ SignedExtraScheduler,
+ SelfContainedSignedInfo,
+ > {
+ signed: fp_self_contained::CheckedSignature::<
+ AccountId,
+ SignedExtraScheduler,
+ SelfContainedSignedInfo,
+ >::Signed(signer.clone().into(), get_signed_extras(signer.into())),
+ function: call.into(),
+ };
+
+ extrinsic.apply::<Runtime>(&dispatch_info, 0)
+ }
+
+ fn reserve_balance(
+ id: [u8; 16],
+ sponsor: <T as frame_system::Config>::AccountId,
+ call: <T as pallet_unique_scheduler::Config>::Call,
+ count: u32,
+ ) -> Result<(), DispatchError> {
+ let dispatch_info = call.get_dispatch_info();
+ let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
+ .saturating_mul(count.into());
+
+ <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
+ &id,
+ &(sponsor.into()),
+ weight,
+ )
+ }
+
+ fn pay_for_call(
+ id: [u8; 16],
+ sponsor: <T as frame_system::Config>::AccountId,
+ call: <T as pallet_unique_scheduler::Config>::Call,
+ ) -> Result<u128, DispatchError> {
+ let dispatch_info = call.get_dispatch_info();
+ let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
+ Ok(
+ <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
+ &id,
+ &(sponsor.into()),
+ weight,
+ ),
+ )
+ }
+
+ fn cancel_reserve(
+ id: [u8; 16],
+ sponsor: <T as frame_system::Config>::AccountId,
+ ) -> Result<u128, DispatchError> {
+ Ok(
+ <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
+ &id,
+ &(sponsor.into()),
+ u128::MAX,
+ ),
+ )
+ }
+}
runtime/common/sponsoring.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/sponsoring.rs
@@ -0,0 +1,359 @@
+// 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 core::marker::PhantomData;
+use up_sponsorship::SponsorshipHandler;
+use frame_support::{
+ traits::{IsSubType},
+ storage::{StorageMap, StorageDoubleMap, StorageNMap},
+};
+use up_data_structs::{
+ CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
+ REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode, CreateItemData,
+};
+use sp_runtime::traits::Saturating;
+use pallet_common::{CollectionHandle};
+use pallet_evm::account::CrossAccountId;
+use pallet_unique::{
+ Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,
+ NftApproveBasket, CreateItemBasket, ReFungibleTransferBasket, FungibleTransferBasket,
+ NftTransferBasket, TokenPropertyBasket,
+};
+use pallet_fungible::Config as FungibleConfig;
+use pallet_nonfungible::Config as NonfungibleConfig;
+use pallet_refungible::Config as RefungibleConfig;
+
+pub trait Config: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
+impl<T> Config for T where T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
+
+// TODO: permission check?
+pub fn withdraw_set_token_property<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::CrossAccountId,
+ item_id: &TokenId,
+ data_size: usize,
+) -> Option<()> {
+ // preliminary sponsoring correctness check
+ match collection.mode {
+ CollectionMode::NFT => {
+ let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
+ if !owner.conv_eq(who) {
+ return None;
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ // Fungible tokens have no properties
+ return None;
+ }
+ CollectionMode::ReFungible => {
+ if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
+ return None;
+ }
+ }
+ }
+
+ if data_size > collection.limits.sponsored_data_size() as usize {
+ return None;
+ }
+
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection.limits.sponsored_data_rate_limit()?;
+
+ if let Some(last_tx_block) = TokenPropertyBasket::<T>::get(collection.id, item_id) {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ <TokenPropertyBasket<T>>::insert(collection.id, item_id, block_number);
+
+ Some(())
+}
+
+pub fn withdraw_transfer<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::CrossAccountId,
+ item_id: &TokenId,
+) -> Option<()> {
+ // preliminary sponsoring correctness check
+ match collection.mode {
+ CollectionMode::NFT => {
+ let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
+ if !owner.conv_eq(who) {
+ return None;
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ if item_id != &TokenId::default() {
+ return None;
+ }
+ if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {
+ return None;
+ }
+ }
+ CollectionMode::ReFungible => {
+ if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
+ return None;
+ }
+ }
+ }
+
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match collection.mode {
+ CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
+ }
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who.as_sub()))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::insert(collection.id, who.as_sub(), block_number)
+ }
+ CollectionMode::ReFungible => <ReFungibleTransferBasket<T>>::insert(
+ (collection.id, item_id, who.as_sub()),
+ block_number,
+ ),
+ };
+
+ Some(())
+}
+
+pub fn withdraw_create_item<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::CrossAccountId,
+ properties: &CreateItemData,
+) -> Option<()> {
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match properties {
+ CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, who.as_sub())) {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);
+
+ Some(())
+}
+
+pub fn withdraw_approve<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::AccountId,
+ item_id: &TokenId,
+) -> Option<()> {
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection.limits.sponsor_approve_timeout();
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),
+ CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),
+ CollectionMode::ReFungible => {
+ <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ match collection.mode {
+ CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),
+ CollectionMode::Fungible(_) => {
+ <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)
+ }
+ CollectionMode::ReFungible => {
+ <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)
+ }
+ };
+
+ Some(())
+}
+
+fn load<T: UniqueConfig>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {
+ let collection = CollectionHandle::new(id)?;
+ let sponsor = collection.sponsorship.sponsor().cloned()?;
+ Some((sponsor, collection))
+}
+
+pub struct UniqueSponsorshipHandler<T>(PhantomData<T>);
+impl<T, C> SponsorshipHandler<T::AccountId, C> for UniqueSponsorshipHandler<T>
+where
+ T: Config,
+ C: IsSubType<UniqueCall<T>>,
+{
+ fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {
+ match IsSubType::<UniqueCall<T>>::is_sub_type(call)? {
+ UniqueCall::set_token_properties {
+ collection_id,
+ token_id,
+ properties,
+ ..
+ } => {
+ let (sponsor, collection) = load::<T>(*collection_id)?;
+ withdraw_set_token_property(
+ &collection,
+ &T::CrossAccountId::from_sub(who.clone()),
+ &token_id,
+ // No overflow may happen, as data larger than usize can't reach here
+ properties.iter().map(|p| p.key.len() + p.value.len()).sum(),
+ )
+ .map(|()| sponsor)
+ }
+ UniqueCall::create_item {
+ collection_id,
+ data,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_create_item::<T>(
+ &collection,
+ &T::CrossAccountId::from_sub(who.clone()),
+ data,
+ )
+ .map(|()| sponsor)
+ }
+ UniqueCall::transfer {
+ collection_id,
+ item_id,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_transfer::<T>(
+ &collection,
+ &T::CrossAccountId::from_sub(who.clone()),
+ item_id,
+ )
+ .map(|()| sponsor)
+ }
+ UniqueCall::transfer_from {
+ collection_id,
+ item_id,
+ from,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_transfer::<T>(&collection, from, item_id).map(|()| sponsor)
+ }
+ UniqueCall::approve {
+ collection_id,
+ item_id,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
+ }
+ _ => None,
+ }
+ }
+}
+
+pub trait SponsorshipPredict<T: Config> {
+ fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>
+ where
+ u64: From<<T as frame_system::Config>::BlockNumber>;
+}
+
+pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);
+
+impl<T: Config> SponsorshipPredict<T> for UniqueSponsorshipPredict<T> {
+ fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>
+ where
+ u64: From<<T as frame_system::Config>::BlockNumber>,
+ {
+ let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;
+ let _ = collection.sponsorship.sponsor()?;
+
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match collection.mode {
+ CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
+ }
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ return Some(
+ last_tx_block
+ .saturating_add(limit.into())
+ .saturating_sub(block_number)
+ .into(),
+ );
+ }
+
+ let token_exists = match collection.mode {
+ CollectionMode::NFT => {
+ <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))
+ }
+ CollectionMode::Fungible(_) => token == TokenId::default(),
+ CollectionMode::ReFungible => {
+ <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))
+ }
+ };
+
+ if token_exists {
+ Some(0)
+ } else {
+ None
+ }
+ }
+}
runtime/common/src/constants.rsdiffbeforeafterboth--- a/runtime/common/src/constants.rs
+++ /dev/null
@@ -1,57 +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_runtime::Perbill;
-use frame_support::{
- parameter_types,
- weights::{Weight, constants::WEIGHT_PER_SECOND},
-};
-use crate::types::{BlockNumber, Balance};
-
-pub const MILLISECS_PER_BLOCK: u64 = 12000;
-
-pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
-
-// These time units are defined in number of blocks.
-pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
-pub const HOURS: BlockNumber = MINUTES * 60;
-pub const DAYS: BlockNumber = HOURS * 24;
-
-pub const MICROUNIQUE: Balance = 1_000_000_000_000;
-pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE;
-pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;
-pub const UNIQUE: Balance = 100 * CENTIUNIQUE;
-
-// Targeting 0.1 UNQ per transfer
-pub const WEIGHT_TO_FEE_COEFF: u32 = 207_890_902;
-
-// Targeting 0.15 UNQ per transfer via ETH
-pub const MIN_GAS_PRICE: u64 = 1_019_493_469_850;
-
-/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
-/// This is used to limit the maximal weight of a single extrinsic.
-pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
-/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
-/// by Operational extrinsics.
-pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
-/// We allow for 2 seconds of compute with a 6 second average block time.
-pub const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2;
-
-parameter_types! {
- pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;
-
- pub const TransactionByteFee: Balance = 501 * MICROUNIQUE;
-}
runtime/common/src/dispatch.rsdiffbeforeafterboth--- a/runtime/common/src/dispatch.rs
+++ /dev/null
@@ -1,181 +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 frame_support::{dispatch::DispatchResult, ensure};
-use pallet_evm::{PrecompileHandle, PrecompileResult};
-use sp_core::H160;
-use sp_runtime::DispatchError;
-use sp_std::{borrow::ToOwned, vec::Vec};
-use pallet_common::{
- CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,
- eth::map_eth_to_id,
-};
-pub use pallet_common::dispatch::CollectionDispatch;
-use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};
-use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};
-use pallet_refungible::{
- Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,
-};
-use up_data_structs::{
- CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,
- CollectionId,
-};
-
-pub enum CollectionDispatchT<T>
-where
- T: pallet_fungible::Config + pallet_nonfungible::Config + pallet_refungible::Config,
-{
- Fungible(FungibleHandle<T>),
- Nonfungible(NonfungibleHandle<T>),
- Refungible(RefungibleHandle<T>),
-}
-impl<T> CollectionDispatch<T> for CollectionDispatchT<T>
-where
- T: pallet_common::Config
- + pallet_unique::Config
- + pallet_fungible::Config
- + pallet_nonfungible::Config
- + pallet_refungible::Config,
-{
- fn create(
- sender: T::CrossAccountId,
- data: CreateCollectionData<T::AccountId>,
- ) -> Result<CollectionId, DispatchError> {
- let id = match data.mode {
- CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data, false)?,
- CollectionMode::Fungible(decimal_points) => {
- // check params
- ensure!(
- decimal_points <= MAX_DECIMAL_POINTS,
- pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded
- );
- <PalletFungible<T>>::init_collection(sender, data)?
- }
- CollectionMode::ReFungible => <PalletRefungible<T>>::init_collection(sender, data)?,
- };
- Ok(id)
- }
-
- fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {
- match collection.mode {
- CollectionMode::ReFungible => {
- PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?
- }
- CollectionMode::Fungible(_) => {
- PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?
- }
- CollectionMode::NFT => {
- PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?
- }
- }
- Ok(())
- }
-
- fn dispatch(handle: CollectionHandle<T>) -> Self {
- match handle.mode {
- CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),
- CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),
- CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),
- }
- }
-
- fn into_inner(self) -> CollectionHandle<T> {
- match self {
- Self::Fungible(f) => f.into_inner(),
- Self::Nonfungible(f) => f.into_inner(),
- Self::Refungible(f) => f.into_inner(),
- }
- }
-
- fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
- match self {
- Self::Fungible(h) => h,
- Self::Nonfungible(h) => h,
- Self::Refungible(h) => h,
- }
- }
-}
-
-impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>
-where
- T: pallet_common::Config
- + pallet_unique::Config
- + pallet_fungible::Config
- + pallet_nonfungible::Config
- + pallet_refungible::Config,
- T::AccountId: From<[u8; 32]>,
-{
- fn is_reserved(target: &H160) -> bool {
- map_eth_to_id(target).is_some()
- }
- fn is_used(target: &H160) -> bool {
- map_eth_to_id(target)
- .map(<CollectionById<T>>::contains_key)
- .unwrap_or(false)
- }
- fn get_code(target: &H160) -> Option<Vec<u8>> {
- if let Some(collection_id) = map_eth_to_id(target) {
- let collection = <CollectionById<T>>::get(collection_id)?;
- Some(
- match collection.mode {
- CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,
- CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,
- CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,
- }
- .to_owned(),
- )
- } else if let Some((collection_id, _token_id)) =
- <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)
- {
- let collection = <CollectionById<T>>::get(collection_id)?;
- if collection.mode != CollectionMode::ReFungible {
- return None;
- }
- // TODO: check token existence
- Some(<RefungibleTokenHandle<T>>::CODE.to_owned())
- } else {
- None
- }
- }
- fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
- if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {
- let collection =
- <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
- let dispatched = Self::dispatch(collection);
-
- match dispatched {
- Self::Fungible(h) => h.call(handle),
- Self::Nonfungible(h) => h.call(handle),
- Self::Refungible(h) => h.call(handle),
- }
- } else if let Some((collection_id, token_id)) =
- <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
- &handle.code_address(),
- ) {
- let collection =
- <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
- if collection.mode != CollectionMode::ReFungible {
- return None;
- }
-
- let h = RefungibleHandle::cast(collection);
- // TODO: check token existence
- RefungibleTokenHandle(h, token_id).call(handle)
- } else {
- None
- }
- }
-}
runtime/common/src/eth_sponsoring.rsdiffbeforeafterboth--- a/runtime/common/src/eth_sponsoring.rs
+++ /dev/null
@@ -1,122 +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/>.
-
-//! Implements EVM sponsoring logic via TransactionValidityHack
-
-use evm_coder::{Call, abi::AbiReader};
-use pallet_common::{CollectionHandle, eth::map_eth_to_id};
-use sp_core::H160;
-use sp_std::prelude::*;
-use up_sponsorship::SponsorshipHandler;
-use core::marker::PhantomData;
-use core::convert::TryInto;
-use pallet_evm::account::CrossAccountId;
-use up_data_structs::{TokenId, CreateItemData, CreateNftData, CollectionMode};
-use pallet_unique::Config as UniqueConfig;
-
-use crate::sponsoring::*;
-
-use pallet_nonfungible::erc::{
- UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call, TokenPropertiesCall,
-};
-use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
-use pallet_fungible::Config as FungibleConfig;
-use pallet_nonfungible::Config as NonfungibleConfig;
-use pallet_refungible::Config as RefungibleConfig;
-
-pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);
-impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>
- SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T>
-{
- fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {
- let collection_id = map_eth_to_id(&call.0)?;
- let collection = <CollectionHandle<T>>::new(collection_id)?;
- let sponsor = collection.sponsorship.sponsor()?.clone();
- let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
- Some(T::CrossAccountId::from_sub(match &collection.mode {
- CollectionMode::NFT => {
- let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
- match call {
- UniqueNFTCall::TokenProperties(TokenPropertiesCall::SetProperty {
- token_id,
- key,
- value,
- ..
- }) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- withdraw_set_token_property::<T>(
- &collection,
- &who,
- &token_id,
- key.len() + value.len(),
- )
- .map(|()| sponsor)
- }
- UniqueNFTCall::ERC721UniqueExtensions(
- ERC721UniqueExtensionsCall::Transfer { token_id, .. },
- ) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
- }
- UniqueNFTCall::ERC721Mintable(
- ERC721MintableCall::Mint { token_id, .. }
- | ERC721MintableCall::MintWithTokenUri { token_id, .. },
- ) => {
- let _token_id: TokenId = token_id.try_into().ok()?;
- withdraw_create_item::<T>(
- &collection,
- &who,
- &CreateItemData::NFT(CreateNftData::default()),
- )
- .map(|()| sponsor)
- }
- UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, from, .. }) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- let from = T::CrossAccountId::from_eth(from);
- withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)
- }
- UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
- .map(|()| sponsor)
- }
- _ => None,
- }
- }
- CollectionMode::Fungible(_) => {
- let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
- #[allow(clippy::single_match)]
- match call {
- UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
- withdraw_transfer::<T>(&collection, who, &TokenId::default())
- .map(|()| sponsor)
- }
- UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {
- let from = T::CrossAccountId::from_eth(from);
- withdraw_transfer::<T>(&collection, &from, &TokenId::default())
- .map(|()| sponsor)
- }
- UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
- withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())
- .map(|()| sponsor)
- }
- _ => None,
- }
- }
- _ => None,
- }?))
- }
-}
runtime/common/src/lib.rsdiffbeforeafterboth--- a/runtime/common/src/lib.rs
+++ /dev/null
@@ -1,25 +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)]
-
-pub mod constants;
-pub mod dispatch;
-pub mod eth_sponsoring;
-pub mod runtime_apis;
-pub mod sponsoring;
-pub mod types;
-pub mod weights;
runtime/common/src/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/src/runtime_apis.rs
+++ /dev/null
@@ -1,546 +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/>.
-
-#[macro_export]
-macro_rules! impl_common_runtime_apis {
- (
- $(
- #![custom_apis]
-
- $($custom_apis:tt)+
- )?
- ) => {
- impl_runtime_apis! {
- $($($custom_apis)+)?
-
- impl up_rpc::UniqueApi<Block, CrossAccountId, AccountId> for Runtime {
- fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>, DispatchError> {
- dispatch_unique_runtime!(collection.account_tokens(account))
- }
- fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>, DispatchError> {
- dispatch_unique_runtime!(collection.collection_tokens())
- }
- fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool, DispatchError> {
- dispatch_unique_runtime!(collection.token_exists(token))
- }
-
- fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
- dispatch_unique_runtime!(collection.token_owner(token))
- }
-
- fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec::<CrossAccountId>, DispatchError> {
- dispatch_unique_runtime!(collection.token_owners(token))
- }
-
- fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
- let budget = up_data_structs::budget::Value::new(10);
-
- Ok(Some(<pallet_structure::Pallet<Runtime>>::find_topmost_owner(collection, token, &budget)?))
- }
- fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>, DispatchError> {
- Ok(<pallet_nonfungible::Pallet<Runtime>>::token_children_ids(collection, token))
- }
- fn collection_properties(
- collection: CollectionId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<Vec<Property>, DispatchError> {
- let keys = keys.map(
- |keys| Common::bytes_keys_to_property_keys(keys)
- ).transpose()?;
-
- Common::filter_collection_properties(collection, keys)
- }
-
- fn token_properties(
- collection: CollectionId,
- token_id: TokenId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<Vec<Property>, DispatchError> {
- let keys = keys.map(
- |keys| Common::bytes_keys_to_property_keys(keys)
- ).transpose()?;
-
- dispatch_unique_runtime!(collection.token_properties(token_id, keys))
- }
-
- fn property_permissions(
- collection: CollectionId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
- let keys = keys.map(
- |keys| Common::bytes_keys_to_property_keys(keys)
- ).transpose()?;
-
- Common::filter_property_permissions(collection, keys)
- }
-
- fn token_data(
- collection: CollectionId,
- token_id: TokenId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<TokenData<CrossAccountId>, DispatchError> {
- let token_data = TokenData {
- properties: Self::token_properties(collection, token_id, keys)?,
- owner: Self::token_owner(collection, token_id)?,
- pieces: Self::total_pieces(collection, token_id)?.unwrap_or(0),
- };
-
- Ok(token_data)
- }
-
- fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {
- dispatch_unique_runtime!(collection.total_supply())
- }
- fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {
- dispatch_unique_runtime!(collection.account_balance(account))
- }
- fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {
- dispatch_unique_runtime!(collection.balance(account, token))
- }
- fn allowance(
- collection: CollectionId,
- sender: CrossAccountId,
- spender: CrossAccountId,
- token: TokenId,
- ) -> Result<u128, DispatchError> {
- dispatch_unique_runtime!(collection.allowance(sender, spender, token))
- }
-
- fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))
- }
- fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))
- }
- fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))
- }
- fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {
- dispatch_unique_runtime!(collection.last_token_id())
- }
- fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::rpc_collection(collection))
- }
- fn collection_stats() -> Result<CollectionStats, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::collection_stats())
- }
- fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {
- Ok(<$crate::sponsoring::UniqueSponsorshipPredict<Runtime> as
- $crate::sponsoring::SponsorshipPredict<Runtime>>::predict(
- collection,
- account,
- token))
- }
-
- fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))
- }
-
- fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
- dispatch_unique_runtime!(collection.total_pieces(token_id))
- }
- }
-
- impl sp_api::Core<Block> for Runtime {
- fn version() -> RuntimeVersion {
- VERSION
- }
-
- fn execute_block(block: Block) {
- Executive::execute_block(block)
- }
-
- fn initialize_block(header: &<Block as BlockT>::Header) {
- Executive::initialize_block(header)
- }
- }
-
- impl sp_api::Metadata<Block> for Runtime {
- fn metadata() -> OpaqueMetadata {
- OpaqueMetadata::new(Runtime::metadata().into())
- }
- }
-
- impl sp_block_builder::BlockBuilder<Block> for Runtime {
- fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
- Executive::apply_extrinsic(extrinsic)
- }
-
- fn finalize_block() -> <Block as BlockT>::Header {
- Executive::finalize_block()
- }
-
- fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
- data.create_extrinsics()
- }
-
- fn check_inherents(
- block: Block,
- data: sp_inherents::InherentData,
- ) -> sp_inherents::CheckInherentsResult {
- data.check_extrinsics(&block)
- }
-
- // fn random_seed() -> <Block as BlockT>::Hash {
- // RandomnessCollectiveFlip::random_seed().0
- // }
- }
-
- impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
- fn validate_transaction(
- source: TransactionSource,
- tx: <Block as BlockT>::Extrinsic,
- hash: <Block as BlockT>::Hash,
- ) -> TransactionValidity {
- Executive::validate_transaction(source, tx, hash)
- }
- }
-
- impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
- fn offchain_worker(header: &<Block as BlockT>::Header) {
- Executive::offchain_worker(header)
- }
- }
-
- impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
- fn chain_id() -> u64 {
- <Runtime as pallet_evm::Config>::ChainId::get()
- }
-
- fn account_basic(address: H160) -> EVMAccount {
- let (account, _) = EVM::account_basic(&address);
- account
- }
-
- fn gas_price() -> U256 {
- let (price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
- price
- }
-
- fn account_code_at(address: H160) -> Vec<u8> {
- EVM::account_codes(address)
- }
-
- fn author() -> H160 {
- <pallet_evm::Pallet<Runtime>>::find_author()
- }
-
- fn storage_at(address: H160, index: U256) -> H256 {
- let mut tmp = [0u8; 32];
- index.to_big_endian(&mut tmp);
- EVM::account_storages(address, H256::from_slice(&tmp[..]))
- }
-
- #[allow(clippy::redundant_closure)]
- fn call(
- from: H160,
- to: H160,
- data: Vec<u8>,
- value: U256,
- gas_limit: U256,
- max_fee_per_gas: Option<U256>,
- max_priority_fee_per_gas: Option<U256>,
- nonce: Option<U256>,
- estimate: bool,
- access_list: Option<Vec<(H160, Vec<H256>)>>,
- ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
- let config = if estimate {
- let mut config = <Runtime as pallet_evm::Config>::config().clone();
- config.estimate = true;
- Some(config)
- } else {
- None
- };
-
- let is_transactional = false;
- <Runtime as pallet_evm::Config>::Runner::call(
- CrossAccountId::from_eth(from),
- to,
- data,
- value,
- gas_limit.low_u64(),
- max_fee_per_gas,
- max_priority_fee_per_gas,
- nonce,
- access_list.unwrap_or_default(),
- is_transactional,
- config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
- ).map_err(|err| err.error.into())
- }
-
- #[allow(clippy::redundant_closure)]
- fn create(
- from: H160,
- data: Vec<u8>,
- value: U256,
- gas_limit: U256,
- max_fee_per_gas: Option<U256>,
- max_priority_fee_per_gas: Option<U256>,
- nonce: Option<U256>,
- estimate: bool,
- access_list: Option<Vec<(H160, Vec<H256>)>>,
- ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
- let config = if estimate {
- let mut config = <Runtime as pallet_evm::Config>::config().clone();
- config.estimate = true;
- Some(config)
- } else {
- None
- };
-
- let is_transactional = false;
- <Runtime as pallet_evm::Config>::Runner::create(
- CrossAccountId::from_eth(from),
- data,
- value,
- gas_limit.low_u64(),
- max_fee_per_gas,
- max_priority_fee_per_gas,
- nonce,
- access_list.unwrap_or_default(),
- is_transactional,
- config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
- ).map_err(|err| err.error.into())
- }
-
- fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {
- Ethereum::current_transaction_statuses()
- }
-
- fn current_block() -> Option<pallet_ethereum::Block> {
- Ethereum::current_block()
- }
-
- fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
- Ethereum::current_receipts()
- }
-
- fn current_all() -> (
- Option<pallet_ethereum::Block>,
- Option<Vec<pallet_ethereum::Receipt>>,
- Option<Vec<TransactionStatus>>
- ) {
- (
- Ethereum::current_block(),
- Ethereum::current_receipts(),
- Ethereum::current_transaction_statuses()
- )
- }
-
- fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {
- xts.into_iter().filter_map(|xt| match xt.0.function {
- Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
- _ => None
- }).collect()
- }
-
- fn elasticity() -> Option<Permill> {
- None
- }
- }
-
- impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
- fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {
- UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- )
- }
- }
-
- impl sp_session::SessionKeys<Block> for Runtime {
- fn decode_session_keys(
- encoded: Vec<u8>,
- ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
- SessionKeys::decode_into_raw_public_keys(&encoded)
- }
-
- fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
- SessionKeys::generate(seed)
- }
- }
-
- impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
- fn slot_duration() -> sp_consensus_aura::SlotDuration {
- sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
- }
-
- fn authorities() -> Vec<AuraId> {
- Aura::authorities().to_vec()
- }
- }
-
- impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
- fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
- ParachainSystem::collect_collation_info(header)
- }
- }
-
- impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
- fn account_nonce(account: AccountId) -> Index {
- System::account_nonce(account)
- }
- }
-
- impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
- fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
- TransactionPayment::query_info(uxt, len)
- }
- fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
- TransactionPayment::query_fee_details(uxt, len)
- }
- }
-
- /*
- impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>
- for Runtime
- {
- fn call(
- origin: AccountId,
- dest: AccountId,
- value: Balance,
- gas_limit: u64,
- input_data: Vec<u8>,
- ) -> pallet_contracts_primitives::ContractExecResult {
- Contracts::bare_call(origin, dest, value, gas_limit, input_data, false)
- }
-
- fn instantiate(
- origin: AccountId,
- endowment: Balance,
- gas_limit: u64,
- code: pallet_contracts_primitives::Code<Hash>,
- data: Vec<u8>,
- salt: Vec<u8>,
- ) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>
- {
- Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false)
- }
-
- fn get_storage(
- address: AccountId,
- key: [u8; 32],
- ) -> pallet_contracts_primitives::GetStorageResult {
- Contracts::get_storage(address, key)
- }
-
- fn rent_projection(
- address: AccountId,
- ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
- Contracts::rent_projection(address)
- }
- }
- */
-
- #[cfg(feature = "runtime-benchmarks")]
- impl frame_benchmarking::Benchmark<Block> for Runtime {
- fn benchmark_metadata(extra: bool) -> (
- Vec<frame_benchmarking::BenchmarkList>,
- Vec<frame_support::traits::StorageInfo>,
- ) {
- use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};
- use frame_support::traits::StorageInfoTrait;
-
- let mut list = Vec::<BenchmarkList>::new();
-
- list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);
- list_benchmark!(list, extra, pallet_common, Common);
- list_benchmark!(list, extra, pallet_unique, Unique);
- list_benchmark!(list, extra, pallet_structure, Structure);
- list_benchmark!(list, extra, pallet_inflation, Inflation);
- list_benchmark!(list, extra, pallet_fungible, Fungible);
- list_benchmark!(list, extra, pallet_refungible, Refungible);
- list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);
- list_benchmark!(list, extra, pallet_unique_scheduler, Scheduler);
-
- #[cfg(not(feature = "unique-runtime"))]
- list_benchmark!(list, extra, pallet_proxy_rmrk_core, RmrkCore);
-
- #[cfg(not(feature = "unique-runtime"))]
- list_benchmark!(list, extra, pallet_proxy_rmrk_equip, RmrkEquip);
-
- // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate);
-
- let storage_info = AllPalletsReversedWithSystemFirst::storage_info();
-
- return (list, storage_info)
- }
-
- fn dispatch_benchmark(
- config: frame_benchmarking::BenchmarkConfig
- ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
- use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};
-
- let allowlist: Vec<TrackedStorageKey> = vec![
- // Total Issuance
- hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
-
- // Block Number
- hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
- // Execution Phase
- hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),
- // Event Count
- hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),
- // System Events
- hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),
-
- // Evm CurrentLogs
- hex_literal::hex!("1da53b775b270400e7e61ed5cbc5a146547f210cec367e9af919603343b9cb56").to_vec().into(),
-
- // Transactional depth
- hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),
- ];
-
- let mut batches = Vec::<BenchmarkBatch>::new();
- let params = (&config, &allowlist);
-
- add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);
- add_benchmark!(params, batches, pallet_common, Common);
- add_benchmark!(params, batches, pallet_unique, Unique);
- add_benchmark!(params, batches, pallet_structure, Structure);
- add_benchmark!(params, batches, pallet_inflation, Inflation);
- add_benchmark!(params, batches, pallet_fungible, Fungible);
- add_benchmark!(params, batches, pallet_refungible, Refungible);
- add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);
- add_benchmark!(params, batches, pallet_unique_scheduler, Scheduler);
-
- #[cfg(not(feature = "unique-runtime"))]
- add_benchmark!(params, batches, pallet_proxy_rmrk_core, RmrkCore);
-
- #[cfg(not(feature = "unique-runtime"))]
- add_benchmark!(params, batches, pallet_proxy_rmrk_equip, RmrkEquip);
-
- // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);
-
- if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
- Ok(batches)
- }
- }
-
- #[cfg(feature = "try-runtime")]
- impl frame_try_runtime::TryRuntime<Block> for Runtime {
- fn on_runtime_upgrade() -> (Weight, Weight) {
- log::info!("try-runtime::on_runtime_upgrade unique-chain.");
- let weight = Executive::try_runtime_upgrade().unwrap();
- (weight, RuntimeBlockWeights::get().max_block)
- }
-
- fn execute_block_no_check(block: Block) -> Weight {
- Executive::execute_block_no_check(block)
- }
- }
- }
- }
-}
runtime/common/src/sponsoring.rsdiffbeforeafterboth--- a/runtime/common/src/sponsoring.rs
+++ /dev/null
@@ -1,359 +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 core::marker::PhantomData;
-use up_sponsorship::SponsorshipHandler;
-use frame_support::{
- traits::{IsSubType},
- storage::{StorageMap, StorageDoubleMap, StorageNMap},
-};
-use up_data_structs::{
- CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
- REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode, CreateItemData,
-};
-use sp_runtime::traits::Saturating;
-use pallet_common::{CollectionHandle};
-use pallet_evm::account::CrossAccountId;
-use pallet_unique::{
- Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,
- NftApproveBasket, CreateItemBasket, ReFungibleTransferBasket, FungibleTransferBasket,
- NftTransferBasket, TokenPropertyBasket,
-};
-use pallet_fungible::Config as FungibleConfig;
-use pallet_nonfungible::Config as NonfungibleConfig;
-use pallet_refungible::Config as RefungibleConfig;
-
-pub trait Config: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
-impl<T> Config for T where T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
-
-// TODO: permission check?
-pub fn withdraw_set_token_property<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::CrossAccountId,
- item_id: &TokenId,
- data_size: usize,
-) -> Option<()> {
- // preliminary sponsoring correctness check
- match collection.mode {
- CollectionMode::NFT => {
- let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
- if !owner.conv_eq(who) {
- return None;
- }
- }
- CollectionMode::Fungible(_) => {
- // Fungible tokens have no properties
- return None;
- }
- CollectionMode::ReFungible => {
- if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
- return None;
- }
- }
- }
-
- if data_size > collection.limits.sponsored_data_size() as usize {
- return None;
- }
-
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection.limits.sponsored_data_rate_limit()?;
-
- if let Some(last_tx_block) = TokenPropertyBasket::<T>::get(collection.id, item_id) {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- <TokenPropertyBasket<T>>::insert(collection.id, item_id, block_number);
-
- Some(())
-}
-
-pub fn withdraw_transfer<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::CrossAccountId,
- item_id: &TokenId,
-) -> Option<()> {
- // preliminary sponsoring correctness check
- match collection.mode {
- CollectionMode::NFT => {
- let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
- if !owner.conv_eq(who) {
- return None;
- }
- }
- CollectionMode::Fungible(_) => {
- if item_id != &TokenId::default() {
- return None;
- }
- if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {
- return None;
- }
- }
- CollectionMode::ReFungible => {
- if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
- return None;
- }
- }
- }
-
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match collection.mode {
- CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
-
- let last_tx_block = match collection.mode {
- CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),
- CollectionMode::Fungible(_) => {
- <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
- }
- CollectionMode::ReFungible => {
- <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who.as_sub()))
- }
- };
-
- if let Some(last_tx_block) = last_tx_block {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- match collection.mode {
- CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),
- CollectionMode::Fungible(_) => {
- <FungibleTransferBasket<T>>::insert(collection.id, who.as_sub(), block_number)
- }
- CollectionMode::ReFungible => <ReFungibleTransferBasket<T>>::insert(
- (collection.id, item_id, who.as_sub()),
- block_number,
- ),
- };
-
- Some(())
-}
-
-pub fn withdraw_create_item<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::CrossAccountId,
- properties: &CreateItemData,
-) -> Option<()> {
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match properties {
- CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
-
- if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, who.as_sub())) {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);
-
- Some(())
-}
-
-pub fn withdraw_approve<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::AccountId,
- item_id: &TokenId,
-) -> Option<()> {
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection.limits.sponsor_approve_timeout();
-
- let last_tx_block = match collection.mode {
- CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),
- CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),
- CollectionMode::ReFungible => {
- <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))
- }
- };
-
- if let Some(last_tx_block) = last_tx_block {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- match collection.mode {
- CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),
- CollectionMode::Fungible(_) => {
- <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)
- }
- CollectionMode::ReFungible => {
- <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)
- }
- };
-
- Some(())
-}
-
-fn load<T: UniqueConfig>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {
- let collection = CollectionHandle::new(id)?;
- let sponsor = collection.sponsorship.sponsor().cloned()?;
- Some((sponsor, collection))
-}
-
-pub struct UniqueSponsorshipHandler<T>(PhantomData<T>);
-impl<T, C> SponsorshipHandler<T::AccountId, C> for UniqueSponsorshipHandler<T>
-where
- T: Config,
- C: IsSubType<UniqueCall<T>>,
-{
- fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {
- match IsSubType::<UniqueCall<T>>::is_sub_type(call)? {
- UniqueCall::set_token_properties {
- collection_id,
- token_id,
- properties,
- ..
- } => {
- let (sponsor, collection) = load::<T>(*collection_id)?;
- withdraw_set_token_property(
- &collection,
- &T::CrossAccountId::from_sub(who.clone()),
- &token_id,
- // No overflow may happen, as data larger than usize can't reach here
- properties.iter().map(|p| p.key.len() + p.value.len()).sum(),
- )
- .map(|()| sponsor)
- }
- UniqueCall::create_item {
- collection_id,
- data,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_create_item::<T>(
- &collection,
- &T::CrossAccountId::from_sub(who.clone()),
- data,
- )
- .map(|()| sponsor)
- }
- UniqueCall::transfer {
- collection_id,
- item_id,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_transfer::<T>(
- &collection,
- &T::CrossAccountId::from_sub(who.clone()),
- item_id,
- )
- .map(|()| sponsor)
- }
- UniqueCall::transfer_from {
- collection_id,
- item_id,
- from,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_transfer::<T>(&collection, from, item_id).map(|()| sponsor)
- }
- UniqueCall::approve {
- collection_id,
- item_id,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
- }
- _ => None,
- }
- }
-}
-
-pub trait SponsorshipPredict<T: Config> {
- fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>
- where
- u64: From<<T as frame_system::Config>::BlockNumber>;
-}
-
-pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);
-
-impl<T: Config> SponsorshipPredict<T> for UniqueSponsorshipPredict<T> {
- fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>
- where
- u64: From<<T as frame_system::Config>::BlockNumber>,
- {
- let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;
- let _ = collection.sponsorship.sponsor()?;
-
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match collection.mode {
- CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
-
- let last_tx_block = match collection.mode {
- CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),
- CollectionMode::Fungible(_) => {
- <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
- }
- CollectionMode::ReFungible => {
- <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))
- }
- };
-
- if let Some(last_tx_block) = last_tx_block {
- return Some(
- last_tx_block
- .saturating_add(limit.into())
- .saturating_sub(block_number)
- .into(),
- );
- }
-
- let token_exists = match collection.mode {
- CollectionMode::NFT => {
- <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))
- }
- CollectionMode::Fungible(_) => token == TokenId::default(),
- CollectionMode::ReFungible => {
- <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))
- }
- };
-
- if token_exists {
- Some(0)
- } else {
- None
- }
- }
-}
runtime/common/src/types.rsdiffbeforeafterboth--- a/runtime/common/src/types.rs
+++ /dev/null
@@ -1,72 +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_runtime::{
- traits::{Verify, IdentifyAccount, BlakeTwo256},
- generic, MultiSignature,
-};
-
-pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
-
-/// Opaque block header type.
-pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
-
-/// Opaque block type.
-pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-
-pub type SessionHandlers = ();
-
-/// An index to a block.
-pub type BlockNumber = u32;
-
-/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
-pub type Signature = MultiSignature;
-
-/// Some way of identifying an account on the chain. We intentionally make it equivalent
-/// to the public key of our transaction signing scheme.
-pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
-
-/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
-/// never know...
-pub type AccountIndex = u32;
-
-/// Balance of an account.
-pub type Balance = u128;
-
-/// Index of a transaction in the chain.
-pub type Index = u32;
-
-/// A hash of some data used by the chain.
-pub type Hash = sp_core::H256;
-
-/// Digest item type.
-pub type DigestItem = generic::DigestItem;
-
-pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
-
-pub trait RuntimeInstance {
- type CrossAccountId: pallet_evm::account::CrossAccountId<sp_runtime::AccountId32>
- + Send
- + Sync
- + 'static;
-
- type TransactionConverter: fp_rpc::ConvertTransaction<UncheckedExtrinsic>
- + Send
- + Sync
- + 'static;
-
- fn get_transaction_converter() -> Self::TransactionConverter;
-}
runtime/common/src/weights.rsdiffbeforeafterboth--- a/runtime/common/src/weights.rs
+++ /dev/null
@@ -1,111 +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 core::marker::PhantomData;
-use frame_support::{weights::Weight};
-use pallet_common::{CommonWeightInfo, dispatch::dispatch_weight, RefungibleExtensionsWeightInfo};
-
-use pallet_fungible::{Config as FungibleConfig, common::CommonWeights as FungibleWeights};
-use pallet_nonfungible::{Config as NonfungibleConfig, common::CommonWeights as NonfungibleWeights};
-use pallet_refungible::{
- Config as RefungibleConfig, weights::WeightInfo, common::CommonWeights as RefungibleWeights,
-};
-use up_data_structs::{CreateItemExData, CreateItemData};
-
-macro_rules! max_weight_of {
- ($method:ident ( $($args:tt)* )) => {
- <FungibleWeights<T>>::$method($($args)*)
- .max(<NonfungibleWeights<T>>::$method($($args)*))
- .max(<RefungibleWeights<T>>::$method($($args)*))
- };
-}
-
-pub struct CommonWeights<T>(PhantomData<T>)
-where
- T: FungibleConfig + NonfungibleConfig + RefungibleConfig;
-impl<T> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T>
-where
- T: FungibleConfig + NonfungibleConfig + RefungibleConfig,
-{
- fn create_item() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(create_item())
- }
-
- fn create_multiple_items(data: &[CreateItemData]) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(create_multiple_items(data))
- }
-
- fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(create_multiple_items_ex(data))
- }
-
- fn burn_item() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(burn_item())
- }
-
- fn set_collection_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_collection_properties(amount))
- }
-
- fn delete_collection_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(delete_collection_properties(amount))
- }
-
- fn set_token_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_token_properties(amount))
- }
-
- fn delete_token_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(delete_token_properties(amount))
- }
-
- fn set_token_property_permissions(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_token_property_permissions(amount))
- }
-
- fn transfer() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(transfer())
- }
-
- fn approve() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(approve())
- }
-
- fn transfer_from() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(transfer_from())
- }
-
- fn burn_from() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(burn_from())
- }
-
- fn burn_recursively_self_raw() -> Weight {
- max_weight_of!(burn_recursively_self_raw())
- }
-
- fn burn_recursively_breadth_raw(amount: u32) -> Weight {
- max_weight_of!(burn_recursively_breadth_raw(amount))
- }
-}
-
-impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
-where
- T: FungibleConfig + NonfungibleConfig + RefungibleConfig,
-{
- fn repartition() -> Weight {
- dispatch_weight::<T>() + <<T as RefungibleConfig>::WeightInfo>::repartition_item()
- }
-}
runtime/common/weights.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/weights.rs
@@ -0,0 +1,143 @@
+// 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 core::marker::PhantomData;
+use frame_support::{weights::Weight};
+use pallet_common::{CommonWeightInfo, dispatch::dispatch_weight, RefungibleExtensionsWeightInfo};
+
+use pallet_fungible::{Config as FungibleConfig, common::CommonWeights as FungibleWeights};
+use pallet_nonfungible::{Config as NonfungibleConfig, common::CommonWeights as NonfungibleWeights};
+
+#[cfg(feature = "refungible")]
+use pallet_refungible::{
+ Config as RefungibleConfig, weights::WeightInfo, common::CommonWeights as RefungibleWeights,
+};
+use up_data_structs::{CreateItemExData, CreateItemData};
+
+macro_rules! max_weight_of {
+ ($method:ident ( $($args:tt)* )) => {{
+ let max_weight = <FungibleWeights<T>>::$method($($args)*)
+ .max(<NonfungibleWeights<T>>::$method($($args)*));
+
+ #[cfg(feature = "refungible")]
+ let max_weight = max_weight.max(<RefungibleWeights<T>>::$method($($args)*));
+
+ max_weight
+ }};
+}
+
+#[cfg(not(feature = "refungible"))]
+pub trait CommonWeightConfigs: FungibleConfig + NonfungibleConfig {}
+
+#[cfg(not(feature = "refungible"))]
+impl<T: FungibleConfig + NonfungibleConfig> CommonWeightConfigs for T {}
+
+#[cfg(feature = "refungible")]
+pub trait CommonWeightConfigs: FungibleConfig + NonfungibleConfig + RefungibleConfig {}
+
+#[cfg(feature = "refungible")]
+impl<T: FungibleConfig + NonfungibleConfig + RefungibleConfig> CommonWeightConfigs for T {}
+
+pub struct CommonWeights<T>(PhantomData<T>);
+
+impl<T> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T>
+where
+ T: CommonWeightConfigs,
+{
+ fn create_item() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(create_item())
+ }
+
+ fn create_multiple_items(data: &[CreateItemData]) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(create_multiple_items(data))
+ }
+
+ fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(create_multiple_items_ex(data))
+ }
+
+ fn burn_item() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(burn_item())
+ }
+
+ fn set_collection_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(set_collection_properties(amount))
+ }
+
+ fn delete_collection_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(delete_collection_properties(amount))
+ }
+
+ fn set_token_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(set_token_properties(amount))
+ }
+
+ fn delete_token_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(delete_token_properties(amount))
+ }
+
+ fn set_token_property_permissions(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(set_token_property_permissions(amount))
+ }
+
+ fn transfer() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(transfer())
+ }
+
+ fn approve() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(approve())
+ }
+
+ fn transfer_from() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(transfer_from())
+ }
+
+ fn burn_from() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(burn_from())
+ }
+
+ fn burn_recursively_self_raw() -> Weight {
+ max_weight_of!(burn_recursively_self_raw())
+ }
+
+ fn burn_recursively_breadth_raw(amount: u32) -> Weight {
+ max_weight_of!(burn_recursively_breadth_raw(amount))
+ }
+
+ fn token_owner() -> Weight {
+ max_weight_of!(token_owner())
+ }
+}
+
+#[cfg(feature = "refungible")]
+impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
+where
+ T: FungibleConfig + NonfungibleConfig + RefungibleConfig,
+{
+ fn repartition() -> Weight {
+ dispatch_weight::<T>() + <<T as RefungibleConfig>::WeightInfo>::repartition_item()
+ }
+}
+
+#[cfg(not(feature = "refungible"))]
+impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
+where
+ T: FungibleConfig + NonfungibleConfig,
+{
+ fn repartition() -> Weight {
+ dispatch_weight::<T>()
+ }
+}
runtime/opal/Cargo.tomldiffbeforeafterboth--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -16,7 +16,7 @@
targets = ['x86_64-unknown-linux-gnu']
[features]
-default = ['std']
+default = ['std', 'opal-runtime']
runtime-benchmarks = [
'hex-literal',
'frame-benchmarking',
@@ -113,13 +113,20 @@
'xcm/std',
'xcm-builder/std',
'xcm-executor/std',
- 'unique-runtime-common/std',
+ 'up-common/std',
'rmrk-rpc/std',
+ 'evm-coder/std',
+ 'up-sponsorship/std',
"orml-vesting/std",
]
limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
+opal-runtime = ['refungible', 'scheduler', 'rmrk']
+refungible = []
+scheduler = []
+rmrk = []
+
################################################################################
# Substrate Dependencies
@@ -396,7 +403,7 @@
[dependencies]
log = { version = "0.4.16", default-features = false }
-unique-runtime-common = { path = "../common", default-features = false }
+up-common = { path = "../../primitives/common", default-features = false }
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
@@ -426,6 +433,8 @@
pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
################################################################################
# Build Dependencies
runtime/opal/src/lib.rsdiffbeforeafterboth--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -25,168 +25,21 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
-use sp_api::impl_runtime_apis;
-use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};
-use sp_runtime::DispatchError;
-use fp_self_contained::*;
-// #[cfg(any(feature = "std", test))]
-// pub use sp_runtime::BuildStorage;
-
-use sp_runtime::{
- Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
- traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},
- transaction_validity::{TransactionSource, TransactionValidity},
- ApplyExtrinsicResult, RuntimeAppPublic,
-};
+use frame_support::parameter_types;
-use sp_std::prelude::*;
-
-#[cfg(feature = "std")]
-use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
-pub use pallet_transaction_payment::{
- Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,
-};
-// A few exports that help ease life for downstream crates.
-pub use pallet_balances::Call as BalancesCall;
-pub use pallet_evm::{
- EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
- OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
-};
-pub use frame_support::{
- construct_runtime, match_types,
- dispatch::DispatchResult,
- PalletId, parameter_types, StorageValue, ConsensusEngineId,
- traits::{
- tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
- Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
- OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,
- },
- weights::{
- constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
- DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
- WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
- WeightToFee,
- },
-};
-use pallet_unique_scheduler::DispatchCall;
-use up_data_structs::{
- CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
- CollectionStats, RpcCollection,
- mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
- TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
- RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
- RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
-};
+use sp_runtime::create_runtime_str;
-// use pallet_contracts::weights::WeightInfo;
-// #[cfg(any(feature = "std", test))]
-use frame_system::{
- self as frame_system, EnsureRoot, EnsureSigned,
- limits::{BlockWeights, BlockLength},
-};
-use sp_arithmetic::{
- traits::{BaseArithmetic, Unsigned},
-};
-use smallvec::smallvec;
-// use scale_info::TypeInfo;
-use codec::{Encode, Decode};
-use fp_rpc::TransactionStatus;
-use sp_runtime::{
- traits::{
- Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,
- Saturating, CheckedConversion,
- },
- generic::Era,
- transaction_validity::TransactionValidityError,
- DispatchErrorWithPostInfo, SaturatedConversion,
-};
+use up_common::types::*;
-// pub use pallet_timestamp::Call as TimestampCall;
-pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
+#[path = "../../common/mod.rs"]
+mod runtime_common;
-// Polkadot imports
-use pallet_xcm::XcmPassthrough;
-use polkadot_parachain::primitives::Sibling;
-use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
-use xcm_builder::{
- AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
- EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
- RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
- SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
- ParentIsPreset,
-};
-use xcm_executor::{Config, XcmExecutor, Assets};
-use sp_std::{cmp::Ordering, marker::PhantomData};
-
-use xcm::latest::{
- // Xcm,
- AssetId::{Concrete},
- Fungibility::Fungible as XcmFungible,
- MultiAsset,
- Error as XcmError,
-};
-use xcm_executor::traits::{MatchesFungible, WeightTrader};
-//use xcm_executor::traits::MatchesFungible;
+pub use runtime_common::*;
-use unique_runtime_common::{
- impl_common_runtime_apis,
- types::*,
- constants::*,
- dispatch::{CollectionDispatchT, CollectionDispatch},
- sponsoring::UniqueSponsorshipHandler,
- eth_sponsoring::UniqueEthSponsorshipHandler,
- weights::CommonWeights,
-};
-
pub const RUNTIME_NAME: &str = "opal";
pub const TOKEN_SYMBOL: &str = "OPL";
-
-type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
-impl RuntimeInstance for Runtime {
- type CrossAccountId = self::CrossAccountId;
- type TransactionConverter = self::TransactionConverter;
-
- fn get_transaction_converter() -> TransactionConverter {
- TransactionConverter
- }
-}
-
-/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
-/// never know...
-pub type AccountIndex = u32;
-
-/// Balance of an account.
-pub type Balance = u128;
-
-/// Index of a transaction in the chain.
-pub type Index = u32;
-
-/// A hash of some data used by the chain.
-pub type Hash = sp_core::H256;
-
-/// Digest item type.
-pub type DigestItem = generic::DigestItem;
-
-/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
-/// the specifics of the runtime. They can then be made to be agnostic over specific formats
-/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
-/// to even the core data structures.
-pub mod opaque {
- use sp_std::prelude::*;
- use sp_runtime::impl_opaque_keys;
- use super::Aura;
-
- pub use unique_runtime_common::types::*;
-
- impl_opaque_keys! {
- pub struct SessionKeys {
- pub aura: Aura,
- }
- }
-}
-
/// This runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!(RUNTIME_NAME),
@@ -199,1206 +52,15 @@
state_version: 0,
};
-#[derive(codec::Encode, codec::Decode)]
-pub enum XCMPMessage<XAccountId, XBalance> {
- /// Transfer tokens to the given account from the Parachain account.
- TransferToken(XAccountId, XBalance),
-}
-
-/// The version information used to identify this runtime when compiled natively.
-#[cfg(feature = "std")]
-pub fn native_version() -> NativeVersion {
- NativeVersion {
- runtime_version: VERSION,
- can_author_with: Default::default(),
- }
-}
-
-type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
-
-pub struct DealWithFees;
-impl OnUnbalanced<NegativeImbalance> for DealWithFees {
- fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
- if let Some(fees) = fees_then_tips.next() {
- // for fees, 100% to treasury
- let mut split = fees.ration(100, 0);
- if let Some(tips) = fees_then_tips.next() {
- // for tips, if any, 100% to treasury
- tips.ration_merge_into(100, 0, &mut split);
- }
- Treasury::on_unbalanced(split.0);
- // Author::on_unbalanced(split.1);
- }
- }
-}
-
parameter_types! {
- pub const BlockHashCount: BlockNumber = 2400;
- pub RuntimeBlockLength: BlockLength =
- BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
- pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
- pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
- pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
- .base_block(BlockExecutionWeight::get())
- .for_class(DispatchClass::all(), |weights| {
- weights.base_extrinsic = ExtrinsicBaseWeight::get();
- })
- .for_class(DispatchClass::Normal, |weights| {
- weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
- })
- .for_class(DispatchClass::Operational, |weights| {
- weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
- // Operational transactions have some extra reserved space, so that they
- // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
- weights.reserved = Some(
- MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
- );
- })
- .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
- .build_or_panic();
pub const Version: RuntimeVersion = VERSION;
pub const SS58Prefix: u8 = 42;
-}
-
-parameter_types! {
pub const ChainId: u64 = 8882;
-}
-
-pub struct FixedFee;
-impl FeeCalculator for FixedFee {
- fn min_gas_price() -> (U256, u64) {
- (MIN_GAS_PRICE.into(), 0)
- }
-}
-
-// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
-// (contract, which only writes a lot of data),
-// approximating on top of our real store write weight
-parameter_types! {
- pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
- pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
- pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
}
-/// Limiting EVM execution to 50% of block for substrate users and management tasks
-/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
-/// scheduled fairly
-const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
-parameter_types! {
- pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
-}
-
-pub enum FixedGasWeightMapping {}
-impl GasWeightMapping for FixedGasWeightMapping {
- fn gas_to_weight(gas: u64) -> Weight {
- gas.saturating_mul(WeightPerGas::get())
- }
- fn weight_to_gas(weight: Weight) -> u64 {
- weight / WeightPerGas::get()
- }
-}
-
-impl pallet_evm::account::Config for Runtime {
- type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
- type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
- type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
-}
-
-impl pallet_evm::Config for Runtime {
- type BlockGasLimit = BlockGasLimit;
- type FeeCalculator = FixedFee;
- type GasWeightMapping = FixedGasWeightMapping;
- type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
- type CallOrigin = EnsureAddressTruncated<Self>;
- type WithdrawOrigin = EnsureAddressTruncated<Self>;
- type AddressMapping = HashedAddressMapping<Self::Hashing>;
- type PrecompilesType = ();
- type PrecompilesValue = ();
- type Currency = Balances;
- type Event = Event;
- type OnMethodCall = (
- pallet_evm_migration::OnMethodCall<Self>,
- pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
- CollectionDispatchT<Self>,
- pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
- );
- type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
- type ChainId = ChainId;
- type Runner = pallet_evm::runner::stack::Runner<Self>;
- type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
- type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
- type FindAuthor = EthereumFindAuthor<Aura>;
-}
-
-impl pallet_evm_migration::Config for Runtime {
- type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
-}
-
-pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
-impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
- fn find_author<'a, I>(digests: I) -> Option<H160>
- where
- I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
- {
- if let Some(author_index) = F::find_author(digests) {
- let authority_id = Aura::authorities()[author_index as usize].clone();
- return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
- }
- None
- }
-}
-
-impl pallet_ethereum::Config for Runtime {
- type Event = Event;
- type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
-}
-
-impl pallet_randomness_collective_flip::Config for Runtime {}
-
-impl frame_system::Config for Runtime {
- /// The data to be stored in an account.
- type AccountData = pallet_balances::AccountData<Balance>;
- /// The identifier used to distinguish between accounts.
- type AccountId = AccountId;
- /// The basic call filter to use in dispatchable.
- type BaseCallFilter = Everything;
- /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
- type BlockHashCount = BlockHashCount;
- /// The maximum length of a block (in bytes).
- type BlockLength = RuntimeBlockLength;
- /// The index type for blocks.
- type BlockNumber = BlockNumber;
- /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
- type BlockWeights = RuntimeBlockWeights;
- /// The aggregated dispatch type that is available for extrinsics.
- type Call = Call;
- /// The weight of database operations that the runtime can invoke.
- type DbWeight = RocksDbWeight;
- /// The ubiquitous event type.
- type Event = Event;
- /// The type for hashing blocks and tries.
- type Hash = Hash;
- /// The hashing algorithm used.
- type Hashing = BlakeTwo256;
- /// The header type.
- type Header = generic::Header<BlockNumber, BlakeTwo256>;
- /// The index type for storing how many extrinsics an account has signed.
- type Index = Index;
- /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
- type Lookup = AccountIdLookup<AccountId, ()>;
- /// What to do if an account is fully reaped from the system.
- type OnKilledAccount = ();
- /// What to do if a new account is created.
- type OnNewAccount = ();
- type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
- /// The ubiquitous origin type.
- type Origin = Origin;
- /// This type is being generated by `construct_runtime!`.
- type PalletInfo = PalletInfo;
- /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
- type SS58Prefix = SS58Prefix;
- /// Weight information for the extrinsics of this pallet.
- type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
- /// Version of the runtime.
- type Version = Version;
- type MaxConsumers = ConstU32<16>;
-}
-
-parameter_types! {
- pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
-}
-
-impl pallet_timestamp::Config for Runtime {
- /// A timestamp: milliseconds since the unix epoch.
- type Moment = u64;
- type OnTimestampSet = ();
- type MinimumPeriod = MinimumPeriod;
- type WeightInfo = ();
-}
-
-parameter_types! {
- // pub const ExistentialDeposit: u128 = 500;
- pub const ExistentialDeposit: u128 = 0;
- pub const MaxLocks: u32 = 50;
- pub const MaxReserves: u32 = 50;
-}
-
-impl pallet_balances::Config for Runtime {
- type MaxLocks = MaxLocks;
- type MaxReserves = MaxReserves;
- type ReserveIdentifier = [u8; 16];
- /// The type for recording an account's balance.
- type Balance = Balance;
- /// The ubiquitous event type.
- type Event = Event;
- type DustRemoval = Treasury;
- type ExistentialDeposit = ExistentialDeposit;
- type AccountStore = System;
- type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
-}
-
-pub const fn deposit(items: u32, bytes: u32) -> Balance {
- items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE
-}
-
-/*
-parameter_types! {
- pub TombstoneDeposit: Balance = deposit(
- 1,
- sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,
- );
- pub DepositPerContract: Balance = TombstoneDeposit::get();
- pub const DepositPerStorageByte: Balance = deposit(0, 1);
- pub const DepositPerStorageItem: Balance = deposit(1, 0);
- pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
- pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;
- pub const SignedClaimHandicap: u32 = 2;
- pub const MaxDepth: u32 = 32;
- pub const MaxValueSize: u32 = 16 * 1024;
- pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb
- // The lazy deletion runs inside on_initialize.
- pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
- RuntimeBlockWeights::get().max_block;
- // The weight needed for decoding the queue should be less or equal than a fifth
- // of the overall weight dedicated to the lazy deletion.
- pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
- )) / 5) as u32;
- pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
-}
-
-impl pallet_contracts::Config for Runtime {
- type Time = Timestamp;
- type Randomness = RandomnessCollectiveFlip;
- type Currency = Balances;
- type Event = Event;
- type RentPayment = ();
- type SignedClaimHandicap = SignedClaimHandicap;
- type TombstoneDeposit = TombstoneDeposit;
- type DepositPerContract = DepositPerContract;
- type DepositPerStorageByte = DepositPerStorageByte;
- type DepositPerStorageItem = DepositPerStorageItem;
- type RentFraction = RentFraction;
- type SurchargeReward = SurchargeReward;
- type WeightPrice = pallet_transaction_payment::Pallet<Self>;
- type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
- type ChainExtension = NFTExtension;
- type DeletionQueueDepth = DeletionQueueDepth;
- type DeletionWeightLimit = DeletionWeightLimit;
- type Schedule = Schedule;
- type CallStack = [pallet_contracts::Frame<Self>; 31];
-}
-*/
+construct_runtime!(opal);
-parameter_types! {
- /// This value increases the priority of `Operational` transactions by adding
- /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
- pub const OperationalFeeMultiplier: u8 = 5;
-}
-
-/// Linear implementor of `WeightToFeePolynomial`
-pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
-
-impl<T> WeightToFeePolynomial for LinearFee<T>
-where
- T: BaseArithmetic + From<u32> + Copy + Unsigned,
-{
- type Balance = T;
-
- fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
- smallvec!(WeightToFeeCoefficient {
- coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
- coeff_frac: Perbill::zero(),
- negative: false,
- degree: 1,
- })
- }
-}
-
-impl pallet_transaction_payment::Config for Runtime {
- type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
- type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
- type OperationalFeeMultiplier = OperationalFeeMultiplier;
- type WeightToFee = LinearFee<Balance>;
- type FeeMultiplierUpdate = ();
-}
-
-parameter_types! {
- pub const ProposalBond: Permill = Permill::from_percent(5);
- pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
- pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
- pub const SpendPeriod: BlockNumber = 5 * MINUTES;
- pub const Burn: Permill = Permill::from_percent(0);
- pub const TipCountdown: BlockNumber = 1 * DAYS;
- pub const TipFindersFee: Percent = Percent::from_percent(20);
- pub const TipReportDepositBase: Balance = 1 * UNIQUE;
- pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
- pub const BountyDepositBase: Balance = 1 * UNIQUE;
- pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
- pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
- pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
- pub const MaximumReasonLength: u32 = 16384;
- pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
- pub const BountyValueMinimum: Balance = 5 * UNIQUE;
- pub const MaxApprovals: u32 = 100;
-}
-
-impl pallet_treasury::Config for Runtime {
- type PalletId = TreasuryModuleId;
- type Currency = Balances;
- type ApproveOrigin = EnsureRoot<AccountId>;
- type RejectOrigin = EnsureRoot<AccountId>;
- type Event = Event;
- type OnSlash = ();
- type ProposalBond = ProposalBond;
- type ProposalBondMinimum = ProposalBondMinimum;
- type ProposalBondMaximum = ProposalBondMaximum;
- type SpendPeriod = SpendPeriod;
- type Burn = Burn;
- type BurnDestination = ();
- type SpendFunds = ();
- type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
- type MaxApprovals = MaxApprovals;
-}
-
-impl pallet_sudo::Config for Runtime {
- type Event = Event;
- type Call = Call;
-}
-
-pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
-
-impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
- for RelayChainBlockNumberProvider<T>
-{
- type BlockNumber = BlockNumber;
-
- fn current_block_number() -> Self::BlockNumber {
- cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
- .map(|d| d.relay_parent_number)
- .unwrap_or_default()
- }
-}
-
-parameter_types! {
- pub const MinVestedTransfer: Balance = 10 * UNIQUE;
- pub const MaxVestingSchedules: u32 = 28;
-}
-
-impl orml_vesting::Config for Runtime {
- type Event = Event;
- type Currency = pallet_balances::Pallet<Runtime>;
- type MinVestedTransfer = MinVestedTransfer;
- type VestedTransferOrigin = EnsureSigned<AccountId>;
- type WeightInfo = ();
- type MaxVestingSchedules = MaxVestingSchedules;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-parameter_types! {
- pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
- pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
-}
-
-impl cumulus_pallet_parachain_system::Config for Runtime {
- type Event = Event;
- type SelfParaId = parachain_info::Pallet<Self>;
- type OnSystemEvent = ();
- // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
- // MaxDownwardMessageWeight,
- // XcmExecutor<XcmConfig>,
- // Call,
- // >;
- type OutboundXcmpMessageSource = XcmpQueue;
- type DmpMessageHandler = DmpQueue;
- type ReservedDmpWeight = ReservedDmpWeight;
- type ReservedXcmpWeight = ReservedXcmpWeight;
- type XcmpMessageHandler = XcmpQueue;
-}
-
-impl parachain_info::Config for Runtime {}
-
-impl cumulus_pallet_aura_ext::Config for Runtime {}
-
-parameter_types! {
- pub const RelayLocation: MultiLocation = MultiLocation::parent();
- pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
- pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
- pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
-}
-
-/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
-/// when determining ownership of accounts for asset transacting and when attempting to use XCM
-/// `Transact` in order to determine the dispatch Origin.
-pub type LocationToAccountId = (
- // The parent (Relay-chain) origin converts to the default `AccountId`.
- ParentIsPreset<AccountId>,
- // Sibling parachain origins convert to AccountId via the `ParaId::into`.
- SiblingParachainConvertsVia<Sibling, AccountId>,
- // Straight up local `AccountId32` origins just alias directly to `AccountId`.
- AccountId32Aliases<RelayNetwork, AccountId>,
-);
-
-pub struct OnlySelfCurrency;
-impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
- fn matches_fungible(a: &MultiAsset) -> Option<B> {
- match (&a.id, &a.fun) {
- (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
- _ => None,
- }
- }
-}
-
-/// Means for transacting assets on this chain.
-pub type LocalAssetTransactor = CurrencyAdapter<
- // Use this currency:
- Balances,
- // Use this currency when it is a fungible asset matching the given location or name:
- OnlySelfCurrency,
- // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
- LocationToAccountId,
- // Our chain's account ID type (we can't get away without mentioning it explicitly):
- AccountId,
- // We don't track any teleports.
- (),
->;
-
-/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
-/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
-/// biases the kind of local `Origin` it will become.
-pub type XcmOriginToTransactDispatchOrigin = (
- // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
- // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
- // foreign chains who want to have a local sovereign account on this chain which they control.
- SovereignSignedViaLocation<LocationToAccountId, Origin>,
- // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
- // recognised.
- RelayChainAsNative<RelayOrigin, Origin>,
- // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
- // recognised.
- SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
- // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
- // transaction from the Root origin.
- ParentAsSuperuser<Origin>,
- // Native signed account converter; this just converts an `AccountId32` origin into a normal
- // `Origin::Signed` origin of the same 32-byte value.
- SignedAccountId32AsNative<RelayNetwork, Origin>,
- // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
- XcmPassthrough<Origin>,
-);
-
-parameter_types! {
- // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
- pub UnitWeightCost: Weight = 1_000_000;
- // 1200 UNIQUEs buy 1 second of weight.
- pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
- pub const MaxInstructions: u32 = 100;
- pub const MaxAuthorities: u32 = 100_000;
-}
-
-match_types! {
- pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
- MultiLocation { parents: 1, interior: Here } |
- MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
- };
-}
-
-pub type Barrier = (
- TakeWeightCredit,
- AllowTopLevelPaidExecutionFrom<Everything>,
- // ^^^ Parent & its unit plurality gets free execution
-);
-
-pub struct UsingOnlySelfCurrencyComponents<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
->(
- Weight,
- Currency::Balance,
- PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
-);
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > WeightTrader
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn new() -> Self {
- Self(0, Zero::zero(), PhantomData)
- }
-
- fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
- let amount = WeightToFee::weight_to_fee(&weight);
- let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
-
- // location to this parachain through relay chain
- let option1: xcm::v1::AssetId = Concrete(MultiLocation {
- parents: 1,
- interior: X1(Parachain(ParachainInfo::parachain_id().into())),
- });
- // direct location
- let option2: xcm::v1::AssetId = Concrete(MultiLocation {
- parents: 0,
- interior: Here,
- });
-
- let required = if payment.fungible.contains_key(&option1) {
- (option1, u128_amount).into()
- } else if payment.fungible.contains_key(&option2) {
- (option2, u128_amount).into()
- } else {
- (Concrete(MultiLocation::default()), u128_amount).into()
- };
-
- let unused = payment
- .checked_sub(required)
- .map_err(|_| XcmError::TooExpensive)?;
- self.0 = self.0.saturating_add(weight);
- self.1 = self.1.saturating_add(amount);
- Ok(unused)
- }
-
- fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
- let weight = weight.min(self.0);
- let amount = WeightToFee::weight_to_fee(&weight);
- self.0 -= weight;
- self.1 = self.1.saturating_sub(amount);
- let amount: u128 = amount.saturated_into();
- if amount > 0 {
- Some((AssetId::get(), amount).into())
- } else {
- None
- }
- }
-}
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > Drop
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn drop(&mut self) {
- OnUnbalanced::on_unbalanced(Currency::issue(self.1));
- }
-}
-
-pub struct XcmConfig;
-impl Config for XcmConfig {
- type Call = Call;
- type XcmSender = XcmRouter;
- // How to withdraw and deposit an asset.
- type AssetTransactor = LocalAssetTransactor;
- type OriginConverter = XcmOriginToTransactDispatchOrigin;
- type IsReserve = NativeAsset;
- type IsTeleporter = (); // Teleportation is disabled
- type LocationInverter = LocationInverter<Ancestry>;
- type Barrier = Barrier;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type Trader =
- UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
- type ResponseHandler = (); // Don't handle responses for now.
- type SubscriptionService = PolkadotXcm;
-
- type AssetTrap = PolkadotXcm;
- type AssetClaims = PolkadotXcm;
-}
-
-// parameter_types! {
-// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
-// }
-
-/// No local origins on this chain are allowed to dispatch XCM sends/executions.
-pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
-
-/// The means for routing XCM messages which are not for local execution into the right message
-/// queues.
-pub type XcmRouter = (
- // Two routers - use UMP to communicate with the relay chain:
- cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
- // ..and XCMP to communicate with the sibling chains.
- XcmpQueue,
-);
-
-impl pallet_evm_coder_substrate::Config for Runtime {}
-
-impl pallet_xcm::Config for Runtime {
- type Event = Event;
- type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmRouter = XcmRouter;
- type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmExecuteFilter = Everything;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type XcmTeleportFilter = Everything;
- type XcmReserveTransferFilter = Everything;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type LocationInverter = LocationInverter<Ancestry>;
- type Origin = Origin;
- type Call = Call;
- const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
- type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
-}
-
-impl cumulus_pallet_xcm::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
-}
-
-impl cumulus_pallet_xcmp_queue::Config for Runtime {
- type WeightInfo = ();
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ChannelInfo = ParachainSystem;
- type VersionWrapper = ();
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
- type ControllerOrigin = EnsureRoot<AccountId>;
- type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
-}
-
-impl cumulus_pallet_dmp_queue::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
-}
-
-impl pallet_aura::Config for Runtime {
- type AuthorityId = AuraId;
- type DisabledValidators = ();
- type MaxAuthorities = MaxAuthorities;
-}
-
-parameter_types! {
- pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
- pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
-}
-
-impl pallet_common::Config for Runtime {
- type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
- type Event = Event;
- type Currency = Balances;
- type CollectionCreationPrice = CollectionCreationPrice;
- type TreasuryAccountId = TreasuryAccountId;
- type CollectionDispatch = CollectionDispatchT<Self>;
-
- type EvmTokenAddressMapping = EvmTokenAddressMapping;
- type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
- type ContractAddress = EvmCollectionHelpersAddress;
-}
-
-impl pallet_structure::Config for Runtime {
- type Event = Event;
- type Call = Call;
- type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_fungible::Config for Runtime {
- type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_refungible::Config for Runtime {
- type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_nonfungible::Config for Runtime {
- type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_proxy_rmrk_core::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
- type Event = Event;
-}
-
-impl pallet_proxy_rmrk_equip::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
- type Event = Event;
-}
-
-impl pallet_unique::Config for Runtime {
- type Event = Event;
- type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
- type CommonWeightInfo = CommonWeights<Self>;
- type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
-}
-
-parameter_types! {
- pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
-}
-
-/// Used for the pallet inflation
-impl pallet_inflation::Config for Runtime {
- type Currency = Balances;
- type TreasuryAccountId = TreasuryAccountId;
- type InflationBlockInterval = InflationBlockInterval;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-parameter_types! {
- pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
- RuntimeBlockWeights::get().max_block;
- pub const MaxScheduledPerBlock: u32 = 50;
-}
-
-type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
-use frame_support::traits::NamedReservableCurrency;
-
-fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
- (
- frame_system::CheckSpecVersion::<Runtime>::new(),
- frame_system::CheckGenesis::<Runtime>::new(),
- frame_system::CheckEra::<Runtime>::from(Era::Immortal),
- frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
- from,
- )),
- frame_system::CheckWeight::<Runtime>::new(),
- // sponsoring transaction logic
- // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
- )
-}
-
-pub struct SchedulerPaymentExecutor;
-impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
- DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
-where
- <T as frame_system::Config>::Call: Member
- + Dispatchable<Origin = Origin, Info = DispatchInfo>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
- + GetDispatchInfo
- + From<frame_system::Call<Runtime>>,
- SelfContainedSignedInfo: Send + Sync + 'static,
- Call: From<<T as frame_system::Config>::Call>
- + From<<T as pallet_unique_scheduler::Config>::Call>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
- sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
-{
- fn dispatch_call(
- signer: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<
- Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
- TransactionValidityError,
- > {
- let dispatch_info = call.get_dispatch_info();
- let extrinsic = fp_self_contained::CheckedExtrinsic::<
- AccountId,
- Call,
- SignedExtraScheduler,
- SelfContainedSignedInfo,
- > {
- signed:
- CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
- signer.clone().into(),
- get_signed_extras(signer.into()),
- ),
- function: call.into(),
- };
-
- extrinsic.apply::<Runtime>(&dispatch_info, 0)
- }
-
- fn reserve_balance(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- count: u32,
- ) -> Result<(), DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
- .saturating_mul(count.into());
-
- <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
- &id,
- &(sponsor.into()),
- weight,
- )
- }
-
- fn pay_for_call(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<u128, DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- weight,
- ),
- )
- }
-
- fn cancel_reserve(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- ) -> Result<u128, DispatchError> {
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- u128::MAX,
- ),
- )
- }
-}
-
-parameter_types! {
- pub const NoPreimagePostponement: Option<u32> = Some(10);
- pub const Preimage: Option<u32> = Some(10);
-}
-
-/// Used the compare the privilege of an origin inside the scheduler.
-pub struct OriginPrivilegeCmp;
-
-impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
- fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
- Some(Ordering::Equal)
- }
-}
-
-impl pallet_unique_scheduler::Config for Runtime {
- type Event = Event;
- type Origin = Origin;
- type Currency = Balances;
- type PalletsOrigin = OriginCaller;
- type Call = Call;
- type MaximumWeight = MaximumSchedulerWeight;
- type ScheduleOrigin = EnsureSigned<AccountId>;
- type MaxScheduledPerBlock = MaxScheduledPerBlock;
- type WeightInfo = ();
- type CallExecutor = SchedulerPaymentExecutor;
- type OriginPrivilegeCmp = OriginPrivilegeCmp;
- type PreimageProvider = ();
- type NoPreimagePostponement = NoPreimagePostponement;
-}
-
-type EvmSponsorshipHandler = (
- UniqueEthSponsorshipHandler<Runtime>,
- pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
-);
-
-type SponsorshipHandler = (
- UniqueSponsorshipHandler<Runtime>,
- //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
- pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
-);
-
-impl pallet_evm_transaction_payment::Config for Runtime {
- type EvmSponsorshipHandler = EvmSponsorshipHandler;
- type Currency = Balances;
-}
-
-impl pallet_charge_transaction::Config for Runtime {
- type SponsorshipHandler = SponsorshipHandler;
-}
-
-// impl pallet_contract_helpers::Config for Runtime {
-// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-// }
-
-parameter_types! {
- // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
- pub const HelpersContractAddress: H160 = H160([
- 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
- ]);
-
- // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
- pub const EvmCollectionHelpersAddress: H160 = H160([
- 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
- ]);
-}
-
-impl pallet_evm_contract_helpers::Config for Runtime {
- type ContractAddress = HelpersContractAddress;
- type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
-construct_runtime!(
- pub enum Runtime where
- Block = Block,
- NodeBlock = opaque::Block,
- UncheckedExtrinsic = UncheckedExtrinsic
- {
- ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
- ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
-
- Aura: pallet_aura::{Pallet, Config<T>} = 22,
- AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
-
- Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
- RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
- Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
- TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
- Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
- Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
- System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
- Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
- // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
- // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
-
- // XCM helpers.
- XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
- PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
- CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
- DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
-
- // Unique Pallets
- Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
- Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
- Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
- // free = 63
- Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
- // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
- Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
- Fungible: pallet_fungible::{Pallet, Storage} = 67,
- Refungible: pallet_refungible::{Pallet, Storage} = 68,
- Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
- Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
- RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
- RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
-
- // Frontier
- EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
- Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
-
- EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
- EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
- EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
- EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
- }
-);
-
-pub struct TransactionConverter;
-
-impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
- UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- )
- }
-}
-
-impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(
- &self,
- transaction: pallet_ethereum::Transaction,
- ) -> opaque::UncheckedExtrinsic {
- let extrinsic = UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- );
- let encoded = extrinsic.encode();
- opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
- .expect("Encoded extrinsic is always valid")
- }
-}
-
-/// The address format for describing accounts.
-pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
-/// Block header type as expected by this runtime.
-pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
-/// Block type as expected by this runtime.
-pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-/// A Block signed with a Justification
-pub type SignedBlock = generic::SignedBlock<Block>;
-/// BlockId type as expected by this runtime.
-pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
- frame_system::CheckSpecVersion<Runtime>,
- // system::CheckTxVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
- ChargeTransactionPayment,
- //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
- pallet_ethereum::FakeTransactionFinalizer<Runtime>,
-);
-pub type SignedExtraScheduler = (
- frame_system::CheckSpecVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
-);
-/// Unchecked extrinsic type as expected by this runtime.
-pub type UncheckedExtrinsic =
- fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
-/// Extrinsic type that has already been checked.
-pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
-/// Executive: handles dispatch to the various modules.
-pub type Executive = frame_executive::Executive<
- Runtime,
- Block,
- frame_system::ChainContext<Runtime>,
- Runtime,
- AllPalletsReversedWithSystemFirst,
->;
-
-impl_opaque_keys! {
- pub struct SessionKeys {
- pub aura: Aura,
- }
-}
-
-impl fp_self_contained::SelfContainedCall for Call {
- type SignedInfo = H160;
-
- fn is_self_contained(&self) -> bool {
- match self {
- Call::Ethereum(call) => call.is_self_contained(),
- _ => false,
- }
- }
-
- fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.check_self_contained(),
- _ => None,
- }
- }
-
- fn validate_self_contained(
- &self,
- info: &Self::SignedInfo,
- dispatch_info: &DispatchInfoOf<Call>,
- len: usize,
- ) -> Option<TransactionValidity> {
- match self {
- Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
- _ => None,
- }
- }
-
- fn pre_dispatch_self_contained(
- &self,
- info: &Self::SignedInfo,
- ) -> Option<Result<(), TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
- _ => None,
- }
- }
-
- fn apply_self_contained(
- self,
- info: Self::SignedInfo,
- ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
- match self {
- call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
- Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
- )),
- _ => None,
- }
- }
-}
-
-macro_rules! dispatch_unique_runtime {
- ($collection:ident.$method:ident($($name:ident),*)) => {{
- let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
- let dispatch = collection.as_dyn();
-
- Ok::<_, DispatchError>(dispatch.$method($($name),*))
- }};
-}
-
-impl_common_runtime_apis! {
- #![custom_apis]
-
- 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> {
- pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>()
- }
-
- fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id)
- }
-
- fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id)
- }
-
- fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id)
- }
-
- fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id)
- }
-
- fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys)
- }
-
- fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys)
- }
-
- fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id)
- }
-
- fn nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id)
- }
-
- fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id)
- }
-
- fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id)
- }
-
- fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id)
- }
-
- fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys)
- }
- }
-}
-
-struct CheckInherents;
-
-impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
- fn check_inherents(
- block: &Block,
- relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
- ) -> sp_inherents::CheckInherentsResult {
- let relay_chain_slot = relay_state_proof
- .read_slot()
- .expect("Could not read the relay chain slot from the proof");
-
- let inherent_data =
- cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
- relay_chain_slot,
- sp_std::time::Duration::from_secs(6),
- )
- .create_inherent_data()
- .expect("Could not create the timestamp inherent data");
-
- inherent_data.check_extrinsics(block)
- }
-}
+impl_common_runtime_apis!();
cumulus_pallet_parachain_system::register_validate_block!(
Runtime = Runtime,
runtime/quartz/Cargo.tomldiffbeforeafterboth--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -16,7 +16,7 @@
targets = ['x86_64-unknown-linux-gnu']
[features]
-default = ['std']
+default = ['std', 'quartz-runtime']
runtime-benchmarks = [
'hex-literal',
'frame-benchmarking',
@@ -113,12 +113,17 @@
'xcm/std',
'xcm-builder/std',
'xcm-executor/std',
- 'unique-runtime-common/std',
+ 'up-common/std',
"orml-vesting/std",
]
limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
+quartz-runtime = []
+refungible = []
+scheduler = []
+rmrk = []
+
################################################################################
# Substrate Dependencies
@@ -403,7 +408,7 @@
[dependencies]
log = { version = "0.4.16", default-features = false }
-unique-runtime-common = { path = "../common", default-features = false }
+up-common = { path = "../../primitives/common", default-features = false }
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
@@ -432,6 +437,8 @@
pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
################################################################################
# Build Dependencies
runtime/quartz/src/lib.rsdiffbeforeafterboth--- a/runtime/quartz/src/lib.rs
+++ b/runtime/quartz/src/lib.rs
@@ -25,167 +25,21 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
-use sp_api::impl_runtime_apis;
-use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};
-use sp_runtime::DispatchError;
-use fp_self_contained::*;
-// #[cfg(any(feature = "std", test))]
-// pub use sp_runtime::BuildStorage;
-
-use sp_runtime::{
- Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
- traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},
- transaction_validity::{TransactionSource, TransactionValidity},
- ApplyExtrinsicResult, RuntimeAppPublic,
-};
+use frame_support::parameter_types;
-use sp_std::prelude::*;
-
-#[cfg(feature = "std")]
-use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
-pub use pallet_transaction_payment::{
- Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,
-};
-// A few exports that help ease life for downstream crates.
-pub use pallet_balances::Call as BalancesCall;
-pub use pallet_evm::{
- EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
- OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
-};
-pub use frame_support::{
- construct_runtime, match_types,
- dispatch::DispatchResult,
- PalletId, parameter_types, StorageValue, ConsensusEngineId,
- traits::{
- tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
- Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
- OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,
- },
- weights::{
- constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
- DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
- WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
- WeightToFee,
- },
-};
-use pallet_unique_scheduler::DispatchCall;
-use up_data_structs::{
- CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
- CollectionStats, RpcCollection,
- mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
- TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
- RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
- RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
-};
+use sp_runtime::create_runtime_str;
-// use pallet_contracts::weights::WeightInfo;
-// #[cfg(any(feature = "std", test))]
-use frame_system::{
- self as frame_system, EnsureRoot, EnsureSigned,
- limits::{BlockWeights, BlockLength},
-};
-use sp_arithmetic::{
- traits::{BaseArithmetic, Unsigned},
-};
-use smallvec::smallvec;
-use codec::{Encode, Decode};
-use fp_rpc::TransactionStatus;
-use sp_runtime::{
- traits::{
- Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,
- Saturating, CheckedConversion,
- },
- generic::Era,
- transaction_validity::TransactionValidityError,
- DispatchErrorWithPostInfo, SaturatedConversion,
-};
+use up_common::types::*;
-// pub use pallet_timestamp::Call as TimestampCall;
-pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
+#[path = "../../common/mod.rs"]
+mod runtime_common;
-// Polkadot imports
-use pallet_xcm::XcmPassthrough;
-use polkadot_parachain::primitives::Sibling;
-use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
-use xcm_builder::{
- AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
- EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
- RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
- SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
- ParentIsPreset,
-};
-use xcm_executor::{Config, XcmExecutor, Assets};
-use sp_std::{cmp::Ordering, marker::PhantomData};
-
-use xcm::latest::{
- // Xcm,
- AssetId::{Concrete},
- Fungibility::Fungible as XcmFungible,
- MultiAsset,
- Error as XcmError,
-};
-use xcm_executor::traits::{MatchesFungible, WeightTrader};
+pub use runtime_common::*;
-use unique_runtime_common::{
- impl_common_runtime_apis,
- types::*,
- constants::*,
- dispatch::{CollectionDispatchT, CollectionDispatch},
- sponsoring::UniqueSponsorshipHandler,
- eth_sponsoring::UniqueEthSponsorshipHandler,
- weights::CommonWeights,
-};
-
pub const RUNTIME_NAME: &str = "quartz";
pub const TOKEN_SYMBOL: &str = "QTZ";
-
-type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
-
-impl RuntimeInstance for Runtime {
- type CrossAccountId = self::CrossAccountId;
-
- type TransactionConverter = self::TransactionConverter;
-
- fn get_transaction_converter() -> TransactionConverter {
- TransactionConverter
- }
-}
-
-/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
-/// never know...
-pub type AccountIndex = u32;
-/// Balance of an account.
-pub type Balance = u128;
-
-/// Index of a transaction in the chain.
-pub type Index = u32;
-
-/// A hash of some data used by the chain.
-pub type Hash = sp_core::H256;
-
-/// Digest item type.
-pub type DigestItem = generic::DigestItem;
-
-/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
-/// the specifics of the runtime. They can then be made to be agnostic over specific formats
-/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
-/// to even the core data structures.
-pub mod opaque {
- use sp_std::prelude::*;
- use sp_runtime::impl_opaque_keys;
- use super::Aura;
-
- pub use unique_runtime_common::types::*;
-
- impl_opaque_keys! {
- pub struct SessionKeys {
- pub aura: Aura,
- }
- }
-}
-
/// This runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!(RUNTIME_NAME),
@@ -198,1207 +52,15 @@
state_version: 0,
};
-#[derive(codec::Encode, codec::Decode)]
-pub enum XCMPMessage<XAccountId, XBalance> {
- /// Transfer tokens to the given account from the Parachain account.
- TransferToken(XAccountId, XBalance),
-}
-
-/// The version information used to identify this runtime when compiled natively.
-#[cfg(feature = "std")]
-pub fn native_version() -> NativeVersion {
- NativeVersion {
- runtime_version: VERSION,
- can_author_with: Default::default(),
- }
-}
-
-type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
-
-pub struct DealWithFees;
-impl OnUnbalanced<NegativeImbalance> for DealWithFees {
- fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
- if let Some(fees) = fees_then_tips.next() {
- // for fees, 100% to treasury
- let mut split = fees.ration(100, 0);
- if let Some(tips) = fees_then_tips.next() {
- // for tips, if any, 100% to treasury
- tips.ration_merge_into(100, 0, &mut split);
- }
- Treasury::on_unbalanced(split.0);
- // Author::on_unbalanced(split.1);
- }
- }
-}
-
parameter_types! {
- pub const BlockHashCount: BlockNumber = 2400;
- pub RuntimeBlockLength: BlockLength =
- BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
- pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
- pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
- pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
- .base_block(BlockExecutionWeight::get())
- .for_class(DispatchClass::all(), |weights| {
- weights.base_extrinsic = ExtrinsicBaseWeight::get();
- })
- .for_class(DispatchClass::Normal, |weights| {
- weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
- })
- .for_class(DispatchClass::Operational, |weights| {
- weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
- // Operational transactions have some extra reserved space, so that they
- // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
- weights.reserved = Some(
- MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
- );
- })
- .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
- .build_or_panic();
pub const Version: RuntimeVersion = VERSION;
pub const SS58Prefix: u8 = 255;
-}
-
-parameter_types! {
pub const ChainId: u64 = 8881;
-}
-
-pub struct FixedFee;
-impl FeeCalculator for FixedFee {
- fn min_gas_price() -> (U256, u64) {
- (MIN_GAS_PRICE.into(), 0)
- }
-}
-
-// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
-// (contract, which only writes a lot of data),
-// approximating on top of our real store write weight
-parameter_types! {
- pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
- pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
- pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
-}
-
-/// Limiting EVM execution to 50% of block for substrate users and management tasks
-/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
-/// scheduled fairly
-const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
-parameter_types! {
- pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
}
-pub enum FixedGasWeightMapping {}
-impl GasWeightMapping for FixedGasWeightMapping {
- fn gas_to_weight(gas: u64) -> Weight {
- gas.saturating_mul(WeightPerGas::get())
- }
- fn weight_to_gas(weight: Weight) -> u64 {
- weight / WeightPerGas::get()
- }
-}
-
-impl pallet_evm::account::Config for Runtime {
- type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
- type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;
- type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
-}
-
-impl pallet_evm::Config for Runtime {
- type BlockGasLimit = BlockGasLimit;
- type FeeCalculator = FixedFee;
- type GasWeightMapping = FixedGasWeightMapping;
- type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
- type CallOrigin = EnsureAddressTruncated<Self>;
- type WithdrawOrigin = EnsureAddressTruncated<Self>;
- type AddressMapping = HashedAddressMapping<Self::Hashing>;
- type PrecompilesType = ();
- type PrecompilesValue = ();
- type Currency = Balances;
- type Event = Event;
- type OnMethodCall = (
- pallet_evm_migration::OnMethodCall<Self>,
- pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
- CollectionDispatchT<Self>,
- pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
- );
- type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
- type ChainId = ChainId;
- type Runner = pallet_evm::runner::stack::Runner<Self>;
- type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
- type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
- type FindAuthor = EthereumFindAuthor<Aura>;
-}
-
-impl pallet_evm_migration::Config for Runtime {
- type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
-}
-
-pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
-impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
- fn find_author<'a, I>(digests: I) -> Option<H160>
- where
- I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
- {
- if let Some(author_index) = F::find_author(digests) {
- let authority_id = Aura::authorities()[author_index as usize].clone();
- return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
- }
- None
- }
-}
-
-impl pallet_ethereum::Config for Runtime {
- type Event = Event;
- type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
-}
-
-impl pallet_randomness_collective_flip::Config for Runtime {}
-
-impl frame_system::Config for Runtime {
- /// The data to be stored in an account.
- type AccountData = pallet_balances::AccountData<Balance>;
- /// The identifier used to distinguish between accounts.
- type AccountId = AccountId;
- /// The basic call filter to use in dispatchable.
- type BaseCallFilter = Everything;
- /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
- type BlockHashCount = BlockHashCount;
- /// The maximum length of a block (in bytes).
- type BlockLength = RuntimeBlockLength;
- /// The index type for blocks.
- type BlockNumber = BlockNumber;
- /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
- type BlockWeights = RuntimeBlockWeights;
- /// The aggregated dispatch type that is available for extrinsics.
- type Call = Call;
- /// The weight of database operations that the runtime can invoke.
- type DbWeight = RocksDbWeight;
- /// The ubiquitous event type.
- type Event = Event;
- /// The type for hashing blocks and tries.
- type Hash = Hash;
- /// The hashing algorithm used.
- type Hashing = BlakeTwo256;
- /// The header type.
- type Header = generic::Header<BlockNumber, BlakeTwo256>;
- /// The index type for storing how many extrinsics an account has signed.
- type Index = Index;
- /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
- type Lookup = AccountIdLookup<AccountId, ()>;
- /// What to do if an account is fully reaped from the system.
- type OnKilledAccount = ();
- /// What to do if a new account is created.
- type OnNewAccount = ();
- type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
- /// The ubiquitous origin type.
- type Origin = Origin;
- /// This type is being generated by `construct_runtime!`.
- type PalletInfo = PalletInfo;
- /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
- type SS58Prefix = SS58Prefix;
- /// Weight information for the extrinsics of this pallet.
- type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
- /// Version of the runtime.
- type Version = Version;
- type MaxConsumers = ConstU32<16>;
-}
-
-parameter_types! {
- pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
-}
-
-impl pallet_timestamp::Config for Runtime {
- /// A timestamp: milliseconds since the unix epoch.
- type Moment = u64;
- type OnTimestampSet = ();
- type MinimumPeriod = MinimumPeriod;
- type WeightInfo = ();
-}
-
-parameter_types! {
- // pub const ExistentialDeposit: u128 = 500;
- pub const ExistentialDeposit: u128 = 0;
- pub const MaxLocks: u32 = 50;
- pub const MaxReserves: u32 = 50;
-}
-
-impl pallet_balances::Config for Runtime {
- type MaxLocks = MaxLocks;
- type MaxReserves = MaxReserves;
- type ReserveIdentifier = [u8; 16];
- /// The type for recording an account's balance.
- type Balance = Balance;
- /// The ubiquitous event type.
- type Event = Event;
- type DustRemoval = Treasury;
- type ExistentialDeposit = ExistentialDeposit;
- type AccountStore = System;
- type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
-}
-
-pub const fn deposit(items: u32, bytes: u32) -> Balance {
- items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE
-}
-
-/*
-parameter_types! {
- pub TombstoneDeposit: Balance = deposit(
- 1,
- sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,
- );
- pub DepositPerContract: Balance = TombstoneDeposit::get();
- pub const DepositPerStorageByte: Balance = deposit(0, 1);
- pub const DepositPerStorageItem: Balance = deposit(1, 0);
- pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
- pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;
- pub const SignedClaimHandicap: u32 = 2;
- pub const MaxDepth: u32 = 32;
- pub const MaxValueSize: u32 = 16 * 1024;
- pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb
- // The lazy deletion runs inside on_initialize.
- pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
- RuntimeBlockWeights::get().max_block;
- // The weight needed for decoding the queue should be less or equal than a fifth
- // of the overall weight dedicated to the lazy deletion.
- pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
- )) / 5) as u32;
- pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
-}
-
-impl pallet_contracts::Config for Runtime {
- type Time = Timestamp;
- type Randomness = RandomnessCollectiveFlip;
- type Currency = Balances;
- type Event = Event;
- type RentPayment = ();
- type SignedClaimHandicap = SignedClaimHandicap;
- type TombstoneDeposit = TombstoneDeposit;
- type DepositPerContract = DepositPerContract;
- type DepositPerStorageByte = DepositPerStorageByte;
- type DepositPerStorageItem = DepositPerStorageItem;
- type RentFraction = RentFraction;
- type SurchargeReward = SurchargeReward;
- type WeightPrice = pallet_transaction_payment::Pallet<Self>;
- type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
- type ChainExtension = NFTExtension;
- type DeletionQueueDepth = DeletionQueueDepth;
- type DeletionWeightLimit = DeletionWeightLimit;
- type Schedule = Schedule;
- type CallStack = [pallet_contracts::Frame<Self>; 31];
-}
-*/
+construct_runtime!(quartz);
-parameter_types! {
- /// This value increases the priority of `Operational` transactions by adding
- /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
- pub const OperationalFeeMultiplier: u8 = 5;
-}
-
-/// Linear implementor of `WeightToFeePolynomial`
-pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
-
-impl<T> WeightToFeePolynomial for LinearFee<T>
-where
- T: BaseArithmetic + From<u32> + Copy + Unsigned,
-{
- type Balance = T;
-
- fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
- smallvec!(WeightToFeeCoefficient {
- coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
- coeff_frac: Perbill::zero(),
- negative: false,
- degree: 1,
- })
- }
-}
-
-impl pallet_transaction_payment::Config for Runtime {
- type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
- type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
- type OperationalFeeMultiplier = OperationalFeeMultiplier;
- type WeightToFee = LinearFee<Balance>;
- type FeeMultiplierUpdate = ();
-}
-
-parameter_types! {
- pub const ProposalBond: Permill = Permill::from_percent(5);
- pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
- pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
- pub const SpendPeriod: BlockNumber = 5 * MINUTES;
- pub const Burn: Permill = Permill::from_percent(0);
- pub const TipCountdown: BlockNumber = 1 * DAYS;
- pub const TipFindersFee: Percent = Percent::from_percent(20);
- pub const TipReportDepositBase: Balance = 1 * UNIQUE;
- pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
- pub const BountyDepositBase: Balance = 1 * UNIQUE;
- pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
- pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
- pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
- pub const MaximumReasonLength: u32 = 16384;
- pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
- pub const BountyValueMinimum: Balance = 5 * UNIQUE;
- pub const MaxApprovals: u32 = 100;
-}
-
-impl pallet_treasury::Config for Runtime {
- type PalletId = TreasuryModuleId;
- type Currency = Balances;
- type ApproveOrigin = EnsureRoot<AccountId>;
- type RejectOrigin = EnsureRoot<AccountId>;
- type Event = Event;
- type OnSlash = ();
- type ProposalBond = ProposalBond;
- type ProposalBondMinimum = ProposalBondMinimum;
- type ProposalBondMaximum = ProposalBondMaximum;
- type SpendPeriod = SpendPeriod;
- type Burn = Burn;
- type BurnDestination = ();
- type SpendFunds = ();
- type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
- type MaxApprovals = MaxApprovals;
-}
-
-impl pallet_sudo::Config for Runtime {
- type Event = Event;
- type Call = Call;
-}
-
-pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
-
-impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
- for RelayChainBlockNumberProvider<T>
-{
- type BlockNumber = BlockNumber;
-
- fn current_block_number() -> Self::BlockNumber {
- cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
- .map(|d| d.relay_parent_number)
- .unwrap_or_default()
- }
-}
-
-parameter_types! {
- pub const MinVestedTransfer: Balance = 10 * UNIQUE;
- pub const MaxVestingSchedules: u32 = 28;
-}
-
-impl orml_vesting::Config for Runtime {
- type Event = Event;
- type Currency = pallet_balances::Pallet<Runtime>;
- type MinVestedTransfer = MinVestedTransfer;
- type VestedTransferOrigin = EnsureSigned<AccountId>;
- type WeightInfo = ();
- type MaxVestingSchedules = MaxVestingSchedules;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-parameter_types! {
- pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
- pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
-}
-
-impl cumulus_pallet_parachain_system::Config for Runtime {
- type Event = Event;
- type SelfParaId = parachain_info::Pallet<Self>;
- type OnSystemEvent = ();
- // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
- // MaxDownwardMessageWeight,
- // XcmExecutor<XcmConfig>,
- // Call,
- // >;
- type OutboundXcmpMessageSource = XcmpQueue;
- type DmpMessageHandler = DmpQueue;
- type ReservedDmpWeight = ReservedDmpWeight;
- type ReservedXcmpWeight = ReservedXcmpWeight;
- type XcmpMessageHandler = XcmpQueue;
-}
-
-impl parachain_info::Config for Runtime {}
-
-impl cumulus_pallet_aura_ext::Config for Runtime {}
-
-parameter_types! {
- pub const RelayLocation: MultiLocation = MultiLocation::parent();
- pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
- pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
- pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
-}
-
-/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
-/// when determining ownership of accounts for asset transacting and when attempting to use XCM
-/// `Transact` in order to determine the dispatch Origin.
-pub type LocationToAccountId = (
- // The parent (Relay-chain) origin converts to the default `AccountId`.
- ParentIsPreset<AccountId>,
- // Sibling parachain origins convert to AccountId via the `ParaId::into`.
- SiblingParachainConvertsVia<Sibling, AccountId>,
- // Straight up local `AccountId32` origins just alias directly to `AccountId`.
- AccountId32Aliases<RelayNetwork, AccountId>,
-);
-
-pub struct OnlySelfCurrency;
-impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
- fn matches_fungible(a: &MultiAsset) -> Option<B> {
- match (&a.id, &a.fun) {
- (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
- _ => None,
- }
- }
-}
-
-/// Means for transacting assets on this chain.
-pub type LocalAssetTransactor = CurrencyAdapter<
- // Use this currency:
- Balances,
- // Use this currency when it is a fungible asset matching the given location or name:
- OnlySelfCurrency,
- // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
- LocationToAccountId,
- // Our chain's account ID type (we can't get away without mentioning it explicitly):
- AccountId,
- // We don't track any teleports.
- (),
->;
-
-/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
-/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
-/// biases the kind of local `Origin` it will become.
-pub type XcmOriginToTransactDispatchOrigin = (
- // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
- // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
- // foreign chains who want to have a local sovereign account on this chain which they control.
- SovereignSignedViaLocation<LocationToAccountId, Origin>,
- // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
- // recognised.
- RelayChainAsNative<RelayOrigin, Origin>,
- // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
- // recognised.
- SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
- // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
- // transaction from the Root origin.
- ParentAsSuperuser<Origin>,
- // Native signed account converter; this just converts an `AccountId32` origin into a normal
- // `Origin::Signed` origin of the same 32-byte value.
- SignedAccountId32AsNative<RelayNetwork, Origin>,
- // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
- XcmPassthrough<Origin>,
-);
-
-parameter_types! {
- // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
- pub UnitWeightCost: Weight = 1_000_000;
- // 1200 UNIQUEs buy 1 second of weight.
- pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
- pub const MaxInstructions: u32 = 100;
- pub const MaxAuthorities: u32 = 100_000;
-}
-
-match_types! {
- pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
- MultiLocation { parents: 1, interior: Here } |
- MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
- };
-}
-
-pub type Barrier = (
- TakeWeightCredit,
- AllowTopLevelPaidExecutionFrom<Everything>,
- // ^^^ Parent & its unit plurality gets free execution
-);
-
-pub struct UsingOnlySelfCurrencyComponents<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
->(
- Weight,
- Currency::Balance,
- PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
-);
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > WeightTrader
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn new() -> Self {
- Self(0, Zero::zero(), PhantomData)
- }
-
- fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
- let amount = WeightToFee::weight_to_fee(&weight);
- let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
-
- // location to this parachain through relay chain
- let option1: xcm::v1::AssetId = Concrete(MultiLocation {
- parents: 1,
- interior: X1(Parachain(ParachainInfo::parachain_id().into())),
- });
- // direct location
- let option2: xcm::v1::AssetId = Concrete(MultiLocation {
- parents: 0,
- interior: Here,
- });
-
- let required = if payment.fungible.contains_key(&option1) {
- (option1, u128_amount).into()
- } else if payment.fungible.contains_key(&option2) {
- (option2, u128_amount).into()
- } else {
- (Concrete(MultiLocation::default()), u128_amount).into()
- };
-
- let unused = payment
- .checked_sub(required)
- .map_err(|_| XcmError::TooExpensive)?;
- self.0 = self.0.saturating_add(weight);
- self.1 = self.1.saturating_add(amount);
- Ok(unused)
- }
-
- fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
- let weight = weight.min(self.0);
- let amount = WeightToFee::weight_to_fee(&weight);
- self.0 -= weight;
- self.1 = self.1.saturating_sub(amount);
- let amount: u128 = amount.saturated_into();
- if amount > 0 {
- Some((AssetId::get(), amount).into())
- } else {
- None
- }
- }
-}
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > Drop
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn drop(&mut self) {
- OnUnbalanced::on_unbalanced(Currency::issue(self.1));
- }
-}
-
-pub struct XcmConfig;
-impl Config for XcmConfig {
- type Call = Call;
- type XcmSender = XcmRouter;
- // How to withdraw and deposit an asset.
- type AssetTransactor = LocalAssetTransactor;
- type OriginConverter = XcmOriginToTransactDispatchOrigin;
- type IsReserve = NativeAsset;
- type IsTeleporter = (); // Teleportation is disabled
- type LocationInverter = LocationInverter<Ancestry>;
- type Barrier = Barrier;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type Trader =
- UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
- type ResponseHandler = (); // Don't handle responses for now.
- type SubscriptionService = PolkadotXcm;
-
- type AssetTrap = PolkadotXcm;
- type AssetClaims = PolkadotXcm;
-}
-
-// parameter_types! {
-// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
-// }
-
-/// No local origins on this chain are allowed to dispatch XCM sends/executions.
-pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
-
-/// The means for routing XCM messages which are not for local execution into the right message
-/// queues.
-pub type XcmRouter = (
- // Two routers - use UMP to communicate with the relay chain:
- cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
- // ..and XCMP to communicate with the sibling chains.
- XcmpQueue,
-);
-
-impl pallet_evm_coder_substrate::Config for Runtime {}
-
-impl pallet_xcm::Config for Runtime {
- type Event = Event;
- type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmRouter = XcmRouter;
- type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmExecuteFilter = Everything;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type XcmTeleportFilter = Everything;
- type XcmReserveTransferFilter = Everything;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type LocationInverter = LocationInverter<Ancestry>;
- type Origin = Origin;
- type Call = Call;
- const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
- type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
-}
-
-impl cumulus_pallet_xcm::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
-}
-
-impl cumulus_pallet_xcmp_queue::Config for Runtime {
- type WeightInfo = ();
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ChannelInfo = ParachainSystem;
- type VersionWrapper = ();
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
- type ControllerOrigin = EnsureRoot<AccountId>;
- type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
-}
-
-impl cumulus_pallet_dmp_queue::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
-}
-
-impl pallet_aura::Config for Runtime {
- type AuthorityId = AuraId;
- type DisabledValidators = ();
- type MaxAuthorities = MaxAuthorities;
-}
-
-parameter_types! {
- pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
- pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
-}
-
-impl pallet_common::Config for Runtime {
- type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
- type Event = Event;
- type Currency = Balances;
- type CollectionCreationPrice = CollectionCreationPrice;
- type TreasuryAccountId = TreasuryAccountId;
- type CollectionDispatch = CollectionDispatchT<Self>;
-
- type EvmTokenAddressMapping = EvmTokenAddressMapping;
- type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
- type ContractAddress = EvmCollectionHelpersAddress;
-}
-
-impl pallet_structure::Config for Runtime {
- type Event = Event;
- type Call = Call;
- type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_fungible::Config for Runtime {
- type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_refungible::Config for Runtime {
- type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_nonfungible::Config for Runtime {
- type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_proxy_rmrk_core::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
- type Event = Event;
-}
-
-impl pallet_proxy_rmrk_equip::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
- type Event = Event;
-}
-
-impl pallet_unique::Config for Runtime {
- type Event = Event;
- type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
- type CommonWeightInfo = CommonWeights<Self>;
- type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
-}
-
-parameter_types! {
- pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
-}
-
-/// Used for the pallet inflation
-impl pallet_inflation::Config for Runtime {
- type Currency = Balances;
- type TreasuryAccountId = TreasuryAccountId;
- type InflationBlockInterval = InflationBlockInterval;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-parameter_types! {
- pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
- RuntimeBlockWeights::get().max_block;
- pub const MaxScheduledPerBlock: u32 = 50;
-}
-
-type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
-use frame_support::traits::NamedReservableCurrency;
-
-fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
- (
- frame_system::CheckSpecVersion::<Runtime>::new(),
- frame_system::CheckGenesis::<Runtime>::new(),
- frame_system::CheckEra::<Runtime>::from(Era::Immortal),
- frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
- from,
- )),
- frame_system::CheckWeight::<Runtime>::new(),
- // sponsoring transaction logic
- // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
- )
-}
-
-pub struct SchedulerPaymentExecutor;
-impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
- DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
-where
- <T as frame_system::Config>::Call: Member
- + Dispatchable<Origin = Origin, Info = DispatchInfo>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
- + GetDispatchInfo
- + From<frame_system::Call<Runtime>>,
- SelfContainedSignedInfo: Send + Sync + 'static,
- Call: From<<T as frame_system::Config>::Call>
- + From<<T as pallet_unique_scheduler::Config>::Call>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
- sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
-{
- fn dispatch_call(
- signer: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<
- Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
- TransactionValidityError,
- > {
- let dispatch_info = call.get_dispatch_info();
- let extrinsic = fp_self_contained::CheckedExtrinsic::<
- AccountId,
- Call,
- SignedExtraScheduler,
- SelfContainedSignedInfo,
- > {
- signed:
- CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
- signer.clone().into(),
- get_signed_extras(signer.into()),
- ),
- function: call.into(),
- };
-
- extrinsic.apply::<Runtime>(&dispatch_info, 0)
- }
-
- fn reserve_balance(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- count: u32,
- ) -> Result<(), DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
- .saturating_mul(count.into());
-
- <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
- &id,
- &(sponsor.into()),
- weight.into(),
- )
- }
-
- fn pay_for_call(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<u128, DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- weight.into(),
- ),
- )
- }
-
- fn cancel_reserve(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- ) -> Result<u128, DispatchError> {
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- u128::MAX,
- ),
- )
- }
-}
-
-parameter_types! {
- pub const NoPreimagePostponement: Option<u32> = Some(10);
- pub const Preimage: Option<u32> = Some(10);
-}
-
-/// Used the compare the privilege of an origin inside the scheduler.
-pub struct OriginPrivilegeCmp;
-
-impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
- fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
- Some(Ordering::Equal)
- }
-}
-
-impl pallet_unique_scheduler::Config for Runtime {
- type Event = Event;
- type Origin = Origin;
- type Currency = Balances;
- type PalletsOrigin = OriginCaller;
- type Call = Call;
- type MaximumWeight = MaximumSchedulerWeight;
- type ScheduleOrigin = EnsureSigned<AccountId>;
- type MaxScheduledPerBlock = MaxScheduledPerBlock;
- type WeightInfo = ();
- type CallExecutor = SchedulerPaymentExecutor;
- type OriginPrivilegeCmp = OriginPrivilegeCmp;
- type PreimageProvider = ();
- type NoPreimagePostponement = NoPreimagePostponement;
-}
-
-type EvmSponsorshipHandler = (
- UniqueEthSponsorshipHandler<Runtime>,
- pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
-);
-type SponsorshipHandler = (
- UniqueSponsorshipHandler<Runtime>,
- //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
- pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
-);
-
-impl pallet_evm_transaction_payment::Config for Runtime {
- type EvmSponsorshipHandler = EvmSponsorshipHandler;
- type Currency = Balances;
-}
-
-impl pallet_charge_transaction::Config for Runtime {
- type SponsorshipHandler = SponsorshipHandler;
-}
-
-// impl pallet_contract_helpers::Config for Runtime {
-// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-// }
-
-parameter_types! {
- // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
- pub const HelpersContractAddress: H160 = H160([
- 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
- ]);
-
- // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
- pub const EvmCollectionHelpersAddress: H160 = H160([
- 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
- ]);
-}
-
-impl pallet_evm_contract_helpers::Config for Runtime {
- type ContractAddress = HelpersContractAddress;
- type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
-construct_runtime!(
- pub enum Runtime where
- Block = Block,
- NodeBlock = opaque::Block,
- UncheckedExtrinsic = UncheckedExtrinsic
- {
- ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
- ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
-
- Aura: pallet_aura::{Pallet, Config<T>} = 22,
- AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
-
- Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
- RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
- Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
- TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
- Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
- Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
- System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
- Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
- // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
- // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
-
- // XCM helpers.
- XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
- PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
- CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
- DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
-
- // Unique Pallets
- Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
- Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
- Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
- // free = 63
- Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
- // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
- Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
- Fungible: pallet_fungible::{Pallet, Storage} = 67,
- Refungible: pallet_refungible::{Pallet, Storage} = 68,
- Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
- Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
- RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
- RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
-
- // Frontier
- EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
- Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
-
- EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
- EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
- EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
- EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
- }
-);
-
-pub struct TransactionConverter;
-
-impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
- UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- )
- }
-}
-
-impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(
- &self,
- transaction: pallet_ethereum::Transaction,
- ) -> opaque::UncheckedExtrinsic {
- let extrinsic = UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- );
- let encoded = extrinsic.encode();
- opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
- .expect("Encoded extrinsic is always valid")
- }
-}
-
-/// The address format for describing accounts.
-pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
-/// Block header type as expected by this runtime.
-pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
-/// Block type as expected by this runtime.
-pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-/// A Block signed with a Justification
-pub type SignedBlock = generic::SignedBlock<Block>;
-/// BlockId type as expected by this runtime.
-pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
- frame_system::CheckSpecVersion<Runtime>,
- // system::CheckTxVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
- ChargeTransactionPayment,
- //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
- pallet_ethereum::FakeTransactionFinalizer<Runtime>,
-);
-
-pub type SignedExtraScheduler = (
- frame_system::CheckSpecVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
- // pallet_charge_transaction::ChargeTransactionPayment<Runtime>,
-);
-/// Unchecked extrinsic type as expected by this runtime.
-pub type UncheckedExtrinsic =
- fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
-/// Extrinsic type that has already been checked.
-pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
-/// Executive: handles dispatch to the various modules.
-pub type Executive = frame_executive::Executive<
- Runtime,
- Block,
- frame_system::ChainContext<Runtime>,
- Runtime,
- AllPalletsReversedWithSystemFirst,
->;
-
-impl_opaque_keys! {
- pub struct SessionKeys {
- pub aura: Aura,
- }
-}
-
-impl fp_self_contained::SelfContainedCall for Call {
- type SignedInfo = H160;
-
- fn is_self_contained(&self) -> bool {
- match self {
- Call::Ethereum(call) => call.is_self_contained(),
- _ => false,
- }
- }
-
- fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.check_self_contained(),
- _ => None,
- }
- }
-
- fn validate_self_contained(
- &self,
- info: &Self::SignedInfo,
- dispatch_info: &DispatchInfoOf<Call>,
- len: usize,
- ) -> Option<TransactionValidity> {
- match self {
- Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
- _ => None,
- }
- }
-
- fn pre_dispatch_self_contained(
- &self,
- info: &Self::SignedInfo,
- ) -> Option<Result<(), TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
- _ => None,
- }
- }
-
- fn apply_self_contained(
- self,
- info: Self::SignedInfo,
- ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
- match self {
- call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
- Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
- )),
- _ => None,
- }
- }
-}
-
-macro_rules! dispatch_unique_runtime {
- ($collection:ident.$method:ident($($name:ident),*)) => {{
- let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
- let dispatch = collection.as_dyn();
-
- Ok::<_, DispatchError>(dispatch.$method($($name),*))
- }};
-}
-
-impl_common_runtime_apis! {
- #![custom_apis]
-
- 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> {
- pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>()
- }
-
- fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id)
- }
-
- fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id)
- }
-
- fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id)
- }
-
- fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id)
- }
-
- fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys)
- }
-
- fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys)
- }
-
- fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id)
- }
-
- fn nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
- pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id)
- }
-
- fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id)
- }
-
- fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id)
- }
-
- fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id)
- }
-
- fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
- pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys)
- }
- }
-}
-
-struct CheckInherents;
-
-impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
- fn check_inherents(
- block: &Block,
- relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
- ) -> sp_inherents::CheckInherentsResult {
- let relay_chain_slot = relay_state_proof
- .read_slot()
- .expect("Could not read the relay chain slot from the proof");
-
- let inherent_data =
- cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
- relay_chain_slot,
- sp_std::time::Duration::from_secs(6),
- )
- .create_inherent_data()
- .expect("Could not create the timestamp inherent data");
-
- inherent_data.check_extrinsics(block)
- }
-}
+impl_common_runtime_apis!();
cumulus_pallet_parachain_system::register_validate_block!(
Runtime = Runtime,
runtime/tests/Cargo.tomldiffbeforeafterboth--- a/runtime/tests/Cargo.toml
+++ b/runtime/tests/Cargo.toml
@@ -3,8 +3,12 @@
version = "0.1.0"
edition = "2021"
+[features]
+default = ['refungible']
+
+refungible = []
+
[dependencies]
-unique-runtime-common = { path = '../common' }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
sp-core = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.24' }
@@ -37,3 +41,6 @@
"derive",
] }
scale-info = "*"
+
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
runtime/tests/src/lib.rsdiffbeforeafterboth--- a/runtime/tests/src/lib.rs
+++ b/runtime/tests/src/lib.rs
@@ -35,9 +35,18 @@
use parity_scale_codec::{Encode, Decode, MaxEncodedLen};
use scale_info::TypeInfo;
-use unique_runtime_common::{dispatch::CollectionDispatchT, weights::CommonWeights};
use up_data_structs::mapping::{CrossTokenAddressMapping, EvmTokenAddressMapping};
+#[path = "../../common/dispatch.rs"]
+mod dispatch;
+
+use dispatch::CollectionDispatchT;
+
+#[path = "../../common/weights.rs"]
+mod weights;
+
+use weights::CommonWeights;
+
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;
runtime/unique/Cargo.tomldiffbeforeafterboth--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -114,13 +114,17 @@
'xcm/std',
'xcm-builder/std',
'xcm-executor/std',
- 'unique-runtime-common/std',
+ 'up-common/std',
"orml-vesting/std",
]
limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
unique-runtime = []
+refungible = []
+scheduler = []
+rmrk = []
+
################################################################################
# Substrate Dependencies
@@ -397,7 +401,7 @@
[dependencies]
log = { version = "0.4.16", default-features = false }
-unique-runtime-common = { path = "../common", default-features = false }
+up-common = { path = "../../primitives/common", default-features = false }
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
@@ -427,6 +431,8 @@
fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
################################################################################
# Build Dependencies
runtime/unique/src/lib.rsdiffbeforeafterboth--- a/runtime/unique/src/lib.rs
+++ b/runtime/unique/src/lib.rs
@@ -25,166 +25,21 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
-use sp_api::impl_runtime_apis;
-use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};
-use sp_runtime::DispatchError;
-use fp_self_contained::*;
-// #[cfg(any(feature = "std", test))]
-// pub use sp_runtime::BuildStorage;
-
-use sp_runtime::{
- Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
- traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},
- transaction_validity::{TransactionSource, TransactionValidity},
- ApplyExtrinsicResult, RuntimeAppPublic,
-};
-
-use sp_std::prelude::*;
+use frame_support::parameter_types;
-#[cfg(feature = "std")]
-use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
-pub use pallet_transaction_payment::{
- Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,
-};
-// A few exports that help ease life for downstream crates.
-pub use pallet_balances::Call as BalancesCall;
-pub use pallet_evm::{
- EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
- OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
-};
-pub use frame_support::{
- construct_runtime, match_types,
- dispatch::DispatchResult,
- PalletId, parameter_types, StorageValue, ConsensusEngineId,
- traits::{
- tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
- Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
- OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,
- },
- weights::{
- constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
- DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
- WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
- WeightToFee,
- },
-};
-use pallet_unique_scheduler::DispatchCall;
-use up_data_structs::{
- CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
- CollectionStats, RpcCollection,
- mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
- TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
- RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
- RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
-};
+use sp_runtime::create_runtime_str;
-// use pallet_contracts::weights::WeightInfo;
-// #[cfg(any(feature = "std", test))]
-use frame_system::{
- self as frame_system, EnsureRoot, EnsureSigned,
- limits::{BlockWeights, BlockLength},
-};
-use sp_arithmetic::{
- traits::{BaseArithmetic, Unsigned},
-};
-use smallvec::smallvec;
-use codec::{Encode, Decode};
-use fp_rpc::TransactionStatus;
-use sp_runtime::{
- traits::{
- Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,
- Saturating, CheckedConversion,
- },
- generic::Era,
- transaction_validity::TransactionValidityError,
- DispatchErrorWithPostInfo, SaturatedConversion,
-};
+use up_common::types::*;
-// pub use pallet_timestamp::Call as TimestampCall;
-pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
+#[path = "../../common/mod.rs"]
+mod runtime_common;
-// Polkadot imports
-use pallet_xcm::XcmPassthrough;
-use polkadot_parachain::primitives::Sibling;
-use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
-use xcm_builder::{
- AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
- EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
- RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
- SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
- ParentIsPreset,
-};
-use xcm_executor::{Config, XcmExecutor, Assets};
-use sp_std::{cmp::Ordering, marker::PhantomData};
-
-use xcm::latest::{
- // Xcm,
- AssetId::{Concrete},
- Fungibility::Fungible as XcmFungible,
- MultiAsset,
- Error as XcmError,
-};
-use xcm_executor::traits::{MatchesFungible, WeightTrader};
-
-use unique_runtime_common::{
- impl_common_runtime_apis,
- types::*,
- constants::*,
- dispatch::{CollectionDispatchT, CollectionDispatch},
- sponsoring::UniqueSponsorshipHandler,
- eth_sponsoring::UniqueEthSponsorshipHandler,
- weights::CommonWeights,
-};
+pub use runtime_common::*;
pub const RUNTIME_NAME: &str = "unique";
pub const TOKEN_SYMBOL: &str = "UNQ";
-
-type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
-
-impl RuntimeInstance for Runtime {
- type CrossAccountId = self::CrossAccountId;
- type TransactionConverter = self::TransactionConverter;
-
- fn get_transaction_converter() -> TransactionConverter {
- TransactionConverter
- }
-}
-
-/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
-/// never know...
-pub type AccountIndex = u32;
-
-/// Balance of an account.
-pub type Balance = u128;
-
-/// Index of a transaction in the chain.
-pub type Index = u32;
-
-/// A hash of some data used by the chain.
-pub type Hash = sp_core::H256;
-
-/// Digest item type.
-pub type DigestItem = generic::DigestItem;
-
-/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
-/// the specifics of the runtime. They can then be made to be agnostic over specific formats
-/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
-/// to even the core data structures.
-pub mod opaque {
- use sp_std::prelude::*;
- use sp_runtime::impl_opaque_keys;
- use super::Aura;
-
- pub use unique_runtime_common::types::*;
- impl_opaque_keys! {
- pub struct SessionKeys {
- pub aura: Aura,
- }
- }
-}
-
/// This runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!(RUNTIME_NAME),
@@ -197,1194 +52,15 @@
state_version: 0,
};
-#[derive(codec::Encode, codec::Decode)]
-pub enum XCMPMessage<XAccountId, XBalance> {
- /// Transfer tokens to the given account from the Parachain account.
- TransferToken(XAccountId, XBalance),
-}
-
-/// The version information used to identify this runtime when compiled natively.
-#[cfg(feature = "std")]
-pub fn native_version() -> NativeVersion {
- NativeVersion {
- runtime_version: VERSION,
- can_author_with: Default::default(),
- }
-}
-
-type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
-
-pub struct DealWithFees;
-impl OnUnbalanced<NegativeImbalance> for DealWithFees {
- fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
- if let Some(fees) = fees_then_tips.next() {
- // for fees, 100% to treasury
- let mut split = fees.ration(100, 0);
- if let Some(tips) = fees_then_tips.next() {
- // for tips, if any, 100% to treasury
- tips.ration_merge_into(100, 0, &mut split);
- }
- Treasury::on_unbalanced(split.0);
- // Author::on_unbalanced(split.1);
- }
- }
-}
-
parameter_types! {
- pub const BlockHashCount: BlockNumber = 2400;
- pub RuntimeBlockLength: BlockLength =
- BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
- pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
- pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
- pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
- .base_block(BlockExecutionWeight::get())
- .for_class(DispatchClass::all(), |weights| {
- weights.base_extrinsic = ExtrinsicBaseWeight::get();
- })
- .for_class(DispatchClass::Normal, |weights| {
- weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
- })
- .for_class(DispatchClass::Operational, |weights| {
- weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
- // Operational transactions have some extra reserved space, so that they
- // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
- weights.reserved = Some(
- MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
- );
- })
- .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
- .build_or_panic();
pub const Version: RuntimeVersion = VERSION;
pub const SS58Prefix: u16 = 7391;
-}
-
-parameter_types! {
pub const ChainId: u64 = 8880;
-}
-
-pub struct FixedFee;
-impl FeeCalculator for FixedFee {
- fn min_gas_price() -> (U256, u64) {
- (MIN_GAS_PRICE.into(), 0)
- }
-}
-
-// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
-// (contract, which only writes a lot of data),
-// approximating on top of our real store write weight
-parameter_types! {
- pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
- pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
- pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
}
-/// Limiting EVM execution to 50% of block for substrate users and management tasks
-/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
-/// scheduled fairly
-const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
-parameter_types! {
- pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
-}
-
-pub enum FixedGasWeightMapping {}
-impl GasWeightMapping for FixedGasWeightMapping {
- fn gas_to_weight(gas: u64) -> Weight {
- gas.saturating_mul(WeightPerGas::get())
- }
- fn weight_to_gas(weight: Weight) -> u64 {
- weight / WeightPerGas::get()
- }
-}
-
-impl pallet_evm::account::Config for Runtime {
- type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
- type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
- type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
-}
-
-impl pallet_evm::Config for Runtime {
- type BlockGasLimit = BlockGasLimit;
- type FeeCalculator = FixedFee;
- type GasWeightMapping = FixedGasWeightMapping;
- type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
- type CallOrigin = EnsureAddressTruncated<Self>;
- type WithdrawOrigin = EnsureAddressTruncated<Self>;
- type AddressMapping = HashedAddressMapping<Self::Hashing>;
- type PrecompilesType = ();
- type PrecompilesValue = ();
- type Currency = Balances;
- type Event = Event;
- type OnMethodCall = (
- pallet_evm_migration::OnMethodCall<Self>,
- pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
- CollectionDispatchT<Self>,
- pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
- );
- type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
- type ChainId = ChainId;
- type Runner = pallet_evm::runner::stack::Runner<Self>;
- type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
- type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
- type FindAuthor = EthereumFindAuthor<Aura>;
-}
-
-impl pallet_evm_migration::Config for Runtime {
- type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
-}
-
-pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
-impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
- fn find_author<'a, I>(digests: I) -> Option<H160>
- where
- I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
- {
- if let Some(author_index) = F::find_author(digests) {
- let authority_id = Aura::authorities()[author_index as usize].clone();
- return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
- }
- None
- }
-}
-
-impl pallet_ethereum::Config for Runtime {
- type Event = Event;
- type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
-}
-
-impl pallet_randomness_collective_flip::Config for Runtime {}
+construct_runtime!(unique);
-impl frame_system::Config for Runtime {
- /// The data to be stored in an account.
- type AccountData = pallet_balances::AccountData<Balance>;
- /// The identifier used to distinguish between accounts.
- type AccountId = AccountId;
- /// The basic call filter to use in dispatchable.
- type BaseCallFilter = Everything;
- /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
- type BlockHashCount = BlockHashCount;
- /// The maximum length of a block (in bytes).
- type BlockLength = RuntimeBlockLength;
- /// The index type for blocks.
- type BlockNumber = BlockNumber;
- /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
- type BlockWeights = RuntimeBlockWeights;
- /// The aggregated dispatch type that is available for extrinsics.
- type Call = Call;
- /// The weight of database operations that the runtime can invoke.
- type DbWeight = RocksDbWeight;
- /// The ubiquitous event type.
- type Event = Event;
- /// The type for hashing blocks and tries.
- type Hash = Hash;
- /// The hashing algorithm used.
- type Hashing = BlakeTwo256;
- /// The header type.
- type Header = generic::Header<BlockNumber, BlakeTwo256>;
- /// The index type for storing how many extrinsics an account has signed.
- type Index = Index;
- /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
- type Lookup = AccountIdLookup<AccountId, ()>;
- /// What to do if an account is fully reaped from the system.
- type OnKilledAccount = ();
- /// What to do if a new account is created.
- type OnNewAccount = ();
- type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
- /// The ubiquitous origin type.
- type Origin = Origin;
- /// This type is being generated by `construct_runtime!`.
- type PalletInfo = PalletInfo;
- /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
- type SS58Prefix = SS58Prefix;
- /// Weight information for the extrinsics of this pallet.
- type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
- /// Version of the runtime.
- type Version = Version;
- type MaxConsumers = ConstU32<16>;
-}
-
-parameter_types! {
- pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
-}
-
-impl pallet_timestamp::Config for Runtime {
- /// A timestamp: milliseconds since the unix epoch.
- type Moment = u64;
- type OnTimestampSet = ();
- type MinimumPeriod = MinimumPeriod;
- type WeightInfo = ();
-}
-
-parameter_types! {
- // pub const ExistentialDeposit: u128 = 500;
- pub const ExistentialDeposit: u128 = 0;
- pub const MaxLocks: u32 = 50;
- pub const MaxReserves: u32 = 50;
-}
-
-impl pallet_balances::Config for Runtime {
- type MaxLocks = MaxLocks;
- type MaxReserves = MaxReserves;
- type ReserveIdentifier = [u8; 16];
- /// The type for recording an account's balance.
- type Balance = Balance;
- /// The ubiquitous event type.
- type Event = Event;
- type DustRemoval = Treasury;
- type ExistentialDeposit = ExistentialDeposit;
- type AccountStore = System;
- type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
-}
-
-pub const fn deposit(items: u32, bytes: u32) -> Balance {
- items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE
-}
-
-/*
-parameter_types! {
- pub TombstoneDeposit: Balance = deposit(
- 1,
- sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,
- );
- pub DepositPerContract: Balance = TombstoneDeposit::get();
- pub const DepositPerStorageByte: Balance = deposit(0, 1);
- pub const DepositPerStorageItem: Balance = deposit(1, 0);
- pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
- pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;
- pub const SignedClaimHandicap: u32 = 2;
- pub const MaxDepth: u32 = 32;
- pub const MaxValueSize: u32 = 16 * 1024;
- pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb
- // The lazy deletion runs inside on_initialize.
- pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
- RuntimeBlockWeights::get().max_block;
- // The weight needed for decoding the queue should be less or equal than a fifth
- // of the overall weight dedicated to the lazy deletion.
- pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
- )) / 5) as u32;
- pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
-}
-
-impl pallet_contracts::Config for Runtime {
- type Time = Timestamp;
- type Randomness = RandomnessCollectiveFlip;
- type Currency = Balances;
- type Event = Event;
- type RentPayment = ();
- type SignedClaimHandicap = SignedClaimHandicap;
- type TombstoneDeposit = TombstoneDeposit;
- type DepositPerContract = DepositPerContract;
- type DepositPerStorageByte = DepositPerStorageByte;
- type DepositPerStorageItem = DepositPerStorageItem;
- type RentFraction = RentFraction;
- type SurchargeReward = SurchargeReward;
- type WeightPrice = pallet_transaction_payment::Pallet<Self>;
- type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
- type ChainExtension = NFTExtension;
- type DeletionQueueDepth = DeletionQueueDepth;
- type DeletionWeightLimit = DeletionWeightLimit;
- type Schedule = Schedule;
- type CallStack = [pallet_contracts::Frame<Self>; 31];
-}
-*/
-
-parameter_types! {
- /// This value increases the priority of `Operational` transactions by adding
- /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
- pub const OperationalFeeMultiplier: u8 = 5;
-}
-
-/// Linear implementor of `WeightToFeePolynomial`
-pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
-
-impl<T> WeightToFeePolynomial for LinearFee<T>
-where
- T: BaseArithmetic + From<u32> + Copy + Unsigned,
-{
- type Balance = T;
-
- fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
- smallvec!(WeightToFeeCoefficient {
- coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
- coeff_frac: Perbill::zero(),
- negative: false,
- degree: 1,
- })
- }
-}
-
-impl pallet_transaction_payment::Config for Runtime {
- type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
- type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
- type OperationalFeeMultiplier = OperationalFeeMultiplier;
- type WeightToFee = LinearFee<Balance>;
- type FeeMultiplierUpdate = ();
-}
-
-parameter_types! {
- pub const ProposalBond: Permill = Permill::from_percent(5);
- pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
- pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
- pub const SpendPeriod: BlockNumber = 5 * MINUTES;
- pub const Burn: Permill = Permill::from_percent(0);
- pub const TipCountdown: BlockNumber = 1 * DAYS;
- pub const TipFindersFee: Percent = Percent::from_percent(20);
- pub const TipReportDepositBase: Balance = 1 * UNIQUE;
- pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
- pub const BountyDepositBase: Balance = 1 * UNIQUE;
- pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
- pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
- pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
- pub const MaximumReasonLength: u32 = 16384;
- pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
- pub const BountyValueMinimum: Balance = 5 * UNIQUE;
- pub const MaxApprovals: u32 = 100;
-}
-
-impl pallet_treasury::Config for Runtime {
- type PalletId = TreasuryModuleId;
- type Currency = Balances;
- type ApproveOrigin = EnsureRoot<AccountId>;
- type RejectOrigin = EnsureRoot<AccountId>;
- type Event = Event;
- type OnSlash = ();
- type ProposalBond = ProposalBond;
- type ProposalBondMinimum = ProposalBondMinimum;
- type ProposalBondMaximum = ProposalBondMaximum;
- type SpendPeriod = SpendPeriod;
- type Burn = Burn;
- type BurnDestination = ();
- type SpendFunds = ();
- type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
- type MaxApprovals = MaxApprovals;
-}
-
-impl pallet_sudo::Config for Runtime {
- type Event = Event;
- type Call = Call;
-}
-
-pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
-
-impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
- for RelayChainBlockNumberProvider<T>
-{
- type BlockNumber = BlockNumber;
-
- fn current_block_number() -> Self::BlockNumber {
- cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
- .map(|d| d.relay_parent_number)
- .unwrap_or_default()
- }
-}
-
-parameter_types! {
- pub const MinVestedTransfer: Balance = 10 * UNIQUE;
- pub const MaxVestingSchedules: u32 = 28;
-}
-
-impl orml_vesting::Config for Runtime {
- type Event = Event;
- type Currency = pallet_balances::Pallet<Runtime>;
- type MinVestedTransfer = MinVestedTransfer;
- type VestedTransferOrigin = EnsureSigned<AccountId>;
- type WeightInfo = ();
- type MaxVestingSchedules = MaxVestingSchedules;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-parameter_types! {
- pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
- pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
-}
-
-impl cumulus_pallet_parachain_system::Config for Runtime {
- type Event = Event;
- type SelfParaId = parachain_info::Pallet<Self>;
- type OnSystemEvent = ();
- // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
- // MaxDownwardMessageWeight,
- // XcmExecutor<XcmConfig>,
- // Call,
- // >;
- type OutboundXcmpMessageSource = XcmpQueue;
- type DmpMessageHandler = DmpQueue;
- type ReservedDmpWeight = ReservedDmpWeight;
- type ReservedXcmpWeight = ReservedXcmpWeight;
- type XcmpMessageHandler = XcmpQueue;
-}
-
-impl parachain_info::Config for Runtime {}
-
-impl cumulus_pallet_aura_ext::Config for Runtime {}
-
-parameter_types! {
- pub const RelayLocation: MultiLocation = MultiLocation::parent();
- pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
- pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
- pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
-}
-
-/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
-/// when determining ownership of accounts for asset transacting and when attempting to use XCM
-/// `Transact` in order to determine the dispatch Origin.
-pub type LocationToAccountId = (
- // The parent (Relay-chain) origin converts to the default `AccountId`.
- ParentIsPreset<AccountId>,
- // Sibling parachain origins convert to AccountId via the `ParaId::into`.
- SiblingParachainConvertsVia<Sibling, AccountId>,
- // Straight up local `AccountId32` origins just alias directly to `AccountId`.
- AccountId32Aliases<RelayNetwork, AccountId>,
-);
-
-pub struct OnlySelfCurrency;
-impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
- fn matches_fungible(a: &MultiAsset) -> Option<B> {
- match (&a.id, &a.fun) {
- (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
- _ => None,
- }
- }
-}
-
-/// Means for transacting assets on this chain.
-pub type LocalAssetTransactor = CurrencyAdapter<
- // Use this currency:
- Balances,
- // Use this currency when it is a fungible asset matching the given location or name:
- OnlySelfCurrency,
- // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
- LocationToAccountId,
- // Our chain's account ID type (we can't get away without mentioning it explicitly):
- AccountId,
- // We don't track any teleports.
- (),
->;
-
-/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
-/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
-/// biases the kind of local `Origin` it will become.
-pub type XcmOriginToTransactDispatchOrigin = (
- // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
- // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
- // foreign chains who want to have a local sovereign account on this chain which they control.
- SovereignSignedViaLocation<LocationToAccountId, Origin>,
- // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
- // recognised.
- RelayChainAsNative<RelayOrigin, Origin>,
- // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
- // recognised.
- SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
- // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
- // transaction from the Root origin.
- ParentAsSuperuser<Origin>,
- // Native signed account converter; this just converts an `AccountId32` origin into a normal
- // `Origin::Signed` origin of the same 32-byte value.
- SignedAccountId32AsNative<RelayNetwork, Origin>,
- // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
- XcmPassthrough<Origin>,
-);
-
-parameter_types! {
- // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
- pub UnitWeightCost: Weight = 1_000_000;
- // 1200 UNIQUEs buy 1 second of weight.
- pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
- pub const MaxInstructions: u32 = 100;
- pub const MaxAuthorities: u32 = 100_000;
-}
-
-match_types! {
- pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
- MultiLocation { parents: 1, interior: Here } |
- MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
- };
-}
-
-pub type Barrier = (
- TakeWeightCredit,
- AllowTopLevelPaidExecutionFrom<Everything>,
- // ^^^ Parent & its unit plurality gets free execution
-);
-
-pub struct UsingOnlySelfCurrencyComponents<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
->(
- Weight,
- Currency::Balance,
- PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
-);
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > WeightTrader
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn new() -> Self {
- Self(0, Zero::zero(), PhantomData)
- }
-
- fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
- let amount = WeightToFee::weight_to_fee(&weight);
- let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
-
- // location to this parachain through relay chain
- let option1: xcm::v1::AssetId = Concrete(MultiLocation {
- parents: 1,
- interior: X1(Parachain(ParachainInfo::parachain_id().into())),
- });
- // direct location
- let option2: xcm::v1::AssetId = Concrete(MultiLocation {
- parents: 0,
- interior: Here,
- });
-
- let required = if payment.fungible.contains_key(&option1) {
- (option1, u128_amount).into()
- } else if payment.fungible.contains_key(&option2) {
- (option2, u128_amount).into()
- } else {
- (Concrete(MultiLocation::default()), u128_amount).into()
- };
-
- let unused = payment
- .checked_sub(required)
- .map_err(|_| XcmError::TooExpensive)?;
- self.0 = self.0.saturating_add(weight);
- self.1 = self.1.saturating_add(amount);
- Ok(unused)
- }
-
- fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
- let weight = weight.min(self.0);
- let amount = WeightToFee::weight_to_fee(&weight);
- self.0 -= weight;
- self.1 = self.1.saturating_sub(amount);
- let amount: u128 = amount.saturated_into();
- if amount > 0 {
- Some((AssetId::get(), amount).into())
- } else {
- None
- }
- }
-}
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > Drop
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn drop(&mut self) {
- OnUnbalanced::on_unbalanced(Currency::issue(self.1));
- }
-}
-
-pub struct XcmConfig;
-impl Config for XcmConfig {
- type Call = Call;
- type XcmSender = XcmRouter;
- // How to withdraw and deposit an asset.
- type AssetTransactor = LocalAssetTransactor;
- type OriginConverter = XcmOriginToTransactDispatchOrigin;
- type IsReserve = NativeAsset;
- type IsTeleporter = (); // Teleportation is disabled
- type LocationInverter = LocationInverter<Ancestry>;
- type Barrier = Barrier;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type Trader =
- UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
- type ResponseHandler = (); // Don't handle responses for now.
- type SubscriptionService = PolkadotXcm;
-
- type AssetTrap = PolkadotXcm;
- type AssetClaims = PolkadotXcm;
-}
-
-// parameter_types! {
-// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
-// }
-
-/// No local origins on this chain are allowed to dispatch XCM sends/executions.
-pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
-
-/// The means for routing XCM messages which are not for local execution into the right message
-/// queues.
-pub type XcmRouter = (
- // Two routers - use UMP to communicate with the relay chain:
- cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
- // ..and XCMP to communicate with the sibling chains.
- XcmpQueue,
-);
-
-impl pallet_evm_coder_substrate::Config for Runtime {}
-
-impl pallet_xcm::Config for Runtime {
- type Event = Event;
- type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmRouter = XcmRouter;
- type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmExecuteFilter = Everything;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type XcmTeleportFilter = Everything;
- type XcmReserveTransferFilter = Everything;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type LocationInverter = LocationInverter<Ancestry>;
- type Origin = Origin;
- type Call = Call;
- const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
- type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
-}
-
-impl cumulus_pallet_xcm::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
-}
-
-impl cumulus_pallet_xcmp_queue::Config for Runtime {
- type WeightInfo = ();
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ChannelInfo = ParachainSystem;
- type VersionWrapper = ();
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
- type ControllerOrigin = EnsureRoot<AccountId>;
- type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
-}
-
-impl cumulus_pallet_dmp_queue::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
-}
-
-impl pallet_aura::Config for Runtime {
- type AuthorityId = AuraId;
- type DisabledValidators = ();
- type MaxAuthorities = MaxAuthorities;
-}
-
-parameter_types! {
- pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
- pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
-}
-
-impl pallet_common::Config for Runtime {
- type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
- type Event = Event;
- type Currency = Balances;
- type CollectionCreationPrice = CollectionCreationPrice;
- type TreasuryAccountId = TreasuryAccountId;
- type CollectionDispatch = CollectionDispatchT<Self>;
-
- type EvmTokenAddressMapping = EvmTokenAddressMapping;
- type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
- type ContractAddress = EvmCollectionHelpersAddress;
-}
-
-impl pallet_structure::Config for Runtime {
- type Event = Event;
- type Call = Call;
- type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_fungible::Config for Runtime {
- type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_refungible::Config for Runtime {
- type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_nonfungible::Config for Runtime {
- type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_unique::Config for Runtime {
- type Event = Event;
- type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
- type CommonWeightInfo = CommonWeights<Self>;
- type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
-}
-
-parameter_types! {
- pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
-}
-
-/// Used for the pallet inflation
-impl pallet_inflation::Config for Runtime {
- type Currency = Balances;
- type TreasuryAccountId = TreasuryAccountId;
- type InflationBlockInterval = InflationBlockInterval;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-parameter_types! {
- pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
- RuntimeBlockWeights::get().max_block;
- pub const MaxScheduledPerBlock: u32 = 50;
-}
-
-type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
-use frame_support::traits::NamedReservableCurrency;
-
-fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
- (
- frame_system::CheckSpecVersion::<Runtime>::new(),
- frame_system::CheckGenesis::<Runtime>::new(),
- frame_system::CheckEra::<Runtime>::from(Era::Immortal),
- frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
- from,
- )),
- frame_system::CheckWeight::<Runtime>::new(),
- // sponsoring transaction logic
- // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
- )
-}
-
-pub struct SchedulerPaymentExecutor;
-impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
- DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
-where
- <T as frame_system::Config>::Call: Member
- + Dispatchable<Origin = Origin, Info = DispatchInfo>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
- + GetDispatchInfo
- + From<frame_system::Call<Runtime>>,
- SelfContainedSignedInfo: Send + Sync + 'static,
- Call: From<<T as frame_system::Config>::Call>
- + From<<T as pallet_unique_scheduler::Config>::Call>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
- sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
-{
- fn dispatch_call(
- signer: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<
- Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
- TransactionValidityError,
- > {
- let dispatch_info = call.get_dispatch_info();
- let extrinsic = fp_self_contained::CheckedExtrinsic::<
- AccountId,
- Call,
- SignedExtraScheduler,
- SelfContainedSignedInfo,
- > {
- signed:
- CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
- signer.clone().into(),
- get_signed_extras(signer.into()),
- ),
- function: call.into(),
- };
-
- extrinsic.apply::<Runtime>(&dispatch_info, 0)
- }
-
- fn reserve_balance(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- count: u32,
- ) -> Result<(), DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
- .saturating_mul(count.into());
-
- <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
- &id,
- &(sponsor.into()),
- weight,
- )
- }
-
- fn pay_for_call(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<u128, DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- weight,
- ),
- )
- }
-
- fn cancel_reserve(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- ) -> Result<u128, DispatchError> {
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- u128::MAX,
- ),
- )
- }
-}
-
-parameter_types! {
- pub const NoPreimagePostponement: Option<u32> = Some(10);
- pub const Preimage: Option<u32> = Some(10);
-}
-
-/// Used the compare the privilege of an origin inside the scheduler.
-pub struct OriginPrivilegeCmp;
-
-impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
- fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
- Some(Ordering::Equal)
- }
-}
-
-impl pallet_unique_scheduler::Config for Runtime {
- type Event = Event;
- type Origin = Origin;
- type Currency = Balances;
- type PalletsOrigin = OriginCaller;
- type Call = Call;
- type MaximumWeight = MaximumSchedulerWeight;
- type ScheduleOrigin = EnsureSigned<AccountId>;
- type MaxScheduledPerBlock = MaxScheduledPerBlock;
- type WeightInfo = ();
- type CallExecutor = SchedulerPaymentExecutor;
- type OriginPrivilegeCmp = OriginPrivilegeCmp;
- type PreimageProvider = ();
- type NoPreimagePostponement = NoPreimagePostponement;
-}
-
-type EvmSponsorshipHandler = (
- UniqueEthSponsorshipHandler<Runtime>,
- pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
-);
-type SponsorshipHandler = (
- UniqueSponsorshipHandler<Runtime>,
- //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
- pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
-);
-
-impl pallet_evm_transaction_payment::Config for Runtime {
- type EvmSponsorshipHandler = EvmSponsorshipHandler;
- type Currency = Balances;
-}
-
-impl pallet_charge_transaction::Config for Runtime {
- type SponsorshipHandler = SponsorshipHandler;
-}
-
-// impl pallet_contract_helpers::Config for Runtime {
-// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-// }
-
-parameter_types! {
- // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
- pub const HelpersContractAddress: H160 = H160([
- 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
- ]);
-
- // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
- pub const EvmCollectionHelpersAddress: H160 = H160([
- 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
- ]);
-}
-
-impl pallet_evm_contract_helpers::Config for Runtime {
- type ContractAddress = HelpersContractAddress;
- type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
-construct_runtime!(
- pub enum Runtime where
- Block = Block,
- NodeBlock = opaque::Block,
- UncheckedExtrinsic = UncheckedExtrinsic
- {
- ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
- ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
-
- Aura: pallet_aura::{Pallet, Config<T>} = 22,
- AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
-
- Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
- RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
- Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
- TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
- Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
- Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
- System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
- Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
- // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
- // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
-
- // XCM helpers.
- XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
- PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
- CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
- DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
-
- // Unique Pallets
- Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
- Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
- Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
- // free = 63
- Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
- // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
- Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
- Fungible: pallet_fungible::{Pallet, Storage} = 67,
- Refungible: pallet_refungible::{Pallet, Storage} = 68,
- Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
- Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
-
- // Frontier
- EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
- Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
-
- EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
- EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
- EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
- EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
- }
-);
-
-pub struct TransactionConverter;
-
-impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
- UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- )
- }
-}
-
-impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(
- &self,
- transaction: pallet_ethereum::Transaction,
- ) -> opaque::UncheckedExtrinsic {
- let extrinsic = UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- );
- let encoded = extrinsic.encode();
- opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
- .expect("Encoded extrinsic is always valid")
- }
-}
-
-/// The address format for describing accounts.
-pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
-/// Block header type as expected by this runtime.
-pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
-/// Block type as expected by this runtime.
-pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-/// A Block signed with a Justification
-pub type SignedBlock = generic::SignedBlock<Block>;
-/// BlockId type as expected by this runtime.
-pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
- frame_system::CheckSpecVersion<Runtime>,
- // system::CheckTxVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
- pallet_charge_transaction::ChargeTransactionPayment<Runtime>,
- //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
- pallet_ethereum::FakeTransactionFinalizer<Runtime>,
-);
-pub type SignedExtraScheduler = (
- frame_system::CheckSpecVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
- // pallet_charge_transaction::ChargeTransactionPayment<Runtime>,
-);
-/// Unchecked extrinsic type as expected by this runtime.
-pub type UncheckedExtrinsic =
- fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
-/// Extrinsic type that has already been checked.
-pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
-/// Executive: handles dispatch to the various modules.
-pub type Executive = frame_executive::Executive<
- Runtime,
- Block,
- frame_system::ChainContext<Runtime>,
- Runtime,
- AllPalletsReversedWithSystemFirst,
->;
-
-impl_opaque_keys! {
- pub struct SessionKeys {
- pub aura: Aura,
- }
-}
-
-impl fp_self_contained::SelfContainedCall for Call {
- type SignedInfo = H160;
-
- fn is_self_contained(&self) -> bool {
- match self {
- Call::Ethereum(call) => call.is_self_contained(),
- _ => false,
- }
- }
-
- fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.check_self_contained(),
- _ => None,
- }
- }
-
- fn validate_self_contained(
- &self,
- info: &Self::SignedInfo,
- dispatch_info: &DispatchInfoOf<Call>,
- len: usize,
- ) -> Option<TransactionValidity> {
- match self {
- Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
- _ => None,
- }
- }
-
- fn pre_dispatch_self_contained(
- &self,
- info: &Self::SignedInfo,
- ) -> Option<Result<(), TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
- _ => None,
- }
- }
-
- fn apply_self_contained(
- self,
- info: Self::SignedInfo,
- ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
- match self {
- call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
- Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
- )),
- _ => None,
- }
- }
-}
-
-macro_rules! dispatch_unique_runtime {
- ($collection:ident.$method:ident($($name:ident),*)) => {{
- let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
- let dispatch = collection.as_dyn();
-
- Ok::<_, DispatchError>(dispatch.$method($($name),*))
- }};
-}
-
-impl_common_runtime_apis! {
- #![custom_apis]
-
- 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> {
- Ok(Default::default())
- }
-
- fn collection_by_id(_collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
- Ok(Default::default())
- }
-
- fn nft_by_id(_collection_id: RmrkCollectionId, _nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
- Ok(Default::default())
- }
-
- fn account_tokens(_account_id: AccountId, _collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
- Ok(Default::default())
- }
-
- fn nft_children(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
- Ok(Default::default())
- }
-
- fn collection_properties(_collection_id: RmrkCollectionId, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- Ok(Default::default())
- }
-
- fn nft_properties(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- Ok(Default::default())
- }
-
- fn nft_resources(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
- Ok(Default::default())
- }
-
- fn nft_resource_priority(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId, _resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
- Ok(Default::default())
- }
-
- fn base(_base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
- Ok(Default::default())
- }
-
- fn base_parts(_base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
- Ok(Default::default())
- }
-
- fn theme_names(_base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
- Ok(Default::default())
- }
-
- fn theme(_base_id: RmrkBaseId, _theme_name: RmrkThemeName, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
- Ok(Default::default())
- }
- }
-}
-
-struct CheckInherents;
-
-impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
- fn check_inherents(
- block: &Block,
- relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
- ) -> sp_inherents::CheckInherentsResult {
- let relay_chain_slot = relay_state_proof
- .read_slot()
- .expect("Could not read the relay chain slot from the proof");
-
- let inherent_data =
- cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
- relay_chain_slot,
- sp_std::time::Duration::from_secs(6),
- )
- .create_inherent_data()
- .expect("Could not create the timestamp inherent data");
-
- inherent_data.check_extrinsics(block)
- }
-}
+impl_common_runtime_apis!();
cumulus_pallet_parachain_system::register_validate_block!(
Runtime = Runtime,
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -8,6 +8,7 @@
"@polkadot/typegen": "8.7.2-15",
"@types/chai": "^4.3.1",
"@types/chai-as-promised": "^7.1.5",
+ "@types/chai-like": "^1.1.1",
"@types/mocha": "^9.1.1",
"@types/node": "^17.0.35",
"@typescript-eslint/eslint-plugin": "^5.26.0",
@@ -96,6 +97,7 @@
"@polkadot/util-crypto": "9.4.1",
"bignumber.js": "^9.0.2",
"chai-as-promised": "^7.1.1",
+ "chai-like": "^1.1.1",
"find-process": "^1.4.7",
"solc": "0.8.14-fixed",
"web3": "^1.7.3"
tests/src/approve.test.tsdiffbeforeafterboth--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -32,6 +32,8 @@
getCreatedCollectionCount,
transferFromExpectSuccess,
transferFromExpectFail,
+ requirePallets,
+ Pallets,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -49,34 +51,44 @@
});
});
- it('Execute the extrinsic and check approvedList', async () => {
+ it('[nft] Execute the extrinsic and check approvedList', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
- // nft
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
- // fungible
+ });
+
+ it('[fungible] Execute the extrinsic and check approvedList', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
- // reFungible
+ });
+
+ it('[refungible] Execute the extrinsic and check approvedList', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
});
- it('Remove approval by using 0 amount', async () => {
+ it('[nft] Remove approval by using 0 amount', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
- // nft
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);
await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);
- // fungible
+ });
+
+ it('[fungible] Remove approval by using 0 amount', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
- // reFungible
+ });
+
+ it('[refungible] Remove approval by using 0 amount', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -117,7 +129,9 @@
await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
});
- it('ReFungible up to an approved amount', async () => {
+ it('ReFungible up to an approved amount', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
@@ -151,7 +165,9 @@
await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');
});
- it('ReFungible up to an approved amount', async () => {
+ it('ReFungible up to an approved amount', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
@@ -188,7 +204,9 @@
await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);
});
- it('ReFungible up to an approved amount', async () => {
+ it('ReFungible up to an approved amount', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
@@ -250,7 +268,9 @@
await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);
});
- it('ReFungible', async () => {
+ it('ReFungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -285,7 +305,9 @@
await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);
});
- it('ReFungible', async () => {
+ it('ReFungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, charlie, 101);
@@ -325,7 +347,9 @@
await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');
});
- it('ReFungible up to an approved amount', async () => {
+ it('ReFungible up to an approved amount', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', charlie.address);
@@ -422,63 +446,87 @@
});
});
- it('Approve for a collection that does not exist', async () => {
+ it('[nft] Approve for a collection that does not exist', async () => {
await usingApi(async (api: ApiPromise) => {
- // nft
const nftCollectionCount = await getCreatedCollectionCount(api);
await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
- // fungible
+ });
+ });
+
+ it('[fungible] Approve for a collection that does not exist', async () => {
+ await usingApi(async (api: ApiPromise) => {
const fungibleCollectionCount = await getCreatedCollectionCount(api);
await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
- // reFungible
+ });
+ });
+
+ it('[refungible] Approve for a collection that does not exist', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ await usingApi(async (api: ApiPromise) => {
const reFungibleCollectionCount = await getCreatedCollectionCount(api);
await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
});
});
- it('Approve for a collection that was destroyed', async () => {
- // nft
+ it('[nft] Approve for a collection that was destroyed', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
await destroyCollectionExpectSuccess(nftCollectionId);
await approveExpectFail(nftCollectionId, 1, alice, bob);
- // fungible
+ });
+
+ it('Approve for a collection that was destroyed', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
await destroyCollectionExpectSuccess(fungibleCollectionId);
await approveExpectFail(fungibleCollectionId, 0, alice, bob);
- // reFungible
+ });
+
+ it('[refungible] Approve for a collection that was destroyed', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await destroyCollectionExpectSuccess(reFungibleCollectionId);
await approveExpectFail(reFungibleCollectionId, 1, alice, bob);
});
- it('Approve transfer of a token that does not exist', async () => {
- // nft
+ it('[nft] Approve transfer of a token that does not exist', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
await approveExpectFail(nftCollectionId, 2, alice, bob);
- // reFungible
+ });
+
+ it('[refungible] Approve transfer of a token that does not exist', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await approveExpectFail(reFungibleCollectionId, 2, alice, bob);
});
- it('Approve using the address that does not own the approved token', async () => {
+ it('[nft] Approve using the address that does not own the approved token', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
- // nft
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);
- // fungible
+ });
+
+ it('[fungible] Approve using the address that does not own the approved token', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);
- // reFungible
+ });
+
+ it('[refungible] Approve using the address that does not own the approved token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);
});
- it('should fail if approved more ReFungibles than owned', async () => {
+ it('should fail if approved more ReFungibles than owned', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');
await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 100, 'ReFungible');
tests/src/burnItem.test.tsdiffbeforeafterboth--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -25,6 +25,8 @@
getBalance,
setCollectionLimitsExpectSuccess,
isTokenExists,
+ requirePallets,
+ Pallets,
} from './util/helpers';
import chai from 'chai';
@@ -80,7 +82,9 @@
});
});
- it('Burn item in ReFungible collection', async () => {
+ it('Burn item in ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const createMode = 'ReFungible';
const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
@@ -99,7 +103,9 @@
});
});
- it('Burn owned portion of item in ReFungible collection', async () => {
+ it('Burn owned portion of item in ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const createMode = 'ReFungible';
const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
@@ -189,7 +195,9 @@
});
// TODO: burnFrom
- it('Burn item in ReFungible collection', async () => {
+ it('Burn item in ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const createMode = 'ReFungible';
const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
tests/src/confirmSponsorship.test.tsdiffbeforeafterboth--- a/tests/src/confirmSponsorship.test.ts
+++ b/tests/src/confirmSponsorship.test.ts
@@ -33,6 +33,8 @@
addCollectionAdminExpectSuccess,
getCreatedCollectionCount,
UNIQUE,
+ requirePallets,
+ Pallets,
} from './util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
@@ -124,7 +126,9 @@
});
});
- it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => {
+ it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -252,7 +256,9 @@
});
});
- it('ReFungible: Sponsoring is rate limited', async () => {
+ it('ReFungible: Sponsoring is rate limited', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
tests/src/createCollection.test.tsdiffbeforeafterboth--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -16,7 +16,7 @@
import {expect} from 'chai';
import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
-import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess} from './util/helpers';
+import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess, requirePallets, Pallets} from './util/helpers';
describe('integration test: ext. createCollection():', () => {
it('Create new NFT collection', async () => {
@@ -34,7 +34,9 @@
it('Create new Fungible collection', async () => {
await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
});
- it('Create new ReFungible collection', async () => {
+ it('Create new ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
});
tests/src/createItem.test.tsdiffbeforeafterboth--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -29,6 +29,8 @@
itApi,
normalizeAccountId,
getCreateItemResult,
+ requirePallets,
+ Pallets,
} from './util/helpers';
const expect = chai.expect;
@@ -79,7 +81,9 @@
}
});
- it('Create new item in ReFungible collection', async () => {
+ it('Create new item in ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const createMode = 'ReFungible';
const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
await createItemExpectSuccess(alice, newCollectionID, createMode);
@@ -96,7 +100,9 @@
await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
await createItemExpectSuccess(bob, newCollectionID, createMode);
});
- it('Create new item in ReFungible collection with collection admin permissions', async () => {
+ it('Create new item in ReFungible collection with collection admin permissions', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const createMode = 'ReFungible';
const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
@@ -175,7 +181,9 @@
});
});
- it('Check total pieces of ReFungible token', async () => {
+ it('Check total pieces of ReFungible token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const createMode = 'ReFungible';
const createCollectionResult = await createCollection(api, alice, {mode: {type: createMode}});
@@ -219,7 +227,9 @@
const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
});
- it('Regular user cannot create new item in ReFungible collection', async () => {
+ it('Regular user cannot create new item in ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const createMode = 'ReFungible';
const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
@@ -296,7 +306,9 @@
});
});
- it('Check total pieces for invalid Refungible token', async () => {
+ it('Check total pieces for invalid Refungible token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
const collectionId = createCollectionResult.collectionId;
tests/src/createMultipleItems.test.tsdiffbeforeafterboth--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -33,6 +33,9 @@
createCollectionWithPropsExpectSuccess,
createMultipleItemsWithPropsExpectSuccess,
getTokenProperties,
+ requirePallets,
+ Pallets,
+ checkPalletsPresence,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -91,7 +94,9 @@
});
});
- it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
+ it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api, privateKeyWrapper) => {
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -272,7 +277,9 @@
});
});
- it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
+ it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api: ApiPromise) => {
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -335,7 +342,9 @@
});
});
- it('Regular user cannot create items in active ReFungible collection', async () => {
+ it('Regular user cannot create items in active ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api: ApiPromise) => {
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -358,9 +367,8 @@
});
});
- it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {
+ it('Create NFTs that has reached the maximum data limit', async function() {
await usingApi(async (api, privateKeyWrapper) => {
- // NFT
const collectionId = await createCollectionWithPropsExpectSuccess({
propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}],
});
@@ -372,8 +380,13 @@
];
const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
+ });
+ });
- // ReFungible
+ it('Create Refungible tokens that has reached the maximum data limit', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ await usingApi(async api => {
const collectionIdReFungible =
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
{
@@ -402,8 +415,15 @@
it('Create tokens with different types', async () => {
await usingApi(async (api: ApiPromise) => {
const collectionId = await createCollectionExpectSuccess();
+
+ const types = ['NFT', 'Fungible'];
+
+ if (await checkPalletsPresence([Pallets.ReFungible])) {
+ types.push('ReFungible');
+ }
+
const createMultipleItemsTx = api.tx.unique
- .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);
+ .createMultipleItems(collectionId, normalizeAccountId(alice.address), types);
await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/nonfungible\.NotNonfungibleDataUsedToMintFungibleCollectionToken/);
// garbage collection :-D // lol
await destroyCollectionExpectSuccess(collectionId);
tests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth--- a/tests/src/createMultipleItemsEx.test.ts
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -16,9 +16,9 @@
import {expect} from 'chai';
import usingApi, {executeTransaction} from './substrate/substrate-api';
-import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId, getTokenProperties} from './util/helpers';
+import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId, getTokenProperties, requirePallets, Pallets} from './util/helpers';
-describe.only('Integration Test: createMultipleItemsEx', () => {
+describe('Integration Test: createMultipleItemsEx', () => {
it('can initialize multiple NFT with different owners', async () => {
const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await usingApi(async (api, privateKeyWrapper) => {
@@ -146,7 +146,9 @@
});
});
- it('can initialize an RFT with multiple owners', async () => {
+ it('can initialize an RFT with multiple owners', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api, privateKeyWrapper) => {
const alice = privateKeyWrapper('//Alice');
const bob = privateKeyWrapper('//Bob');
@@ -178,7 +180,9 @@
});
});
- it('can initialize multiple RFTs with the same owner', async () => {
+ it('can initialize multiple RFTs with the same owner', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api, privateKeyWrapper) => {
const alice = privateKeyWrapper('//Alice');
const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
@@ -386,27 +390,6 @@
const tokens = await api.query.nonfungible.tokenData.entries(collection);
const json = tokens.map(([, token]) => token.toJSON());
expect(json).to.be.deep.equal(data);
- });
- });
-
- it('fails when trying to set multiple owners when creating multiple refungibles', async () => {
- const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-
- await usingApi(async (api, privateKeyWrapper) => {
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
- // Polkadot requires map, and yet requires keys to be JSON encoded
- const users = new Map();
- users.set(JSON.stringify({substrate: alice.address}), 1);
- users.set(JSON.stringify({substrate: bob.address}), 1);
-
- // TODO: better error message?
- await expect(executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
- RefungibleMultipleItems: [
- {users},
- {users},
- ],
- }))).to.be.rejectedWith(/^refungible\.NotRefungibleDataUsedToMintFungibleCollectionToken$/);
});
});
});
tests/src/destroyCollection.test.tsdiffbeforeafterboth--- a/tests/src/destroyCollection.test.ts
+++ b/tests/src/destroyCollection.test.ts
@@ -25,6 +25,8 @@
addCollectionAdminExpectSuccess,
getCreatedCollectionCount,
createItemExpectSuccess,
+ requirePallets,
+ Pallets,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -38,7 +40,9 @@
const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
await destroyCollectionExpectSuccess(collectionId);
});
- it('ReFungible collection can be destroyed', async () => {
+ it('ReFungible collection can be destroyed', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await destroyCollectionExpectSuccess(collectionId);
});
tests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth--- a/tests/src/eth/api/CollectionHelpers.sol
+++ b/tests/src/eth/api/CollectionHelpers.sol
@@ -48,7 +48,7 @@
string memory name,
string memory description,
string memory tokenPrefix
- ) external view returns (address);
+ ) external returns (address);
// Selector: createERC721MetadataCompatibleRFTCollection(string,string,string,string) a5596388
function createERC721MetadataCompatibleRFTCollection(
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -22,13 +22,7 @@
);
}
-// Selector: 79cc6790
-interface ERC20UniqueExtensions is Dummy, ERC165 {
- // Selector: burnFrom(address,uint256) 79cc6790
- function burnFrom(address from, uint256 amount) external returns (bool);
-}
-
-// Selector: 7d9262e6
+// Selector: 6cf113cd
interface Collection is Dummy, ERC165 {
// Set collection property.
//
@@ -174,6 +168,27 @@
//
// Selector: setCollectionMintMode(bool) 00018e84
function setCollectionMintMode(bool mode) external;
+
+ // Check that account is the owner or admin of the collection
+ //
+ // @param user account to verify
+ // @return "true" if account is the owner or admin
+ //
+ // Selector: verifyOwnerOrAdmin(address) c2282493
+ function verifyOwnerOrAdmin(address user) external view returns (bool);
+
+ // Returns collection type
+ //
+ // @return `Fungible` or `NFT` or `ReFungible`
+ //
+ // Selector: uniqueCollectionType() d34b55b8
+ function uniqueCollectionType() external returns (string memory);
+}
+
+// Selector: 79cc6790
+interface ERC20UniqueExtensions is Dummy, ERC165 {
+ // Selector: burnFrom(address,uint256) 79cc6790
+ function burnFrom(address from, uint256 amount) external returns (bool);
}
// Selector: 942e8b22
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -250,33 +250,7 @@
function finishMinting() external returns (bool);
}
-// Selector: 780e9d63
-interface ERC721Enumerable is Dummy, ERC165 {
- // @notice Enumerate valid NFTs
- // @param index A counter less than `totalSupply()`
- // @return The token identifier for the `index`th NFT,
- // (sort order not specified)
- //
- // Selector: tokenByIndex(uint256) 4f6ccce7
- function tokenByIndex(uint256 index) external view returns (uint256);
-
- // @dev Not implemented
- //
- // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
- function tokenOfOwnerByIndex(address owner, uint256 index)
- external
- view
- returns (uint256);
-
- // @notice Count NFTs tracked by this contract
- // @return A count of valid NFTs tracked by this contract, where each one of
- // them has an assigned and queryable owner not equal to the zero address
- //
- // Selector: totalSupply() 18160ddd
- function totalSupply() external view returns (uint256);
-}
-
-// Selector: 7d9262e6
+// Selector: 6cf113cd
interface Collection is Dummy, ERC165 {
// Set collection property.
//
@@ -422,6 +396,47 @@
//
// Selector: setCollectionMintMode(bool) 00018e84
function setCollectionMintMode(bool mode) external;
+
+ // Check that account is the owner or admin of the collection
+ //
+ // @param user account to verify
+ // @return "true" if account is the owner or admin
+ //
+ // Selector: verifyOwnerOrAdmin(address) c2282493
+ function verifyOwnerOrAdmin(address user) external view returns (bool);
+
+ // Returns collection type
+ //
+ // @return `Fungible` or `NFT` or `ReFungible`
+ //
+ // Selector: uniqueCollectionType() d34b55b8
+ function uniqueCollectionType() external returns (string memory);
+}
+
+// Selector: 780e9d63
+interface ERC721Enumerable is Dummy, ERC165 {
+ // @notice Enumerate valid NFTs
+ // @param index A counter less than `totalSupply()`
+ // @return The token identifier for the `index`th NFT,
+ // (sort order not specified)
+ //
+ // Selector: tokenByIndex(uint256) 4f6ccce7
+ function tokenByIndex(uint256 index) external view returns (uint256);
+
+ // @dev Not implemented
+ //
+ // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
+ function tokenOfOwnerByIndex(address owner, uint256 index)
+ external
+ view
+ returns (uint256);
+
+ // @notice Count NFTs tracked by this contract
+ // @return A count of valid NFTs tracked by this contract, where each one of
+ // them has an assigned and queryable owner not equal to the zero address
+ //
+ // Selector: totalSupply() 18160ddd
+ function totalSupply() external view returns (uint256);
}
// Selector: d74d154f
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -248,33 +248,7 @@
function finishMinting() external returns (bool);
}
-// Selector: 780e9d63
-interface ERC721Enumerable is Dummy, ERC165 {
- // @notice Enumerate valid RFTs
- // @param index A counter less than `totalSupply()`
- // @return The token identifier for the `index`th NFT,
- // (sort order not specified)
- //
- // Selector: tokenByIndex(uint256) 4f6ccce7
- function tokenByIndex(uint256 index) external view returns (uint256);
-
- // Not implemented
- //
- // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
- function tokenOfOwnerByIndex(address owner, uint256 index)
- external
- view
- returns (uint256);
-
- // @notice Count RFTs tracked by this contract
- // @return A count of valid RFTs tracked by this contract, where each one of
- // them has an assigned and queryable owner not equal to the zero address
- //
- // Selector: totalSupply() 18160ddd
- function totalSupply() external view returns (uint256);
-}
-
-// Selector: 7d9262e6
+// Selector: 6cf113cd
interface Collection is Dummy, ERC165 {
// Set collection property.
//
@@ -420,9 +394,50 @@
//
// Selector: setCollectionMintMode(bool) 00018e84
function setCollectionMintMode(bool mode) external;
+
+ // Check that account is the owner or admin of the collection
+ //
+ // @param user account to verify
+ // @return "true" if account is the owner or admin
+ //
+ // Selector: verifyOwnerOrAdmin(address) c2282493
+ function verifyOwnerOrAdmin(address user) external view returns (bool);
+
+ // Returns collection type
+ //
+ // @return `Fungible` or `NFT` or `ReFungible`
+ //
+ // Selector: uniqueCollectionType() d34b55b8
+ function uniqueCollectionType() external returns (string memory);
+}
+
+// Selector: 780e9d63
+interface ERC721Enumerable is Dummy, ERC165 {
+ // @notice Enumerate valid RFTs
+ // @param index A counter less than `totalSupply()`
+ // @return The token identifier for the `index`th NFT,
+ // (sort order not specified)
+ //
+ // Selector: tokenByIndex(uint256) 4f6ccce7
+ function tokenByIndex(uint256 index) external view returns (uint256);
+
+ // Not implemented
+ //
+ // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59
+ function tokenOfOwnerByIndex(address owner, uint256 index)
+ external
+ view
+ returns (uint256);
+
+ // @notice Count RFTs tracked by this contract
+ // @return A count of valid RFTs tracked by this contract, where each one of
+ // them has an assigned and queryable owner not equal to the zero address
+ //
+ // Selector: totalSupply() 18160ddd
+ function totalSupply() external view returns (uint256);
}
-// Selector: d74d154f
+// Selector: 7c3bef89
interface ERC721UniqueExtensions is Dummy, ERC165 {
// @notice Transfer ownership of an RFT
// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
@@ -473,6 +488,16 @@
function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)
external
returns (bool);
+
+ // Returns EVM address for refungible token
+ //
+ // @param token ID of the token
+ //
+ // Selector: tokenContractAddress(uint256) ab76fac6
+ function tokenContractAddress(uint256 token)
+ external
+ view
+ returns (address);
}
interface UniqueRefungible is
tests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungibleToken.sol
+++ b/tests/src/eth/api/UniqueRefungibleToken.sol
@@ -22,6 +22,23 @@
);
}
+// Selector: 042f1106
+interface ERC1633UniqueExtensions is Dummy, ERC165 {
+ // Selector: setParentNFT(address,uint256) 042f1106
+ function setParentNFT(address collection, uint256 nftId)
+ external
+ returns (bool);
+}
+
+// Selector: 5755c3f2
+interface ERC1633 is Dummy, ERC165 {
+ // Selector: parentToken() 80a54001
+ function parentToken() external view returns (address);
+
+ // Selector: parentTokenId() d7f083f3
+ function parentTokenId() external view returns (uint256);
+}
+
// Selector: 942e8b22
interface ERC20 is Dummy, ERC165, ERC20Events {
// @return the name of the token.
@@ -115,5 +132,7 @@
Dummy,
ERC165,
ERC20,
- ERC20UniqueExtensions
+ ERC20UniqueExtensions,
+ ERC1633,
+ ERC1633UniqueExtensions
{}
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -59,6 +59,22 @@
expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())
.to.be.eq(newAdmin.address.toLocaleLowerCase());
});
+
+ itWeb3('Verify owner or admin', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const collectionHelper = evmCollectionHelpers(web3, owner);
+
+ const result = await collectionHelper.methods
+ .createNonfungibleCollection('A', 'B', 'C')
+ .send();
+ const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
+
+ const newAdmin = createEthAccount(web3);
+ const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
+ expect(await collectionEvm.methods.verifyOwnerOrAdmin(newAdmin).call()).to.be.false;
+ await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
+ expect(await collectionEvm.methods.verifyOwnerOrAdmin(newAdmin).call()).to.be.true;
+ });
itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {
const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
tests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth--- a/tests/src/eth/collectionHelpersAbi.json
+++ b/tests/src/eth/collectionHelpersAbi.json
@@ -61,7 +61,7 @@
],
"name": "createRefungibleCollection",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
- "stateMutability": "view",
+ "stateMutability": "nonpayable",
"type": "function"
},
{
tests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -16,7 +16,7 @@
import {evmToAddress} from '@polkadot/util-crypto';
import {expect} from 'chai';
-import {getCreatedCollectionCount, getDetailedCollectionInfo} from '../util/helpers';
+import {getCreatedCollectionCount, getDetailedCollectionInfo, requirePallets, Pallets} from '../util/helpers';
import {
evmCollectionHelpers,
collectionIdToAddress,
@@ -28,6 +28,10 @@
} from './util/helpers';
describe('Create RFT collection from EVM', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('Create collection', async ({api, web3, privateKeyWrapper}) => {
const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const collectionHelper = evmCollectionHelpers(web3, owner);
@@ -146,6 +150,10 @@
});
describe('(!negative tests!) Create RFT collection from EVM', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3, privateKeyWrapper}) => {
const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const helper = evmCollectionHelpers(web3, owner);
@@ -228,4 +236,4 @@
.setCollectionLimit('badLimit', 'true')
.call()).to.be.rejectedWith('unknown boolean limit "badLimit"');
});
-});
\ No newline at end of file
+});
tests/src/eth/fractionalizer/Fractionalizer.bindiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/fractionalizer/Fractionalizer.bin
@@ -0,0 +1 @@
+60c0604052600a60805269526546756e6769626c6560b01b60a0527fcdb72fd4e1d0d6d4eebd7ab142113ec2b4b06ddb24324db5c287ef01ab484d6b60055534801561004a57600080fd5b50600480546001600160a01b0319163317905561137a8061006c6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063115091401461005c5780631b191ea214610071578063d470e60f14610084578063dbc38ad214610097578063eb292412146100aa575b600080fd5b61006f61006a366004610f85565b6100bd565b005b61006f61007f366004610ff2565b61035b565b61006f61009236600461108c565b6104c0565b61006f6100a53660046110b8565b61089d565b61006f6100b8366004611114565b610ee0565b6004546001600160a01b031633146100f05760405162461bcd60e51b81526004016100e79061114d565b60405180910390fd5b6000546001600160a01b0316156101495760405162461bcd60e51b815260206004820152601d60248201527f52465420636f6c6c656374696f6e20697320616c72656164792073657400000060448201526064016100e7565b60008190506000816001600160a01b031663d34b55b86040518163ffffffff1660e01b81526004016000604051808303816000875af1158015610190573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101b8919081019061118b565b905060055481805190602001201461022f5760405162461bcd60e51b815260206004820152603460248201527f57726f6e6720636f6c6c656374696f6e20747970652e20436f6c6c656374696f604482015273371034b9903737ba103932b33ab733b4b136329760611b60648201526084016100e7565b816001600160a01b03166304a460536040518163ffffffff1660e01b81526004016020604051808303816000875af115801561026f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610293919061125b565b6103055760405162461bcd60e51b815260206004820152603c60248201527f4672616374696f6e616c697a657220636f6e74726163742073686f756c64206260448201527f6520616e2061646d696e206f662074686520636f6c6c656374696f6e0000000060648201526084016100e7565b600080546001600160a01b0319166001600160a01b0385169081179091556040519081527f7186a599bf2297b1f4c8957d30b0965291eee0021a5f9a0aeb54dcbd1ffdceef9060200160405180910390a1505050565b6004546001600160a01b031633146103855760405162461bcd60e51b81526004016100e79061114d565b6000546001600160a01b0316156103de5760405162461bcd60e51b815260206004820152601d60248201527f52465420636f6c6c656374696f6e20697320616c72656164792073657400000060448201526064016100e7565b6040516344a68ad560e01b8152736c4e9fe1ae37a41e93cee429e8e1881abdcbb54f9081906344a68ad590610421908a908a908a908a908a908a906004016112a1565b6020604051808303816000875af1158015610440573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046491906112ea565b600080546001600160a01b0319166001600160a01b039290921691821790556040519081527f7186a599bf2297b1f4c8957d30b0965291eee0021a5f9a0aeb54dcbd1ffdceef906020015b60405180910390a150505050505050565b6000546001600160a01b03166105145760405162461bcd60e51b81526020600482015260196024820152781491950818dbdb1b1958dd1a5bdb881a5cc81b9bdd081cd95d603a1b60448201526064016100e7565b6000546001600160a01b038381169116146105685760405162461bcd60e51b81526020600482015260146024820152732bb937b7339029232a1031b7b63632b1ba34b7b760611b60448201526064016100e7565b600080546040516355bb7d6360e11b8152600481018490526001600160a01b039091169190829063ab76fac690602401602060405180830381865afa1580156105b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d991906112ea565b6001600160a01b03808216600090815260036020908152604091829020825180840190935280549093168083526001909301549082015291925061065f5760405162461bcd60e51b815260206004820181905260248201527f4e6f20636f72726573706f6e64696e67204e465420746f6b656e20666f756e6460448201526064016100e7565b6000829050806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c69190611307565b6040516370a0823160e01b81523360048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801561070a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072e9190611307565b1461078a5760405162461bcd60e51b815260206004820152602660248201527f4e6f7420616c6c2070696563657320617265206f776e6564206279207468652060448201526531b0b63632b960d11b60648201526084016100e7565b6040516323b872dd60e01b81526001600160a01b038516906323b872dd906107ba90339030908a90600401611320565b600060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b5050835160208501516040516323b872dd60e01b81526001600160a01b0390921693506323b872dd92506108229130913391600401611320565b600060405180830381600087803b15801561083c57600080fd5b505af1158015610850573d6000803e3d6000fd5b5050835160208501516040517fe9e9808d24ff79ccc3b1ecf48be7b2d11591adccc452150d0d7947cb48eb0d53945061088d935087929190611320565b60405180910390a1505050505050565b6000546001600160a01b03166108f15760405162461bcd60e51b81526020600482015260196024820152781491950818dbdb1b1958dd1a5bdb881a5cc81b9bdd081cd95d603a1b60448201526064016100e7565b600080546001600160a01b0385811683526001602081905260409093205491169160ff90911615151461098c5760405162461bcd60e51b815260206004820152603c60248201527f4672616374696f6e616c697a6174696f6e206f66207468697320636f6c6c656360448201527f74696f6e206973206e6f7420616c6c6f7765642062792061646d696e0000000060648201526084016100e7565b6040516331a9108f60e11b81526004810184905233906001600160a01b03861690636352211e90602401602060405180830381865afa1580156109d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f791906112ea565b6001600160a01b031614610a5d5760405162461bcd60e51b815260206004820152602760248201527f4f6e6c7920746f6b656e206f776e657220636f756c64206672616374696f6e616044820152661b1a5e99481a5d60ca1b60648201526084016100e7565b6040516323b872dd60e01b81526001600160a01b038516906323b872dd90610a8d90339030908890600401611320565b600060405180830381600087803b158015610aa757600080fd5b505af1158015610abb573d6000803e3d6000fd5b505050506001600160a01b0384166000908152600260209081526040808320868452909152812054819081908103610d0757836001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4f9190611307565b6040516340c10f1960e01b8152306004820152602481018290529093506001600160a01b038516906340c10f19906044016020604051808303816000875af1158015610b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc3919061125b565b506040516355bb7d6360e11b8152600481018490526001600160a01b0385169063ab76fac690602401602060405180830381865afa158015610c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2d91906112ea565b6001600160a01b0388811660008181526002602090815260408083208c84528252808320899055805180820182528481528083018d8152878716808652600390945293829020905181546001600160a01b0319169616959095178555915160019094019390935551630217888360e11b81526004810191909152602481018990529193508392509063042f1106906044016020604051808303816000875af1158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d01919061125b565b50610d98565b6001600160a01b0387811660009081526002602090815260408083208a8452909152908190205490516355bb7d6360e11b8152600481018290529094509085169063ab76fac690602401602060405180830381865afa158015610d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9291906112ea565b91508190505b60405163d2418ca760e01b81526001600160801b03861660048201526001600160a01b0382169063d2418ca7906024016020604051808303816000875af1158015610de7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0b919061125b565b5060405163a9059cbb60e01b81523360048201526001600160801b03861660248201526001600160a01b0382169063a9059cbb906044016020604051808303816000875af1158015610e61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e85919061125b565b50604080516001600160a01b03808a168252602082018990528416918101919091526001600160801b03861660608201527f29f372538523984f33874da1b50e596ce0f180a6eb04d7ff22bb2ce80e1576b6906080016104af565b6004546001600160a01b03163314610f0a5760405162461bcd60e51b81526004016100e79061114d565b6001600160a01b038216600081815260016020908152604091829020805460ff19168515159081179091558251938452908301527f6dad0aed33f4b7f07095619b668698e17943fd9f4c83e7cfcc7f6dd880a11588910160405180910390a15050565b6001600160a01b0381168114610f8257600080fd5b50565b600060208284031215610f9757600080fd5b8135610fa281610f6d565b9392505050565b60008083601f840112610fbb57600080fd5b50813567ffffffffffffffff811115610fd357600080fd5b602083019150836020828501011115610feb57600080fd5b9250929050565b6000806000806000806060878903121561100b57600080fd5b863567ffffffffffffffff8082111561102357600080fd5b61102f8a838b01610fa9565b9098509650602089013591508082111561104857600080fd5b6110548a838b01610fa9565b9096509450604089013591508082111561106d57600080fd5b5061107a89828a01610fa9565b979a9699509497509295939492505050565b6000806040838503121561109f57600080fd5b82356110aa81610f6d565b946020939093013593505050565b6000806000606084860312156110cd57600080fd5b83356110d881610f6d565b92506020840135915060408401356001600160801b03811681146110fb57600080fd5b809150509250925092565b8015158114610f8257600080fd5b6000806040838503121561112757600080fd5b823561113281610f6d565b9150602083013561114281611106565b809150509250929050565b6020808252600e908201526d27b7363c9037bbb732b91031b0b760911b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561119e57600080fd5b825167ffffffffffffffff808211156111b657600080fd5b818501915085601f8301126111ca57600080fd5b8151818111156111dc576111dc611175565b604051601f8201601f19908116603f0116810190838211818310171561120457611204611175565b81604052828152888684870101111561121c57600080fd5b600093505b8284101561123e5784840186015181850187015292850192611221565b8284111561124f5760008684830101525b98975050505050505050565b60006020828403121561126d57600080fd5b8151610fa281611106565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060815260006112b560608301888a611278565b82810360208401526112c8818789611278565b905082810360408401526112dd818587611278565b9998505050505050505050565b6000602082840312156112fc57600080fd5b8151610fa281610f6d565b60006020828403121561131957600080fd5b5051919050565b6001600160a01b03938416815291909216602082015260408101919091526060019056fea2646970667358221220a118fe8c3b83b3933baa7bfe084ed165a014ec509367252e5c99e1a3332d000364736f6c634300080f0033
\ No newline at end of file
tests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/fractionalizer/Fractionalizer.sol
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: Apache License
+pragma solidity >=0.8.0;
+import {CollectionHelpers} from "../api/CollectionHelpers.sol";
+import {ContractHelpers} from "../api/ContractHelpers.sol";
+import {UniqueRefungibleToken} from "../api/UniqueRefungibleToken.sol";
+import {UniqueRefungible} from "../api/UniqueRefungible.sol";
+import {UniqueNFT} from "../api/UniqueNFT.sol";
+
+/// @dev Fractionalization contract. It stores mappings between NFT and RFT tokens,
+/// stores allowlist of NFT tokens available for fractionalization, has methods
+/// for fractionalization and defractionalization of NFT tokens.
+contract Fractionalizer {
+ struct Token {
+ address _collection;
+ uint256 _tokenId;
+ }
+ address rftCollection;
+ mapping(address => bool) nftCollectionAllowList;
+ mapping(address => mapping(uint256 => uint256)) nft2rftMapping;
+ mapping(address => Token) rft2nftMapping;
+ bytes32 refungibleCollectionType = keccak256(bytes("ReFungible"));
+
+ receive() external payable onlyOwner {}
+
+ /// @dev Method modifier to only allow contract owner to call it.
+ modifier onlyOwner() {
+ address contracthelpersAddress = 0x842899ECF380553E8a4de75bF534cdf6fBF64049;
+ ContractHelpers contractHelpers = ContractHelpers(contracthelpersAddress);
+ address contractOwner = contractHelpers.contractOwner(address(this));
+ require(msg.sender == contractOwner, "Only owner can");
+ _;
+ }
+
+ /// @dev This emits when RFT collection setting is changed.
+ event RFTCollectionSet(address _collection);
+
+ /// @dev This emits when NFT collection is allowed or disallowed.
+ event AllowListSet(address _collection, bool _status);
+
+ /// @dev This emits when NFT token is fractionalized by contract.
+ event Fractionalized(address _collection, uint256 _tokenId, address _rftToken, uint128 _amount);
+
+ /// @dev This emits when NFT token is defractionalized by contract.
+ event Defractionalized(address _rftToken, address _nftCollection, uint256 _nftTokenId);
+
+ /// Set RFT collection that contract will work with. RFT tokens for fractionalized NFT tokens
+ /// would be created in this collection.
+ /// @dev Throws if RFT collection is already configured for this contract.
+ /// Throws if collection of wrong type (NFT, Fungible) is provided instead
+ /// of RFT collection.
+ /// Throws if `msg.sender` is not owner or admin of provided RFT collection.
+ /// Can only be called by contract owner.
+ /// @param _collection address of RFT collection.
+ function setRFTCollection(address _collection) public onlyOwner {
+ require(
+ rftCollection == address(0),
+ "RFT collection is already set"
+ );
+ UniqueRefungible refungibleContract = UniqueRefungible(_collection);
+ string memory collectionType = refungibleContract.uniqueCollectionType();
+
+ require(
+ keccak256(bytes(collectionType)) == refungibleCollectionType,
+ "Wrong collection type. Collection is not refungible."
+ );
+ require(
+ refungibleContract.verifyOwnerOrAdmin(address(this)),
+ "Fractionalizer contract should be an admin of the collection"
+ );
+ rftCollection = _collection;
+ emit RFTCollectionSet(rftCollection);
+ }
+
+ /// Creates and sets RFT collection that contract will work with. RFT tokens for fractionalized NFT tokens
+ /// would be created in this collection.
+ /// @dev Throws if RFT collection is already configured for this contract.
+ /// Can only be called by contract owner.
+ /// @param _name name for created RFT collection.
+ /// @param _description description for created RFT collection.
+ /// @param _tokenPrefix token prefix for created RFT collection.
+ function createAndSetRFTCollection(string calldata _name, string calldata _description, string calldata _tokenPrefix) public onlyOwner {
+ require(
+ rftCollection == address(0),
+ "RFT collection is already set"
+ );
+ address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;
+ rftCollection = CollectionHelpers(collectionHelpers).createRefungibleCollection(_name, _description, _tokenPrefix);
+ emit RFTCollectionSet(rftCollection);
+ }
+
+ /// Allow or disallow NFT collection tokens from being fractionalized by this contract.
+ /// @dev Can only be called by contract owner.
+ /// @param collection NFT token address.
+ /// @param status `true` to allow and `false` to disallow NFT token.
+ function setNftCollectionIsAllowed(address collection, bool status) public onlyOwner {
+ nftCollectionAllowList[collection] = status;
+ emit AllowListSet(collection, status);
+ }
+
+ /// Fractionilize NFT token.
+ /// @dev Takes NFT token from `msg.sender` and transfers RFT token to `msg.sender`
+ /// instead. Creates new RFT token if provided NFT token never was fractionalized
+ /// by this contract or existing RFT token if it was.
+ /// Throws if RFT collection isn't configured for this contract.
+ /// Throws if fractionalization of provided NFT token is not allowed
+ /// Throws if `msg.sender` is not owner of provided NFT token
+ /// @param _collection NFT collection address
+ /// @param _token id of NFT token to be fractionalized
+ /// @param _pieces number of pieces new RFT token would have
+ function nft2rft(address _collection, uint256 _token, uint128 _pieces) public {
+ require(
+ rftCollection != address(0),
+ "RFT collection is not set"
+ );
+ UniqueRefungible rftCollectionContract = UniqueRefungible(rftCollection);
+ require(
+ nftCollectionAllowList[_collection] == true,
+ "Fractionalization of this collection is not allowed by admin"
+ );
+ require(
+ UniqueNFT(_collection).ownerOf(_token) == msg.sender,
+ "Only token owner could fractionalize it"
+ );
+ UniqueNFT(_collection).transferFrom(
+ msg.sender,
+ address(this),
+ _token
+ );
+ uint256 rftTokenId;
+ address rftTokenAddress;
+ UniqueRefungibleToken rftTokenContract;
+ if (nft2rftMapping[_collection][_token] == 0) {
+ rftTokenId = rftCollectionContract.nextTokenId();
+ rftCollectionContract.mint(address(this), rftTokenId);
+ rftTokenAddress = rftCollectionContract.tokenContractAddress(rftTokenId);
+ nft2rftMapping[_collection][_token] = rftTokenId;
+ rft2nftMapping[rftTokenAddress] = Token(_collection, _token);
+
+ rftTokenContract = UniqueRefungibleToken(rftTokenAddress);
+ rftTokenContract.setParentNFT(_collection, _token);
+ } else {
+ rftTokenId = nft2rftMapping[_collection][_token];
+ rftTokenAddress = rftCollectionContract.tokenContractAddress(rftTokenId);
+ rftTokenContract = UniqueRefungibleToken(rftTokenAddress);
+ }
+ rftTokenContract.repartition(_pieces);
+ rftTokenContract.transfer(msg.sender, _pieces);
+ emit Fractionalized(_collection, _token, rftTokenAddress, _pieces);
+ }
+
+ /// Defrationalize NFT token.
+ /// @dev Takes RFT token from `msg.sender` and transfers corresponding NFT token
+ /// to `msg.sender` instead.
+ /// Throws if RFT collection isn't configured for this contract.
+ /// Throws if provided RFT token is no from configured RFT collection.
+ /// Throws if RFT token was not created by this contract.
+ /// Throws if `msg.sender` isn't owner of all RFT token pieces.
+ /// @param _collection RFT collection address
+ /// @param _token id of RFT token
+ function rft2nft(address _collection, uint256 _token) public {
+ require(
+ rftCollection != address(0),
+ "RFT collection is not set"
+ );
+ require(
+ rftCollection == _collection,
+ "Wrong RFT collection"
+ );
+ UniqueRefungible rftCollectionContract = UniqueRefungible(rftCollection);
+ address rftTokenAddress = rftCollectionContract.tokenContractAddress(_token);
+ Token memory nftToken = rft2nftMapping[rftTokenAddress];
+ require(
+ nftToken._collection != address(0),
+ "No corresponding NFT token found"
+ );
+ UniqueRefungibleToken rftTokenContract = UniqueRefungibleToken(rftTokenAddress);
+ require(
+ rftTokenContract.balanceOf(msg.sender) == rftTokenContract.totalSupply(),
+ "Not all pieces are owned by the caller"
+ );
+ rftCollectionContract.transferFrom(msg.sender, address(this), _token);
+ UniqueNFT(nftToken._collection).transferFrom(
+ address(this),
+ msg.sender,
+ nftToken._tokenId
+ );
+ emit Defractionalized(rftTokenAddress, nftToken._collection, nftToken._tokenId);
+ }
+}
\ No newline at end of file
tests/src/eth/fractionalizer/FractionalizerAbi.jsondiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/fractionalizer/FractionalizerAbi.json
@@ -0,0 +1,142 @@
+[
+ { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_collection",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_status",
+ "type": "bool"
+ }
+ ],
+ "name": "AllowListSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_rftToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_nftCollection",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_nftTokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Defractionalized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_collection",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_rftToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint128",
+ "name": "_amount",
+ "type": "uint128"
+ }
+ ],
+ "name": "Fractionalized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_collection",
+ "type": "address"
+ }
+ ],
+ "name": "RFTCollectionSet",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ { "internalType": "string", "name": "_name", "type": "string" },
+ { "internalType": "string", "name": "_description", "type": "string" },
+ { "internalType": "string", "name": "_tokenPrefix", "type": "string" }
+ ],
+ "name": "createAndSetRFTCollection",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "_collection", "type": "address" },
+ { "internalType": "uint256", "name": "_token", "type": "uint256" },
+ { "internalType": "uint128", "name": "_pieces", "type": "uint128" }
+ ],
+ "name": "nft2rft",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "_collection", "type": "address" },
+ { "internalType": "uint256", "name": "_token", "type": "uint256" }
+ ],
+ "name": "rft2nft",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "collection", "type": "address" },
+ { "internalType": "bool", "name": "status", "type": "bool" }
+ ],
+ "name": "setNftCollectionIsAllowed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "_collection", "type": "address" }
+ ],
+ "name": "setRFTCollection",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
tests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/fractionalizer/fractionalizer.test.ts
@@ -0,0 +1,470 @@
+// 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/>.
+
+
+import Web3 from 'web3';
+import {ApiPromise} from '@polkadot/api';
+import {evmToAddress} from '@polkadot/util-crypto';
+import {readFile} from 'fs/promises';
+import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api';
+import {getCreateCollectionResult, getCreateItemResult, UNIQUE} from '../../util/helpers';
+import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers';
+import {Contract} from 'web3-eth-contract';
+import * as solc from 'solc';
+
+import chai from 'chai';
+import chaiLike from 'chai-like';
+import {IKeyringPair} from '@polkadot/types/types';
+chai.use(chaiLike);
+const expect = chai.expect;
+let fractionalizer: CompiledContract;
+
+async function compileFractionalizer() {
+ if (!fractionalizer) {
+ const input = {
+ language: 'Solidity',
+ sources: {
+ ['Fractionalizer.sol']: {
+ content: (await readFile(`${__dirname}/Fractionalizer.sol`)).toString(),
+ },
+ },
+ settings: {
+ outputSelection: {
+ '*': {
+ '*': ['*'],
+ },
+ },
+ },
+ };
+ const json = JSON.parse(solc.compile(JSON.stringify(input), {import: await findImports()}));
+ const out = json.contracts['Fractionalizer.sol']['Fractionalizer'];
+
+ fractionalizer = {
+ abi: out.abi,
+ object: '0x' + out.evm.bytecode.object,
+ };
+ }
+ return fractionalizer;
+}
+
+async function findImports() {
+ const collectionHelpers = (await readFile(`${__dirname}/../api/CollectionHelpers.sol`)).toString();
+ const contractHelpers = (await readFile(`${__dirname}/../api/ContractHelpers.sol`)).toString();
+ const uniqueRefungibleToken = (await readFile(`${__dirname}/../api/UniqueRefungibleToken.sol`)).toString();
+ const uniqueRefungible = (await readFile(`${__dirname}/../api/UniqueRefungible.sol`)).toString();
+ const uniqueNFT = (await readFile(`${__dirname}/../api/UniqueNFT.sol`)).toString();
+
+ return function(path: string) {
+ switch (path) {
+ case 'api/CollectionHelpers.sol': return {contents: `${collectionHelpers}`};
+ case 'api/ContractHelpers.sol': return {contents: `${contractHelpers}`};
+ case 'api/UniqueRefungibleToken.sol': return {contents: `${uniqueRefungibleToken}`};
+ case 'api/UniqueRefungible.sol': return {contents: `${uniqueRefungible}`};
+ case 'api/UniqueNFT.sol': return {contents: `${uniqueNFT}`};
+ default: return {error: 'File not found'};
+ }
+ };
+}
+
+async function deployFractionalizer(web3: Web3, owner: string) {
+ const compiled = await compileFractionalizer();
+ const fractionalizerContract = new web3.eth.Contract(compiled.abi, undefined, {
+ data: compiled.object,
+ from: owner,
+ ...GAS_ARGS,
+ });
+ return await fractionalizerContract.deploy({data: compiled.object}).send({from: owner});
+}
+
+async function initFractionalizer(api: ApiPromise, web3: Web3, privateKeyWrapper: (account: string) => IKeyringPair, owner: string) {
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const amount = 10n * UNIQUE;
+ await web3.eth.sendTransaction({from: owner, to: fractionalizer.options.address, value: `${amount}`, ...GAS_ARGS});
+ const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send();
+ const rftCollectionAddress = result.events.RFTCollectionSet.returnValues._collection;
+ return {fractionalizer, rftCollectionAddress};
+}
+
+async function createRFTToken(api: ApiPromise, web3: Web3, owner: string, fractionalizer: Contract, amount: bigint) {
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+
+ await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+ await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
+ const result = await fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, amount).send();
+ const {_collection, _tokenId, _rftToken} = result.events.Fractionalized.returnValues;
+ return {
+ nftCollectionAddress: _collection,
+ nftTokenId: _tokenId,
+ rftTokenAddress: _rftToken,
+ };
+}
+
+describe('Fractionalizer contract usage', () => {
+ itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);
+ const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
+ await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
+ const result = await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();
+ expect(result.events).to.be.like({
+ RFTCollectionSet: {
+ returnValues: {
+ _collection: collectionIdAddress,
+ },
+ },
+ });
+ });
+
+ itWeb3('Mint RFT collection', async ({api, web3, privateKeyWrapper}) => {
+ const alice = privateKeyWrapper('//Alice');
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const tx = api.tx.balances.transfer(evmToAddress(fractionalizer.options.address), 10n * UNIQUE);
+ await submitTransactionAsync(alice, tx);
+
+ const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner});
+ expect(result.events).to.be.like({
+ RFTCollectionSet: {},
+ });
+ expect(result.events.RFTCollectionSet.returnValues._collection).to.be.ok;
+ });
+
+ itWeb3('Set Allowlist', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const result1 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send({from: owner});
+ expect(result1.events).to.be.like({
+ AllowListSet: {
+ returnValues: {
+ _collection: nftCollectionAddress,
+ _status: true,
+ },
+ },
+ });
+ const result2 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, false).send({from: owner});
+ expect(result2.events).to.be.like({
+ AllowListSet: {
+ returnValues: {
+ _collection: nftCollectionAddress,
+ _status: false,
+ },
+ },
+ });
+ });
+
+ itWeb3('NFT to RFT', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+
+ await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+ await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
+ const result = await fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).send();
+ expect(result.events).to.be.like({
+ Fractionalized: {
+ returnValues: {
+ _collection: nftCollectionAddress,
+ _tokenId: nftTokenId,
+ _amount: '100',
+ },
+ },
+ });
+ const rftTokenAddress = result.events.Fractionalized.returnValues._rftToken;
+ const rftTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
+ expect(await rftTokenContract.methods.balanceOf(owner).call()).to.equal('100');
+ });
+
+ itWeb3('RFT to NFT', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {fractionalizer, rftCollectionAddress} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+ const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await createRFTToken(api, web3, owner, fractionalizer, 100n);
+
+ const {collectionId, tokenId} = tokenIdFromAddress(rftTokenAddress);
+ const refungibleAddress = collectionIdToAddress(collectionId);
+ expect(rftCollectionAddress).to.be.equal(refungibleAddress);
+ const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
+ await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send();
+ const result = await fractionalizer.methods.rft2nft(refungibleAddress, tokenId).send();
+ expect(result.events).to.be.like({
+ Defractionalized: {
+ returnValues: {
+ _rftToken: rftTokenAddress,
+ _nftCollection: nftCollectionAddress,
+ _nftTokenId: nftTokenId,
+ },
+ },
+ });
+ });
+});
+
+
+
+describe('Negative Integration Tests for fractionalizer', () => {
+ itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);
+ const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
+
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
+ await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();
+
+ await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+ .to.be.rejectedWith(/RFT collection is already set$/g);
+ });
+
+ itWeb3('call setRFTCollection with NFT collection', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const {collectionIdAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, collectionIdAddress, owner);
+
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ await nftContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
+
+ await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+ .to.be.rejectedWith(/Wrong collection type. Collection is not refungible.$/g);
+ });
+
+ itWeb3('call setRFTCollection while not collection admin', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);
+
+ await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+ .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);
+ });
+
+ itWeb3('call setRFTCollection after createAndSetRFTCollection', async ({api, web3, privateKeyWrapper}) => {
+ const alice = privateKeyWrapper('//Alice');
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const tx = api.tx.balances.transfer(evmToAddress(fractionalizer.options.address), 10n * UNIQUE);
+ await submitTransactionAsync(alice, tx);
+
+ const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner});
+ const collectionIdAddress = result.events.RFTCollectionSet.returnValues._collection;
+
+ await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+ .to.be.rejectedWith(/RFT collection is already set$/g);
+ });
+
+ itWeb3('call nft2rft without setting RFT collection for contract', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+
+ const fractionalizer = await deployFractionalizer(web3, owner);
+
+ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+ .to.be.rejectedWith(/RFT collection is not set$/g);
+ });
+
+ itWeb3('call nft2rft while not owner of NFT token', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const nftOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+ await nftContract.methods.transfer(nftOwner, 1).send();
+
+
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+ await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+
+ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+ .to.be.rejectedWith(/Only token owner could fractionalize it$/g);
+ });
+
+ itWeb3('call nft2rft while not in list of allowed accounts', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+
+ await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
+ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+ .to.be.rejectedWith(/Fractionalization of this collection is not allowed by admin$/g);
+ });
+
+ itWeb3('call nft2rft while fractionalizer doesnt have approval for nft token', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+
+ await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+ .to.be.rejectedWith(/ApprovedValueTooLow$/g);
+ });
+
+ itWeb3('call rft2nft without setting RFT collection for contract', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);
+ const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
+ const rftTokenId = await refungibleContract.methods.nextTokenId().call();
+ await refungibleContract.methods.mint(owner, rftTokenId).send();
+
+ await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, rftTokenId).call())
+ .to.be.rejectedWith(/RFT collection is not set$/g);
+ });
+
+ itWeb3('call rft2nft for RFT token that is not from configured RFT collection', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+ const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);
+ const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
+ const rftTokenId = await refungibleContract.methods.nextTokenId().call();
+ await refungibleContract.methods.mint(owner, rftTokenId).send();
+
+ await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, rftTokenId).call())
+ .to.be.rejectedWith(/Wrong RFT collection$/g);
+ });
+
+ itWeb3('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);
+
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
+
+ await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
+ await fractionalizer.methods.setRFTCollection(rftCollectionAddress).send();
+
+ const rftTokenId = await refungibleContract.methods.nextTokenId().call();
+ await refungibleContract.methods.mint(owner, rftTokenId).send();
+
+ await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, rftTokenId).call())
+ .to.be.rejectedWith(/No corresponding NFT token found$/g);
+ });
+
+ itWeb3('call rft2nft without owning all RFT pieces', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {fractionalizer, rftCollectionAddress} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+ const {rftTokenAddress} = await createRFTToken(api, web3, owner, fractionalizer, 100n);
+
+ const {tokenId} = tokenIdFromAddress(rftTokenAddress);
+ const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
+ await refungibleTokenContract.methods.transfer(receiver, 50).send();
+ await refungibleTokenContract.methods.approve(fractionalizer.options.address, 50).send();
+ await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, tokenId).call())
+ .to.be.rejectedWith(/Not all pieces are owned by the caller$/g);
+ });
+
+ itWeb3('send QTZ/UNQ to contract from non owner', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const payer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ const amount = 10n * UNIQUE;
+ await expect(web3.eth.sendTransaction({from: payer, to: fractionalizer.options.address, value: `${amount}`, ...GAS_ARGS})).to.be.rejected;
+ });
+
+ itWeb3('fractionalize NFT with NFT transfers disallowed', async ({api, web3, privateKeyWrapper}) => {
+ const alice = privateKeyWrapper('//Alice');
+ let collectionId;
+ {
+ const tx = api.tx.unique.createCollectionEx({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'});
+ const events = await submitTransactionAsync(alice, tx);
+ const result = getCreateCollectionResult(events);
+ collectionId = result.collectionId;
+ }
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ let nftTokenId;
+ {
+ const createData = {nft: {}};
+ const tx = api.tx.unique.createItem(collectionId, {Ethereum: owner}, createData as any);
+ const events = await executeTransaction(api, alice, tx);
+ const result = getCreateItemResult(events);
+ nftTokenId = result.itemId;
+ }
+ {
+ const tx = api.tx.unique.setTransfersEnabledFlag(collectionId, false);
+ await executeTransaction(api, alice, tx);
+ }
+ const nftCollectionAddress = collectionIdToAddress(collectionId);
+ const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+ await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
+ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+ .to.be.rejectedWith(/TransferNotAllowed$/g);
+ });
+
+ itWeb3('fractionalize NFT with RFT transfers disallowed', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ const alice = privateKeyWrapper('//Alice');
+
+ let collectionId;
+ {
+ const tx = api.tx.unique.createCollectionEx({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'ReFungible'});
+ const events = await submitTransactionAsync(alice, tx);
+ const result = getCreateCollectionResult(events);
+ collectionId = result.collectionId;
+ }
+ const rftCollectionAddress = collectionIdToAddress(collectionId);
+ const fractionalizer = await deployFractionalizer(web3, owner);
+ {
+ const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, {Ethereum: fractionalizer.options.address});
+ await submitTransactionAsync(alice, changeAdminTx);
+ }
+ await fractionalizer.methods.setRFTCollection(rftCollectionAddress).send();
+ {
+ const tx = api.tx.unique.setTransfersEnabledFlag(collectionId, false);
+ await executeTransaction(api, alice, tx);
+ }
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+
+ await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+ await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
+
+ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100n).call())
+ .to.be.rejectedWith(/TransferNotAllowed$/g);
+ });
+});
\ No newline at end of file
tests/src/eth/fungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/fungibleAbi.json
+++ b/tests/src/eth/fungibleAbi.json
@@ -301,5 +301,21 @@
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
"type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "uniqueCollectionType",
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "user", "type": "address" }
+ ],
+ "name": "verifyOwnerOrAdmin",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "view",
+ "type": "function"
}
]
tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -526,5 +526,21 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "uniqueCollectionType",
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "user", "type": "address" }
+ ],
+ "name": "verifyOwnerOrAdmin",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "view",
+ "type": "function"
}
]
tests/src/eth/reFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -14,12 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {createCollectionExpectSuccess, UNIQUE} from '../util/helpers';
-import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress} from './util/helpers';
-import reFungibleTokenAbi from './reFungibleTokenAbi.json';
+import {createCollectionExpectSuccess, UNIQUE, requirePallets, Pallets} from '../util/helpers';
+import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress, uniqueRefungibleToken} from './util/helpers';
import {expect} from 'chai';
describe('Refungible: Information getting', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const helper = evmCollectionHelpers(web3, caller);
@@ -84,7 +87,7 @@
await contract.methods.mint(caller, tokenId).send();
const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});
+ const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
@@ -108,7 +111,7 @@
await contract.methods.mint(caller, tokenId).send();
const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});
+ const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
@@ -120,6 +123,10 @@
});
describe('Refungible: Plain calls', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const helper = evmCollectionHelpers(web3, owner);
@@ -250,7 +257,7 @@
await contract.methods.mint(caller, tokenId).send();
const address = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});
+ const tokenContract = uniqueRefungibleToken(web3, address, caller);
await tokenContract.methods.repartition(15).send();
{
@@ -269,7 +276,7 @@
},
]);
});
-
+
expect(erc20Events).to.include.deep.members([
{
address,
@@ -345,12 +352,12 @@
await contract.methods.mint(caller, tokenId).send();
const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});
+ const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
- const events = await recordEvents(contract, async () =>
+ const events = await recordEvents(contract, async () =>
await tokenContract.methods.transfer(receiver, 1).send());
expect(events).to.deep.equal([
{
@@ -377,13 +384,13 @@
await contract.methods.mint(caller, tokenId).send();
const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});
+ const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
await tokenContract.methods.repartition(2).send();
-
- const events = await recordEvents(contract, async () =>
+
+ const events = await recordEvents(contract, async () =>
await tokenContract.methods.transfer(receiver, 1).send());
-
+
expect(events).to.deep.equal([
{
address: collectionIdAddress,
@@ -399,6 +406,10 @@
});
describe('RFT: Fees', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const helper = evmCollectionHelpers(web3, caller);
@@ -435,6 +446,10 @@
});
describe('Common metadata', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {
const collection = await createCollectionExpectSuccess({
name: 'token name',
@@ -462,4 +477,4 @@
expect(symbol).to.equal('TOK');
});
-});
\ No newline at end of file
+});
tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleAbi.json
+++ b/tests/src/eth/reFungibleAbi.json
@@ -482,6 +482,15 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "token", "type": "uint256" }
+ ],
+ "name": "tokenContractAddress",
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
@@ -526,5 +535,21 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "uniqueCollectionType",
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "user", "type": "address" }
+ ],
+ "name": "verifyOwnerOrAdmin",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "view",
+ "type": "function"
}
]
tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungibleToken.test.ts
+++ b/tests/src/eth/reFungibleToken.test.ts
@@ -14,9 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';
-import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';
-import reFungibleTokenAbi from './reFungibleTokenAbi.json';
+import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';
+import {collectionIdFromAddress, collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
@@ -24,6 +23,10 @@
const expect = chai.expect;
describe('Refungible token: Information getting', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
const alice = privateKeyWrapper('//Alice');
@@ -34,7 +37,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, caller);
const totalSupply = await contract.methods.totalSupply().call();
expect(totalSupply).to.equal('200');
@@ -50,7 +53,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, caller);
const balance = await contract.methods.balanceOf(caller).call();
expect(balance).to.equal('200');
@@ -66,7 +69,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, caller);
const decimals = await contract.methods.decimals().call();
expect(decimals).to.equal('0');
@@ -75,6 +78,10 @@
// FIXME: Need erc721 for ReFubgible.
describe('Check ERC721 token URI for ReFungible', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {
const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const helper = evmCollectionHelpers(web3, owner);
@@ -82,7 +89,7 @@
const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
const receiver = createEthAccount(web3);
const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
-
+
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
result = await contract.methods.mint(
@@ -115,17 +122,17 @@
const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
const receiver = createEthAccount(web3);
const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
-
+
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
result = await contract.methods.mint(
receiver,
nextTokenId,
).send();
-
+
// Set URL
await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();
-
+
const events = normalizeEvents(result.events);
const address = collectionIdToAddress(collectionId);
@@ -151,14 +158,14 @@
const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
const receiver = createEthAccount(web3);
const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
-
+
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
result = await contract.methods.mint(
receiver,
nextTokenId,
).send();
-
+
const events = normalizeEvents(result.events);
const address = collectionIdToAddress(collectionId);
@@ -184,14 +191,14 @@
const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
const receiver = createEthAccount(web3);
const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
-
+
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
result = await contract.methods.mint(
receiver,
nextTokenId,
).send();
-
+
// Set suffix
const suffix = '/some/suffix';
await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();
@@ -216,6 +223,10 @@
});
describe('Refungible: Plain calls', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {
const alice = privateKeyWrapper('//Alice');
@@ -229,7 +240,7 @@
const spender = createEthAccount(web3);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
{
const result = await contract.methods.approve(spender, 100).send({from: owner});
@@ -270,7 +281,7 @@
const receiver = createEthAccount(web3);
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
await contract.methods.approve(spender, 100).send();
@@ -324,7 +335,7 @@
await transferBalanceToEth(api, alice, receiver);
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
{
const result = await contract.methods.transfer(receiver, 50).send({from: owner});
@@ -367,14 +378,14 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
await contract.methods.repartition(200).send({from: owner});
expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);
await contract.methods.transfer(receiver, 110).send({from: owner});
expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);
expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);
-
+
await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;
await contract.methods.transfer(receiver, 90).send({from: owner});
@@ -397,7 +408,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
const result = await contract.methods.repartition(200).send();
const events = normalizeEvents(result.events);
@@ -426,7 +437,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
const result = await contract.methods.repartition(50).send();
const events = normalizeEvents(result.events);
@@ -456,11 +467,11 @@
const address = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});
+ const tokenContract = uniqueRefungibleToken(web3, address, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
- const events = await recordEvents(contract, async () =>
+ const events = await recordEvents(contract, async () =>
await tokenContract.methods.burnFrom(caller, 1).send());
expect(events).to.deep.equal([
{
@@ -477,6 +488,10 @@
});
describe('Refungible: Fees', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
const alice = privateKeyWrapper('//Alice');
@@ -488,7 +503,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));
expect(cost < BigInt(0.2 * Number(UNIQUE)));
@@ -505,7 +520,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
await contract.methods.approve(spender, 100).send({from: owner});
@@ -524,7 +539,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = uniqueRefungibleToken(web3, address, owner);
const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));
expect(cost < BigInt(0.2 * Number(UNIQUE)));
@@ -532,6 +547,10 @@
});
describe('Refungible: Substrate calls', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+ });
+
itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {
const alice = privateKeyWrapper('//Alice');
@@ -542,7 +561,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);
+ const contract = uniqueRefungibleToken(web3, address);
const events = await recordEvents(contract, async () => {
expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;
@@ -573,7 +592,7 @@
expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);
+ const contract = uniqueRefungibleToken(web3, address);
const events = await recordEvents(contract, async () => {
expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;
@@ -611,7 +630,7 @@
const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;
const address = tokenIdToAddress(collectionId, tokenId);
- const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);
+ const contract = uniqueRefungibleToken(web3, address);
const events = await recordEvents(contract, async () => {
expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;
@@ -630,3 +649,47 @@
]);
});
});
+
+describe('ERC 1633 implementation', () => {
+ itWeb3('Parent NFT token address and id', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
+ const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+ const nftTokenId = await nftContract.methods.nextTokenId().call();
+ await nftContract.methods.mint(owner, nftTokenId).send();
+ const nftCollectionId = collectionIdFromAddress(nftCollectionAddress);
+
+ const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);
+ const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
+ const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();
+ await refungibleContract.methods.mint(owner, refungibleTokenId).send();
+
+ const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);
+ const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
+ await refungibleTokenContract.methods.setParentNFT(nftCollectionAddress, nftTokenId).send();
+
+ const tokenAddress = await refungibleTokenContract.methods.parentToken().call();
+ const tokenId = await refungibleTokenContract.methods.parentTokenId().call();
+ const nftTokenAddress = tokenIdToAddress(nftCollectionId, nftTokenId);
+ expect(tokenAddress).to.be.equal(nftTokenAddress);
+ expect(tokenId).to.be.equal(nftTokenId);
+ });
+
+ itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {
+ const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+
+ const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);
+ const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
+ const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();
+ await refungibleContract.methods.mint(owner, refungibleTokenId).send();
+
+ const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);
+ const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
+
+ const tokenAddress = await refungibleTokenContract.methods.parentToken().call();
+ const tokenId = await refungibleTokenContract.methods.parentTokenId().call();
+ expect(tokenAddress).to.be.equal(rftTokenAddress);
+ expect(tokenId).to.be.equal(refungibleTokenId);
+ });
+});
tests/src/eth/reFungibleTokenAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleTokenAbi.json
+++ b/tests/src/eth/reFungibleTokenAbi.json
@@ -103,6 +103,20 @@
"type": "function"
},
{
+ "inputs": [],
+ "name": "parentToken",
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "parentTokenId",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"inputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
@@ -113,6 +127,16 @@
},
{
"inputs": [
+ { "internalType": "address", "name": "collection", "type": "address" },
+ { "internalType": "uint256", "name": "nftId", "type": "uint256" }
+ ],
+ "name": "setParentNFT",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
],
"name": "supportsInterface",
tests/src/eth/scheduling.test.tsdiffbeforeafterboth--- a/tests/src/eth/scheduling.test.ts
+++ b/tests/src/eth/scheduling.test.ts
@@ -16,9 +16,13 @@
import {expect} from 'chai';
import {createEthAccountWithBalance, deployFlipper, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from './util/helpers';
-import {scheduleExpectSuccess, waitNewBlocks} from '../util/helpers';
+import {scheduleExpectSuccess, waitNewBlocks, requirePallets, Pallets} from '../util/helpers';
describe('Scheduing EVM smart contracts', () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.Scheduler]);
+ });
+
itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3, privateKeyWrapper}) => {
const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const flipper = await deployFlipper(web3, deployer);
@@ -51,4 +55,4 @@
expect(await flipper.methods.getValue().call()).to.be.equal(initialValue);
}
});
-});
\ No newline at end of file
+});
tests/src/eth/util/helpers.tsdiffbeforeafterboth--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -32,6 +32,7 @@
import fungibleAbi from '../fungibleAbi.json';
import nonFungibleAbi from '../nonFungibleAbi.json';
import refungibleAbi from '../reFungibleAbi.json';
+import refungibleTokenAbi from '../reFungibleTokenAbi.json';
import contractHelpersAbi from './contractHelpersAbi.json';
export const GAS_ARGS = {gas: 2500000};
@@ -101,6 +102,18 @@
]);
return Web3.utils.toChecksumAddress('0x' + buf.toString('hex'));
}
+
+export function tokenIdFromAddress(address: string) {
+ if (!address.startsWith('0x'))
+ throw 'address not starts with "0x"';
+ if (address.length > 42)
+ throw 'address length is more than 20 bytes';
+ return {
+ collectionId: Number('0x' + address.substring(address.length - 16, address.length - 8)),
+ tokenId: Number('0x' + address.substring(address.length - 8)),
+ };
+}
+
export function tokenIdToCross(collection: number, token: number): CrossAccountId {
return {
Ethereum: tokenIdToAddress(collection, token),
@@ -128,6 +141,44 @@
expect(result.success).to.be.true;
}
+export async function createRefungibleCollection(api: ApiPromise, web3: Web3, owner: string) {
+ const collectionHelper = evmCollectionHelpers(web3, owner);
+ const result = await collectionHelper.methods
+ .createRefungibleCollection('A', 'B', 'C')
+ .send();
+ return await getCollectionAddressFromResult(api, result);
+}
+
+
+export async function createNonfungibleCollection(api: ApiPromise, web3: Web3, owner: string) {
+ const collectionHelper = evmCollectionHelpers(web3, owner);
+ const result = await collectionHelper.methods
+ .createNonfungibleCollection('A', 'B', 'C')
+ .send();
+ return await getCollectionAddressFromResult(api, result);
+}
+
+export function uniqueNFT(web3: Web3, address: string, owner: string) {
+ return new web3.eth.Contract(nonFungibleAbi as any, address, {
+ from: owner,
+ ...GAS_ARGS,
+ });
+}
+
+export function uniqueRefungible(web3: Web3, collectionAddress: string, owner: string) {
+ return new web3.eth.Contract(refungibleAbi as any, collectionAddress, {
+ from: owner,
+ ...GAS_ARGS,
+ });
+}
+
+export function uniqueRefungibleToken(web3: Web3, tokenAddress: string, owner: string | undefined = undefined) {
+ return new web3.eth.Contract(refungibleTokenAbi as any, tokenAddress, {
+ from: owner,
+ ...GAS_ARGS,
+ });
+}
+
export async function itWeb3(name: string, cb: (apis: { web3: Web3, api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any, opts: { only?: boolean, skip?: boolean } = {}) {
let i: any = it;
if (opts.only) i = i.only;
@@ -199,7 +250,12 @@
return Web3.utils.toChecksumAddress(subToEthLowercase(eth));
}
-export function compileContract(name: string, src: string) {
+export interface CompiledContract {
+ abi: any,
+ object: string,
+}
+
+export function compileContract(name: string, src: string) : CompiledContract {
const out = JSON.parse(solc.compile(JSON.stringify({
language: 'Solidity',
sources: {
tests/src/fungible.test.tsdiffbeforeafterboth--- a/tests/src/fungible.test.ts
+++ b/tests/src/fungible.test.ts
@@ -14,25 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {default as usingApi} from './substrate/substrate-api';
import {IKeyringPair} from '@polkadot/types/types';
-import {
- getBalance,
- createMultipleItemsExpectSuccess,
- isTokenExists,
- getLastTokenId,
- getAllowance,
- approve,
- transferFrom,
- createCollection,
- transfer,
- burnItem,
- normalizeAccountId,
- CrossAccountId,
- createFungibleItemExpectSuccess,
- U128_MAX,
- burnFromExpectSuccess,
-} from './util/helpers';
+import {U128_MAX} from './util/helpers';
+
+import {usingPlaygrounds} from './util/playgrounds';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
@@ -44,141 +29,137 @@
describe('integration test: Fungible functionality:', () => {
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
+ await usingPlaygrounds(async (helper, privateKey) => {
+ alice = privateKey('//Alice');
+ bob = privateKey('//Bob');
});
});
it('Create fungible collection and token', async () => {
- await usingApi(async api => {
- const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});
- expect(createCollectionResult.success).to.be.true;
- const collectionId = createCollectionResult.collectionId;
- const defaultTokenId = await getLastTokenId(api, collectionId);
- const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);
- const aliceBalance = await getBalance(api, collectionId, alice, aliceTokenId);
- const itemCountAfter = await getLastTokenId(api, collectionId);
-
- // What to expect
- // tslint:disable-next-line:no-unused-expression
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
+ const defaultTokenId = await collection.getLastTokenId();
+ expect(defaultTokenId).to.be.equal(0);
+
+ await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
+ const aliceBalance = await collection.getBalance({Substrate: alice.address});
+ const itemCountAfter = await collection.getLastTokenId();
+
expect(itemCountAfter).to.be.equal(defaultTokenId);
expect(aliceBalance).to.be.equal(U128_MAX);
});
});
it('RPC method tokenOnewrs for fungible collection and token', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
+ await usingPlaygrounds(async (helper, privateKey) => {
const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
- const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));
+ const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
+
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+
+ await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
+
+ await collection.transfer(alice, {Substrate: bob.address}, 1000n);
+ await collection.transfer(alice, ethAcc, 900n);
- const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});
- const collectionId = createCollectionResult.collectionId;
- const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);
-
- await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
- await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
-
for (let i = 0; i < 7; i++) {
- await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);
+ await collection.transfer(alice, facelessCrowd[i], 1n);
}
-
- const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
- const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
- const aliceID = normalizeAccountId(alice);
- const bobId = normalizeAccountId(bob);
+ const owners = await collection.getTop10Owners();
+
// What to expect
- // tslint:disable-next-line:no-unused-expression
- expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
- expect(owners.length == 10).to.be.true;
+ expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+ expect(owners.length).to.be.equal(10);
- const eleven = privateKeyWrapper('11');
- expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;
- expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);
+ const eleven = privateKey('//ALice+11');
+ expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+ expect((await collection.getTop10Owners()).length).to.be.equal(10);
});
});
it('Transfer token', async () => {
- await usingApi(async api => {
+ await usingPlaygrounds(async helper => {
const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
- const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;
- const tokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: 500n}, alice.address);
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ await collection.mint(alice, {Substrate: alice.address}, 500n);
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(500n);
- expect(await transfer(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;
- expect(await transfer(api, collectionId, tokenId, alice, ethAcc, 140n)).to.be.true;
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
+ expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+ expect(await collection.transfer(alice, ethAcc, 140n)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(300n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(60n);
- expect(await getBalance(api, collectionId, ethAcc, tokenId)).to.be.equal(140n);
- await expect(transfer(api, collectionId, tokenId, alice, bob, 350n)).to.eventually.be.rejected;
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(300n);
+ expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(60n);
+ expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
+
+ await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
});
});
it('Tokens multiple creation', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;
-
- const args = [
- {Fungible: {Value: 500n}},
- {Fungible: {Value: 400n}},
- {Fungible: {Value: 300n}},
- ];
-
- await createMultipleItemsExpectSuccess(alice, collectionId, args);
- expect(await getBalance(api, collectionId, alice, 0)).to.be.equal(1200n);
- });
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+
+ await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [
+ {value: 500n},
+ {value: 400n},
+ {value: 300n},
+ ]);
+
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
+ });
});
it('Burn some tokens ', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;
- const tokenId = (await createFungibleItemExpectSuccess(alice, collectionId, {Value: 500n}, alice.address));
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(500n);
- expect(await burnItem(api, alice, collectionId, tokenId, 499n)).to.be.true;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(1n);
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ await collection.mint(alice, {Substrate: alice.address}, 500n);
+
+ expect(await collection.isTokenExists(0)).to.be.true;
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
+ expect(await collection.burnTokens(alice, 499n)).to.be.true;
+ expect(await collection.isTokenExists(0)).to.be.true;
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
});
});
it('Burn all tokens ', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;
- const tokenId = (await createFungibleItemExpectSuccess(alice, collectionId, {Value: 500n}, alice.address));
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await burnItem(api, alice, collectionId, tokenId, 500n)).to.be.true;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
-
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(0n);
- expect((await api.rpc.unique.totalPieces(collectionId, tokenId)).value.toBigInt()).to.be.equal(0n);
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ await collection.mint(alice, {Substrate: alice.address}, 500n);
+
+ expect(await collection.isTokenExists(0)).to.be.true;
+ expect(await collection.burnTokens(alice, 500n)).to.be.true;
+ expect(await collection.isTokenExists(0)).to.be.true;
+
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
+ expect(await collection.getTotalPieces()).to.be.equal(0n);
});
});
it('Set allowance for token', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+ await collection.mint(alice, {Substrate: alice.address}, 100n);
+
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
- const tokenId = (await createFungibleItemExpectSuccess(alice, collectionId, {Value: 100n}, alice.address));
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
+ expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
+ expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
+ expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
+
+ expect(await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(80n);
+ expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(20n);
+ expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
- expect(await approve(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;
- expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(60n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(0n);
-
- expect(await transferFrom(api, collectionId, tokenId, bob, alice, bob, 20n)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(80n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(20n);
- expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(40n);
-
- await burnFromExpectSuccess(bob, alice, collectionId, tokenId, 10n);
-
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(70n);
- expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(30n);
- expect(await transferFrom(api, collectionId, tokenId, bob, alice, ethAcc, 10n)).to.be.true;
- expect(await getBalance(api, collectionId, ethAcc, tokenId)).to.be.equal(10n);
+ await collection.burnTokensFrom(bob, {Substrate: alice.address}, 10n);
+
+ expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(70n);
+ expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
+ expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
+ expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
});
});
});
tests/src/interfaces/augment-api-query.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -266,7 +266,7 @@
*
* Currently used to store RMRK data.
**/
- tokenAuxProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: UpDataStructsPropertyScope | 'None' | 'Rmrk' | number | Uint8Array, arg4: Bytes | string | Uint8Array) => Observable<Option<Bytes>>, [u32, u32, UpDataStructsPropertyScope, Bytes]> & QueryableStorageEntry<ApiType, [u32, u32, UpDataStructsPropertyScope, Bytes]>;
+ tokenAuxProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: UpDataStructsPropertyScope | 'None' | 'Rmrk' | 'Eth' | number | Uint8Array, arg4: Bytes | string | Uint8Array) => Observable<Option<Bytes>>, [u32, u32, UpDataStructsPropertyScope, Bytes]> & QueryableStorageEntry<ApiType, [u32, u32, UpDataStructsPropertyScope, Bytes]>;
/**
* Used to enumerate token's children.
**/
tests/src/interfaces/default/types.tsdiffbeforeafterboth1// Auto-generated via `yarn polkadot-types-from-defs`, do not edit2/* eslint-disable */34import type { BTreeMap, BTreeSet, Bytes, Compact, Enum, Null, Option, Result, Struct, Text, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec';5import type { ITuple } from '@polkadot/types-codec/types';6import type { AccountId32, Call, H160, H256, MultiAddress, Perbill, Permill } from '@polkadot/types/interfaces/runtime';7import type { Event } from '@polkadot/types/interfaces/system';89/** @name CumulusPalletDmpQueueCall */10export interface CumulusPalletDmpQueueCall extends Enum {11 readonly isServiceOverweight: boolean;12 readonly asServiceOverweight: {13 readonly index: u64;14 readonly weightLimit: u64;15 } & Struct;16 readonly type: 'ServiceOverweight';17}1819/** @name CumulusPalletDmpQueueConfigData */20export interface CumulusPalletDmpQueueConfigData extends Struct {21 readonly maxIndividual: u64;22}2324/** @name CumulusPalletDmpQueueError */25export interface CumulusPalletDmpQueueError extends Enum {26 readonly isUnknown: boolean;27 readonly isOverLimit: boolean;28 readonly type: 'Unknown' | 'OverLimit';29}3031/** @name CumulusPalletDmpQueueEvent */32export interface CumulusPalletDmpQueueEvent extends Enum {33 readonly isInvalidFormat: boolean;34 readonly asInvalidFormat: {35 readonly messageId: U8aFixed;36 } & Struct;37 readonly isUnsupportedVersion: boolean;38 readonly asUnsupportedVersion: {39 readonly messageId: U8aFixed;40 } & Struct;41 readonly isExecutedDownward: boolean;42 readonly asExecutedDownward: {43 readonly messageId: U8aFixed;44 readonly outcome: XcmV2TraitsOutcome;45 } & Struct;46 readonly isWeightExhausted: boolean;47 readonly asWeightExhausted: {48 readonly messageId: U8aFixed;49 readonly remainingWeight: u64;50 readonly requiredWeight: u64;51 } & Struct;52 readonly isOverweightEnqueued: boolean;53 readonly asOverweightEnqueued: {54 readonly messageId: U8aFixed;55 readonly overweightIndex: u64;56 readonly requiredWeight: u64;57 } & Struct;58 readonly isOverweightServiced: boolean;59 readonly asOverweightServiced: {60 readonly overweightIndex: u64;61 readonly weightUsed: u64;62 } & Struct;63 readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward' | 'WeightExhausted' | 'OverweightEnqueued' | 'OverweightServiced';64}6566/** @name CumulusPalletDmpQueuePageIndexData */67export interface CumulusPalletDmpQueuePageIndexData extends Struct {68 readonly beginUsed: u32;69 readonly endUsed: u32;70 readonly overweightCount: u64;71}7273/** @name CumulusPalletParachainSystemCall */74export interface CumulusPalletParachainSystemCall extends Enum {75 readonly isSetValidationData: boolean;76 readonly asSetValidationData: {77 readonly data: CumulusPrimitivesParachainInherentParachainInherentData;78 } & Struct;79 readonly isSudoSendUpwardMessage: boolean;80 readonly asSudoSendUpwardMessage: {81 readonly message: Bytes;82 } & Struct;83 readonly isAuthorizeUpgrade: boolean;84 readonly asAuthorizeUpgrade: {85 readonly codeHash: H256;86 } & Struct;87 readonly isEnactAuthorizedUpgrade: boolean;88 readonly asEnactAuthorizedUpgrade: {89 readonly code: Bytes;90 } & Struct;91 readonly type: 'SetValidationData' | 'SudoSendUpwardMessage' | 'AuthorizeUpgrade' | 'EnactAuthorizedUpgrade';92}9394/** @name CumulusPalletParachainSystemError */95export interface CumulusPalletParachainSystemError extends Enum {96 readonly isOverlappingUpgrades: boolean;97 readonly isProhibitedByPolkadot: boolean;98 readonly isTooBig: boolean;99 readonly isValidationDataNotAvailable: boolean;100 readonly isHostConfigurationNotAvailable: boolean;101 readonly isNotScheduled: boolean;102 readonly isNothingAuthorized: boolean;103 readonly isUnauthorized: boolean;104 readonly type: 'OverlappingUpgrades' | 'ProhibitedByPolkadot' | 'TooBig' | 'ValidationDataNotAvailable' | 'HostConfigurationNotAvailable' | 'NotScheduled' | 'NothingAuthorized' | 'Unauthorized';105}106107/** @name CumulusPalletParachainSystemEvent */108export interface CumulusPalletParachainSystemEvent extends Enum {109 readonly isValidationFunctionStored: boolean;110 readonly isValidationFunctionApplied: boolean;111 readonly asValidationFunctionApplied: {112 readonly relayChainBlockNum: u32;113 } & Struct;114 readonly isValidationFunctionDiscarded: boolean;115 readonly isUpgradeAuthorized: boolean;116 readonly asUpgradeAuthorized: {117 readonly codeHash: H256;118 } & Struct;119 readonly isDownwardMessagesReceived: boolean;120 readonly asDownwardMessagesReceived: {121 readonly count: u32;122 } & Struct;123 readonly isDownwardMessagesProcessed: boolean;124 readonly asDownwardMessagesProcessed: {125 readonly weightUsed: u64;126 readonly dmqHead: H256;127 } & Struct;128 readonly type: 'ValidationFunctionStored' | 'ValidationFunctionApplied' | 'ValidationFunctionDiscarded' | 'UpgradeAuthorized' | 'DownwardMessagesReceived' | 'DownwardMessagesProcessed';129}130131/** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot */132export interface CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot extends Struct {133 readonly dmqMqcHead: H256;134 readonly relayDispatchQueueSize: ITuple<[u32, u32]>;135 readonly ingressChannels: Vec<ITuple<[u32, PolkadotPrimitivesV2AbridgedHrmpChannel]>>;136 readonly egressChannels: Vec<ITuple<[u32, PolkadotPrimitivesV2AbridgedHrmpChannel]>>;137}138139/** @name CumulusPalletXcmCall */140export interface CumulusPalletXcmCall extends Null {}141142/** @name CumulusPalletXcmError */143export interface CumulusPalletXcmError extends Null {}144145/** @name CumulusPalletXcmEvent */146export interface CumulusPalletXcmEvent extends Enum {147 readonly isInvalidFormat: boolean;148 readonly asInvalidFormat: U8aFixed;149 readonly isUnsupportedVersion: boolean;150 readonly asUnsupportedVersion: U8aFixed;151 readonly isExecutedDownward: boolean;152 readonly asExecutedDownward: ITuple<[U8aFixed, XcmV2TraitsOutcome]>;153 readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward';154}155156/** @name CumulusPalletXcmOrigin */157export interface CumulusPalletXcmOrigin extends Enum {158 readonly isRelay: boolean;159 readonly isSiblingParachain: boolean;160 readonly asSiblingParachain: u32;161 readonly type: 'Relay' | 'SiblingParachain';162}163164/** @name CumulusPalletXcmpQueueCall */165export interface CumulusPalletXcmpQueueCall extends Enum {166 readonly isServiceOverweight: boolean;167 readonly asServiceOverweight: {168 readonly index: u64;169 readonly weightLimit: u64;170 } & Struct;171 readonly isSuspendXcmExecution: boolean;172 readonly isResumeXcmExecution: boolean;173 readonly isUpdateSuspendThreshold: boolean;174 readonly asUpdateSuspendThreshold: {175 readonly new_: u32;176 } & Struct;177 readonly isUpdateDropThreshold: boolean;178 readonly asUpdateDropThreshold: {179 readonly new_: u32;180 } & Struct;181 readonly isUpdateResumeThreshold: boolean;182 readonly asUpdateResumeThreshold: {183 readonly new_: u32;184 } & Struct;185 readonly isUpdateThresholdWeight: boolean;186 readonly asUpdateThresholdWeight: {187 readonly new_: u64;188 } & Struct;189 readonly isUpdateWeightRestrictDecay: boolean;190 readonly asUpdateWeightRestrictDecay: {191 readonly new_: u64;192 } & Struct;193 readonly isUpdateXcmpMaxIndividualWeight: boolean;194 readonly asUpdateXcmpMaxIndividualWeight: {195 readonly new_: u64;196 } & Struct;197 readonly type: 'ServiceOverweight' | 'SuspendXcmExecution' | 'ResumeXcmExecution' | 'UpdateSuspendThreshold' | 'UpdateDropThreshold' | 'UpdateResumeThreshold' | 'UpdateThresholdWeight' | 'UpdateWeightRestrictDecay' | 'UpdateXcmpMaxIndividualWeight';198}199200/** @name CumulusPalletXcmpQueueError */201export interface CumulusPalletXcmpQueueError extends Enum {202 readonly isFailedToSend: boolean;203 readonly isBadXcmOrigin: boolean;204 readonly isBadXcm: boolean;205 readonly isBadOverweightIndex: boolean;206 readonly isWeightOverLimit: boolean;207 readonly type: 'FailedToSend' | 'BadXcmOrigin' | 'BadXcm' | 'BadOverweightIndex' | 'WeightOverLimit';208}209210/** @name CumulusPalletXcmpQueueEvent */211export interface CumulusPalletXcmpQueueEvent extends Enum {212 readonly isSuccess: boolean;213 readonly asSuccess: Option<H256>;214 readonly isFail: boolean;215 readonly asFail: ITuple<[Option<H256>, XcmV2TraitsError]>;216 readonly isBadVersion: boolean;217 readonly asBadVersion: Option<H256>;218 readonly isBadFormat: boolean;219 readonly asBadFormat: Option<H256>;220 readonly isUpwardMessageSent: boolean;221 readonly asUpwardMessageSent: Option<H256>;222 readonly isXcmpMessageSent: boolean;223 readonly asXcmpMessageSent: Option<H256>;224 readonly isOverweightEnqueued: boolean;225 readonly asOverweightEnqueued: ITuple<[u32, u32, u64, u64]>;226 readonly isOverweightServiced: boolean;227 readonly asOverweightServiced: ITuple<[u64, u64]>;228 readonly type: 'Success' | 'Fail' | 'BadVersion' | 'BadFormat' | 'UpwardMessageSent' | 'XcmpMessageSent' | 'OverweightEnqueued' | 'OverweightServiced';229}230231/** @name CumulusPalletXcmpQueueInboundChannelDetails */232export interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct {233 readonly sender: u32;234 readonly state: CumulusPalletXcmpQueueInboundState;235 readonly messageMetadata: Vec<ITuple<[u32, PolkadotParachainPrimitivesXcmpMessageFormat]>>;236}237238/** @name CumulusPalletXcmpQueueInboundState */239export interface CumulusPalletXcmpQueueInboundState extends Enum {240 readonly isOk: boolean;241 readonly isSuspended: boolean;242 readonly type: 'Ok' | 'Suspended';243}244245/** @name CumulusPalletXcmpQueueOutboundChannelDetails */246export interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct {247 readonly recipient: u32;248 readonly state: CumulusPalletXcmpQueueOutboundState;249 readonly signalsExist: bool;250 readonly firstIndex: u16;251 readonly lastIndex: u16;252}253254/** @name CumulusPalletXcmpQueueOutboundState */255export interface CumulusPalletXcmpQueueOutboundState extends Enum {256 readonly isOk: boolean;257 readonly isSuspended: boolean;258 readonly type: 'Ok' | 'Suspended';259}260261/** @name CumulusPalletXcmpQueueQueueConfigData */262export interface CumulusPalletXcmpQueueQueueConfigData extends Struct {263 readonly suspendThreshold: u32;264 readonly dropThreshold: u32;265 readonly resumeThreshold: u32;266 readonly thresholdWeight: u64;267 readonly weightRestrictDecay: u64;268 readonly xcmpMaxIndividualWeight: u64;269}270271/** @name CumulusPrimitivesParachainInherentParachainInherentData */272export interface CumulusPrimitivesParachainInherentParachainInherentData extends Struct {273 readonly validationData: PolkadotPrimitivesV2PersistedValidationData;274 readonly relayChainState: SpTrieStorageProof;275 readonly downwardMessages: Vec<PolkadotCorePrimitivesInboundDownwardMessage>;276 readonly horizontalMessages: BTreeMap<u32, Vec<PolkadotCorePrimitivesInboundHrmpMessage>>;277}278279/** @name EthbloomBloom */280export interface EthbloomBloom extends U8aFixed {}281282/** @name EthereumBlock */283export interface EthereumBlock extends Struct {284 readonly header: EthereumHeader;285 readonly transactions: Vec<EthereumTransactionTransactionV2>;286 readonly ommers: Vec<EthereumHeader>;287}288289/** @name EthereumHeader */290export interface EthereumHeader extends Struct {291 readonly parentHash: H256;292 readonly ommersHash: H256;293 readonly beneficiary: H160;294 readonly stateRoot: H256;295 readonly transactionsRoot: H256;296 readonly receiptsRoot: H256;297 readonly logsBloom: EthbloomBloom;298 readonly difficulty: U256;299 readonly number: U256;300 readonly gasLimit: U256;301 readonly gasUsed: U256;302 readonly timestamp: u64;303 readonly extraData: Bytes;304 readonly mixHash: H256;305 readonly nonce: EthereumTypesHashH64;306}307308/** @name EthereumLog */309export interface EthereumLog extends Struct {310 readonly address: H160;311 readonly topics: Vec<H256>;312 readonly data: Bytes;313}314315/** @name EthereumReceiptEip658ReceiptData */316export interface EthereumReceiptEip658ReceiptData extends Struct {317 readonly statusCode: u8;318 readonly usedGas: U256;319 readonly logsBloom: EthbloomBloom;320 readonly logs: Vec<EthereumLog>;321}322323/** @name EthereumReceiptReceiptV3 */324export interface EthereumReceiptReceiptV3 extends Enum {325 readonly isLegacy: boolean;326 readonly asLegacy: EthereumReceiptEip658ReceiptData;327 readonly isEip2930: boolean;328 readonly asEip2930: EthereumReceiptEip658ReceiptData;329 readonly isEip1559: boolean;330 readonly asEip1559: EthereumReceiptEip658ReceiptData;331 readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';332}333334/** @name EthereumTransactionAccessListItem */335export interface EthereumTransactionAccessListItem extends Struct {336 readonly address: H160;337 readonly storageKeys: Vec<H256>;338}339340/** @name EthereumTransactionEip1559Transaction */341export interface EthereumTransactionEip1559Transaction extends Struct {342 readonly chainId: u64;343 readonly nonce: U256;344 readonly maxPriorityFeePerGas: U256;345 readonly maxFeePerGas: U256;346 readonly gasLimit: U256;347 readonly action: EthereumTransactionTransactionAction;348 readonly value: U256;349 readonly input: Bytes;350 readonly accessList: Vec<EthereumTransactionAccessListItem>;351 readonly oddYParity: bool;352 readonly r: H256;353 readonly s: H256;354}355356/** @name EthereumTransactionEip2930Transaction */357export interface EthereumTransactionEip2930Transaction extends Struct {358 readonly chainId: u64;359 readonly nonce: U256;360 readonly gasPrice: U256;361 readonly gasLimit: U256;362 readonly action: EthereumTransactionTransactionAction;363 readonly value: U256;364 readonly input: Bytes;365 readonly accessList: Vec<EthereumTransactionAccessListItem>;366 readonly oddYParity: bool;367 readonly r: H256;368 readonly s: H256;369}370371/** @name EthereumTransactionLegacyTransaction */372export interface EthereumTransactionLegacyTransaction extends Struct {373 readonly nonce: U256;374 readonly gasPrice: U256;375 readonly gasLimit: U256;376 readonly action: EthereumTransactionTransactionAction;377 readonly value: U256;378 readonly input: Bytes;379 readonly signature: EthereumTransactionTransactionSignature;380}381382/** @name EthereumTransactionTransactionAction */383export interface EthereumTransactionTransactionAction extends Enum {384 readonly isCall: boolean;385 readonly asCall: H160;386 readonly isCreate: boolean;387 readonly type: 'Call' | 'Create';388}389390/** @name EthereumTransactionTransactionSignature */391export interface EthereumTransactionTransactionSignature extends Struct {392 readonly v: u64;393 readonly r: H256;394 readonly s: H256;395}396397/** @name EthereumTransactionTransactionV2 */398export interface EthereumTransactionTransactionV2 extends Enum {399 readonly isLegacy: boolean;400 readonly asLegacy: EthereumTransactionLegacyTransaction;401 readonly isEip2930: boolean;402 readonly asEip2930: EthereumTransactionEip2930Transaction;403 readonly isEip1559: boolean;404 readonly asEip1559: EthereumTransactionEip1559Transaction;405 readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';406}407408/** @name EthereumTypesHashH64 */409export interface EthereumTypesHashH64 extends U8aFixed {}410411/** @name EvmCoreErrorExitError */412export interface EvmCoreErrorExitError extends Enum {413 readonly isStackUnderflow: boolean;414 readonly isStackOverflow: boolean;415 readonly isInvalidJump: boolean;416 readonly isInvalidRange: boolean;417 readonly isDesignatedInvalid: boolean;418 readonly isCallTooDeep: boolean;419 readonly isCreateCollision: boolean;420 readonly isCreateContractLimit: boolean;421 readonly isOutOfOffset: boolean;422 readonly isOutOfGas: boolean;423 readonly isOutOfFund: boolean;424 readonly isPcUnderflow: boolean;425 readonly isCreateEmpty: boolean;426 readonly isOther: boolean;427 readonly asOther: Text;428 readonly isInvalidCode: boolean;429 readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other' | 'InvalidCode';430}431432/** @name EvmCoreErrorExitFatal */433export interface EvmCoreErrorExitFatal extends Enum {434 readonly isNotSupported: boolean;435 readonly isUnhandledInterrupt: boolean;436 readonly isCallErrorAsFatal: boolean;437 readonly asCallErrorAsFatal: EvmCoreErrorExitError;438 readonly isOther: boolean;439 readonly asOther: Text;440 readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';441}442443/** @name EvmCoreErrorExitReason */444export interface EvmCoreErrorExitReason extends Enum {445 readonly isSucceed: boolean;446 readonly asSucceed: EvmCoreErrorExitSucceed;447 readonly isError: boolean;448 readonly asError: EvmCoreErrorExitError;449 readonly isRevert: boolean;450 readonly asRevert: EvmCoreErrorExitRevert;451 readonly isFatal: boolean;452 readonly asFatal: EvmCoreErrorExitFatal;453 readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';454}455456/** @name EvmCoreErrorExitRevert */457export interface EvmCoreErrorExitRevert extends Enum {458 readonly isReverted: boolean;459 readonly type: 'Reverted';460}461462/** @name EvmCoreErrorExitSucceed */463export interface EvmCoreErrorExitSucceed extends Enum {464 readonly isStopped: boolean;465 readonly isReturned: boolean;466 readonly isSuicided: boolean;467 readonly type: 'Stopped' | 'Returned' | 'Suicided';468}469470/** @name FpRpcTransactionStatus */471export interface FpRpcTransactionStatus extends Struct {472 readonly transactionHash: H256;473 readonly transactionIndex: u32;474 readonly from: H160;475 readonly to: Option<H160>;476 readonly contractAddress: Option<H160>;477 readonly logs: Vec<EthereumLog>;478 readonly logsBloom: EthbloomBloom;479}480481/** @name FrameSupportDispatchRawOrigin */482export interface FrameSupportDispatchRawOrigin extends Enum {483 readonly isRoot: boolean;484 readonly isSigned: boolean;485 readonly asSigned: AccountId32;486 readonly isNone: boolean;487 readonly type: 'Root' | 'Signed' | 'None';488}489490/** @name FrameSupportPalletId */491export interface FrameSupportPalletId extends U8aFixed {}492493/** @name FrameSupportScheduleLookupError */494export interface FrameSupportScheduleLookupError extends Enum {495 readonly isUnknown: boolean;496 readonly isBadFormat: boolean;497 readonly type: 'Unknown' | 'BadFormat';498}499500/** @name FrameSupportScheduleMaybeHashed */501export interface FrameSupportScheduleMaybeHashed extends Enum {502 readonly isValue: boolean;503 readonly asValue: Call;504 readonly isHash: boolean;505 readonly asHash: H256;506 readonly type: 'Value' | 'Hash';507}508509/** @name FrameSupportTokensMiscBalanceStatus */510export interface FrameSupportTokensMiscBalanceStatus extends Enum {511 readonly isFree: boolean;512 readonly isReserved: boolean;513 readonly type: 'Free' | 'Reserved';514}515516/** @name FrameSupportWeightsDispatchClass */517export interface FrameSupportWeightsDispatchClass extends Enum {518 readonly isNormal: boolean;519 readonly isOperational: boolean;520 readonly isMandatory: boolean;521 readonly type: 'Normal' | 'Operational' | 'Mandatory';522}523524/** @name FrameSupportWeightsDispatchInfo */525export interface FrameSupportWeightsDispatchInfo extends Struct {526 readonly weight: u64;527 readonly class: FrameSupportWeightsDispatchClass;528 readonly paysFee: FrameSupportWeightsPays;529}530531/** @name FrameSupportWeightsPays */532export interface FrameSupportWeightsPays extends Enum {533 readonly isYes: boolean;534 readonly isNo: boolean;535 readonly type: 'Yes' | 'No';536}537538/** @name FrameSupportWeightsPerDispatchClassU32 */539export interface FrameSupportWeightsPerDispatchClassU32 extends Struct {540 readonly normal: u32;541 readonly operational: u32;542 readonly mandatory: u32;543}544545/** @name FrameSupportWeightsPerDispatchClassU64 */546export interface FrameSupportWeightsPerDispatchClassU64 extends Struct {547 readonly normal: u64;548 readonly operational: u64;549 readonly mandatory: u64;550}551552/** @name FrameSupportWeightsPerDispatchClassWeightsPerClass */553export interface FrameSupportWeightsPerDispatchClassWeightsPerClass extends Struct {554 readonly normal: FrameSystemLimitsWeightsPerClass;555 readonly operational: FrameSystemLimitsWeightsPerClass;556 readonly mandatory: FrameSystemLimitsWeightsPerClass;557}558559/** @name FrameSupportWeightsRuntimeDbWeight */560export interface FrameSupportWeightsRuntimeDbWeight extends Struct {561 readonly read: u64;562 readonly write: u64;563}564565/** @name FrameSystemAccountInfo */566export interface FrameSystemAccountInfo extends Struct {567 readonly nonce: u32;568 readonly consumers: u32;569 readonly providers: u32;570 readonly sufficients: u32;571 readonly data: PalletBalancesAccountData;572}573574/** @name FrameSystemCall */575export interface FrameSystemCall extends Enum {576 readonly isFillBlock: boolean;577 readonly asFillBlock: {578 readonly ratio: Perbill;579 } & Struct;580 readonly isRemark: boolean;581 readonly asRemark: {582 readonly remark: Bytes;583 } & Struct;584 readonly isSetHeapPages: boolean;585 readonly asSetHeapPages: {586 readonly pages: u64;587 } & Struct;588 readonly isSetCode: boolean;589 readonly asSetCode: {590 readonly code: Bytes;591 } & Struct;592 readonly isSetCodeWithoutChecks: boolean;593 readonly asSetCodeWithoutChecks: {594 readonly code: Bytes;595 } & Struct;596 readonly isSetStorage: boolean;597 readonly asSetStorage: {598 readonly items: Vec<ITuple<[Bytes, Bytes]>>;599 } & Struct;600 readonly isKillStorage: boolean;601 readonly asKillStorage: {602 readonly keys_: Vec<Bytes>;603 } & Struct;604 readonly isKillPrefix: boolean;605 readonly asKillPrefix: {606 readonly prefix: Bytes;607 readonly subkeys: u32;608 } & Struct;609 readonly isRemarkWithEvent: boolean;610 readonly asRemarkWithEvent: {611 readonly remark: Bytes;612 } & Struct;613 readonly type: 'FillBlock' | 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent';614}615616/** @name FrameSystemError */617export interface FrameSystemError extends Enum {618 readonly isInvalidSpecName: boolean;619 readonly isSpecVersionNeedsToIncrease: boolean;620 readonly isFailedToExtractRuntimeVersion: boolean;621 readonly isNonDefaultComposite: boolean;622 readonly isNonZeroRefCount: boolean;623 readonly isCallFiltered: boolean;624 readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';625}626627/** @name FrameSystemEvent */628export interface FrameSystemEvent extends Enum {629 readonly isExtrinsicSuccess: boolean;630 readonly asExtrinsicSuccess: {631 readonly dispatchInfo: FrameSupportWeightsDispatchInfo;632 } & Struct;633 readonly isExtrinsicFailed: boolean;634 readonly asExtrinsicFailed: {635 readonly dispatchError: SpRuntimeDispatchError;636 readonly dispatchInfo: FrameSupportWeightsDispatchInfo;637 } & Struct;638 readonly isCodeUpdated: boolean;639 readonly isNewAccount: boolean;640 readonly asNewAccount: {641 readonly account: AccountId32;642 } & Struct;643 readonly isKilledAccount: boolean;644 readonly asKilledAccount: {645 readonly account: AccountId32;646 } & Struct;647 readonly isRemarked: boolean;648 readonly asRemarked: {649 readonly sender: AccountId32;650 readonly hash_: H256;651 } & Struct;652 readonly type: 'ExtrinsicSuccess' | 'ExtrinsicFailed' | 'CodeUpdated' | 'NewAccount' | 'KilledAccount' | 'Remarked';653}654655/** @name FrameSystemEventRecord */656export interface FrameSystemEventRecord extends Struct {657 readonly phase: FrameSystemPhase;658 readonly event: Event;659 readonly topics: Vec<H256>;660}661662/** @name FrameSystemExtensionsCheckGenesis */663export interface FrameSystemExtensionsCheckGenesis extends Null {}664665/** @name FrameSystemExtensionsCheckNonce */666export interface FrameSystemExtensionsCheckNonce extends Compact<u32> {}667668/** @name FrameSystemExtensionsCheckSpecVersion */669export interface FrameSystemExtensionsCheckSpecVersion extends Null {}670671/** @name FrameSystemExtensionsCheckWeight */672export interface FrameSystemExtensionsCheckWeight extends Null {}673674/** @name FrameSystemLastRuntimeUpgradeInfo */675export interface FrameSystemLastRuntimeUpgradeInfo extends Struct {676 readonly specVersion: Compact<u32>;677 readonly specName: Text;678}679680/** @name FrameSystemLimitsBlockLength */681export interface FrameSystemLimitsBlockLength extends Struct {682 readonly max: FrameSupportWeightsPerDispatchClassU32;683}684685/** @name FrameSystemLimitsBlockWeights */686export interface FrameSystemLimitsBlockWeights extends Struct {687 readonly baseBlock: u64;688 readonly maxBlock: u64;689 readonly perClass: FrameSupportWeightsPerDispatchClassWeightsPerClass;690}691692/** @name FrameSystemLimitsWeightsPerClass */693export interface FrameSystemLimitsWeightsPerClass extends Struct {694 readonly baseExtrinsic: u64;695 readonly maxExtrinsic: Option<u64>;696 readonly maxTotal: Option<u64>;697 readonly reserved: Option<u64>;698}699700/** @name FrameSystemPhase */701export interface FrameSystemPhase extends Enum {702 readonly isApplyExtrinsic: boolean;703 readonly asApplyExtrinsic: u32;704 readonly isFinalization: boolean;705 readonly isInitialization: boolean;706 readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';707}708709/** @name OpalRuntimeOriginCaller */710export interface OpalRuntimeOriginCaller extends Enum {711 readonly isVoid: boolean;712 readonly asVoid: SpCoreVoid;713 readonly isSystem: boolean;714 readonly asSystem: FrameSupportDispatchRawOrigin;715 readonly isPolkadotXcm: boolean;716 readonly asPolkadotXcm: PalletXcmOrigin;717 readonly isCumulusXcm: boolean;718 readonly asCumulusXcm: CumulusPalletXcmOrigin;719 readonly isEthereum: boolean;720 readonly asEthereum: PalletEthereumRawOrigin;721 readonly type: 'Void' | 'System' | 'PolkadotXcm' | 'CumulusXcm' | 'Ethereum';722}723724/** @name OpalRuntimeRuntime */725export interface OpalRuntimeRuntime extends Null {}726727/** @name OrmlVestingModuleCall */728export interface OrmlVestingModuleCall extends Enum {729 readonly isClaim: boolean;730 readonly isVestedTransfer: boolean;731 readonly asVestedTransfer: {732 readonly dest: MultiAddress;733 readonly schedule: OrmlVestingVestingSchedule;734 } & Struct;735 readonly isUpdateVestingSchedules: boolean;736 readonly asUpdateVestingSchedules: {737 readonly who: MultiAddress;738 readonly vestingSchedules: Vec<OrmlVestingVestingSchedule>;739 } & Struct;740 readonly isClaimFor: boolean;741 readonly asClaimFor: {742 readonly dest: MultiAddress;743 } & Struct;744 readonly type: 'Claim' | 'VestedTransfer' | 'UpdateVestingSchedules' | 'ClaimFor';745}746747/** @name OrmlVestingModuleError */748export interface OrmlVestingModuleError extends Enum {749 readonly isZeroVestingPeriod: boolean;750 readonly isZeroVestingPeriodCount: boolean;751 readonly isInsufficientBalanceToLock: boolean;752 readonly isTooManyVestingSchedules: boolean;753 readonly isAmountLow: boolean;754 readonly isMaxVestingSchedulesExceeded: boolean;755 readonly type: 'ZeroVestingPeriod' | 'ZeroVestingPeriodCount' | 'InsufficientBalanceToLock' | 'TooManyVestingSchedules' | 'AmountLow' | 'MaxVestingSchedulesExceeded';756}757758/** @name OrmlVestingModuleEvent */759export interface OrmlVestingModuleEvent extends Enum {760 readonly isVestingScheduleAdded: boolean;761 readonly asVestingScheduleAdded: {762 readonly from: AccountId32;763 readonly to: AccountId32;764 readonly vestingSchedule: OrmlVestingVestingSchedule;765 } & Struct;766 readonly isClaimed: boolean;767 readonly asClaimed: {768 readonly who: AccountId32;769 readonly amount: u128;770 } & Struct;771 readonly isVestingSchedulesUpdated: boolean;772 readonly asVestingSchedulesUpdated: {773 readonly who: AccountId32;774 } & Struct;775 readonly type: 'VestingScheduleAdded' | 'Claimed' | 'VestingSchedulesUpdated';776}777778/** @name OrmlVestingVestingSchedule */779export interface OrmlVestingVestingSchedule extends Struct {780 readonly start: u32;781 readonly period: u32;782 readonly periodCount: u32;783 readonly perPeriod: Compact<u128>;784}785786/** @name PalletBalancesAccountData */787export interface PalletBalancesAccountData extends Struct {788 readonly free: u128;789 readonly reserved: u128;790 readonly miscFrozen: u128;791 readonly feeFrozen: u128;792}793794/** @name PalletBalancesBalanceLock */795export interface PalletBalancesBalanceLock extends Struct {796 readonly id: U8aFixed;797 readonly amount: u128;798 readonly reasons: PalletBalancesReasons;799}800801/** @name PalletBalancesCall */802export interface PalletBalancesCall extends Enum {803 readonly isTransfer: boolean;804 readonly asTransfer: {805 readonly dest: MultiAddress;806 readonly value: Compact<u128>;807 } & Struct;808 readonly isSetBalance: boolean;809 readonly asSetBalance: {810 readonly who: MultiAddress;811 readonly newFree: Compact<u128>;812 readonly newReserved: Compact<u128>;813 } & Struct;814 readonly isForceTransfer: boolean;815 readonly asForceTransfer: {816 readonly source: MultiAddress;817 readonly dest: MultiAddress;818 readonly value: Compact<u128>;819 } & Struct;820 readonly isTransferKeepAlive: boolean;821 readonly asTransferKeepAlive: {822 readonly dest: MultiAddress;823 readonly value: Compact<u128>;824 } & Struct;825 readonly isTransferAll: boolean;826 readonly asTransferAll: {827 readonly dest: MultiAddress;828 readonly keepAlive: bool;829 } & Struct;830 readonly isForceUnreserve: boolean;831 readonly asForceUnreserve: {832 readonly who: MultiAddress;833 readonly amount: u128;834 } & Struct;835 readonly type: 'Transfer' | 'SetBalance' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve';836}837838/** @name PalletBalancesError */839export interface PalletBalancesError extends Enum {840 readonly isVestingBalance: boolean;841 readonly isLiquidityRestrictions: boolean;842 readonly isInsufficientBalance: boolean;843 readonly isExistentialDeposit: boolean;844 readonly isKeepAlive: boolean;845 readonly isExistingVestingSchedule: boolean;846 readonly isDeadAccount: boolean;847 readonly isTooManyReserves: boolean;848 readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'KeepAlive' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves';849}850851/** @name PalletBalancesEvent */852export interface PalletBalancesEvent extends Enum {853 readonly isEndowed: boolean;854 readonly asEndowed: {855 readonly account: AccountId32;856 readonly freeBalance: u128;857 } & Struct;858 readonly isDustLost: boolean;859 readonly asDustLost: {860 readonly account: AccountId32;861 readonly amount: u128;862 } & Struct;863 readonly isTransfer: boolean;864 readonly asTransfer: {865 readonly from: AccountId32;866 readonly to: AccountId32;867 readonly amount: u128;868 } & Struct;869 readonly isBalanceSet: boolean;870 readonly asBalanceSet: {871 readonly who: AccountId32;872 readonly free: u128;873 readonly reserved: u128;874 } & Struct;875 readonly isReserved: boolean;876 readonly asReserved: {877 readonly who: AccountId32;878 readonly amount: u128;879 } & Struct;880 readonly isUnreserved: boolean;881 readonly asUnreserved: {882 readonly who: AccountId32;883 readonly amount: u128;884 } & Struct;885 readonly isReserveRepatriated: boolean;886 readonly asReserveRepatriated: {887 readonly from: AccountId32;888 readonly to: AccountId32;889 readonly amount: u128;890 readonly destinationStatus: FrameSupportTokensMiscBalanceStatus;891 } & Struct;892 readonly isDeposit: boolean;893 readonly asDeposit: {894 readonly who: AccountId32;895 readonly amount: u128;896 } & Struct;897 readonly isWithdraw: boolean;898 readonly asWithdraw: {899 readonly who: AccountId32;900 readonly amount: u128;901 } & Struct;902 readonly isSlashed: boolean;903 readonly asSlashed: {904 readonly who: AccountId32;905 readonly amount: u128;906 } & Struct;907 readonly type: 'Endowed' | 'DustLost' | 'Transfer' | 'BalanceSet' | 'Reserved' | 'Unreserved' | 'ReserveRepatriated' | 'Deposit' | 'Withdraw' | 'Slashed';908}909910/** @name PalletBalancesReasons */911export interface PalletBalancesReasons extends Enum {912 readonly isFee: boolean;913 readonly isMisc: boolean;914 readonly isAll: boolean;915 readonly type: 'Fee' | 'Misc' | 'All';916}917918/** @name PalletBalancesReleases */919export interface PalletBalancesReleases extends Enum {920 readonly isV100: boolean;921 readonly isV200: boolean;922 readonly type: 'V100' | 'V200';923}924925/** @name PalletBalancesReserveData */926export interface PalletBalancesReserveData extends Struct {927 readonly id: U8aFixed;928 readonly amount: u128;929}930931/** @name PalletCommonError */932export interface PalletCommonError extends Enum {933 readonly isCollectionNotFound: boolean;934 readonly isMustBeTokenOwner: boolean;935 readonly isNoPermission: boolean;936 readonly isCantDestroyNotEmptyCollection: boolean;937 readonly isPublicMintingNotAllowed: boolean;938 readonly isAddressNotInAllowlist: boolean;939 readonly isCollectionNameLimitExceeded: boolean;940 readonly isCollectionDescriptionLimitExceeded: boolean;941 readonly isCollectionTokenPrefixLimitExceeded: boolean;942 readonly isTotalCollectionsLimitExceeded: boolean;943 readonly isCollectionAdminCountExceeded: boolean;944 readonly isCollectionLimitBoundsExceeded: boolean;945 readonly isOwnerPermissionsCantBeReverted: boolean;946 readonly isTransferNotAllowed: boolean;947 readonly isAccountTokenLimitExceeded: boolean;948 readonly isCollectionTokenLimitExceeded: boolean;949 readonly isMetadataFlagFrozen: boolean;950 readonly isTokenNotFound: boolean;951 readonly isTokenValueTooLow: boolean;952 readonly isApprovedValueTooLow: boolean;953 readonly isCantApproveMoreThanOwned: boolean;954 readonly isAddressIsZero: boolean;955 readonly isUnsupportedOperation: boolean;956 readonly isNotSufficientFounds: boolean;957 readonly isUserIsNotAllowedToNest: boolean;958 readonly isSourceCollectionIsNotAllowedToNest: boolean;959 readonly isCollectionFieldSizeExceeded: boolean;960 readonly isNoSpaceForProperty: boolean;961 readonly isPropertyLimitReached: boolean;962 readonly isPropertyKeyIsTooLong: boolean;963 readonly isInvalidCharacterInPropertyKey: boolean;964 readonly isEmptyPropertyKey: boolean;965 readonly isCollectionIsExternal: boolean;966 readonly isCollectionIsInternal: boolean;967 readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'CantDestroyNotEmptyCollection' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'UserIsNotAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey' | 'CollectionIsExternal' | 'CollectionIsInternal';968}969970/** @name PalletCommonEvent */971export interface PalletCommonEvent extends Enum {972 readonly isCollectionCreated: boolean;973 readonly asCollectionCreated: ITuple<[u32, u8, AccountId32]>;974 readonly isCollectionDestroyed: boolean;975 readonly asCollectionDestroyed: u32;976 readonly isItemCreated: boolean;977 readonly asItemCreated: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;978 readonly isItemDestroyed: boolean;979 readonly asItemDestroyed: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;980 readonly isTransfer: boolean;981 readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;982 readonly isApproved: boolean;983 readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;984 readonly isCollectionPropertySet: boolean;985 readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;986 readonly isCollectionPropertyDeleted: boolean;987 readonly asCollectionPropertyDeleted: ITuple<[u32, Bytes]>;988 readonly isTokenPropertySet: boolean;989 readonly asTokenPropertySet: ITuple<[u32, u32, Bytes]>;990 readonly isTokenPropertyDeleted: boolean;991 readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;992 readonly isPropertyPermissionSet: boolean;993 readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;994 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';995}996997/** @name PalletEthereumCall */998export interface PalletEthereumCall extends Enum {999 readonly isTransact: boolean;1000 readonly asTransact: {1001 readonly transaction: EthereumTransactionTransactionV2;1002 } & Struct;1003 readonly type: 'Transact';1004}10051006/** @name PalletEthereumError */1007export interface PalletEthereumError extends Enum {1008 readonly isInvalidSignature: boolean;1009 readonly isPreLogExists: boolean;1010 readonly type: 'InvalidSignature' | 'PreLogExists';1011}10121013/** @name PalletEthereumEvent */1014export interface PalletEthereumEvent extends Enum {1015 readonly isExecuted: boolean;1016 readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;1017 readonly type: 'Executed';1018}10191020/** @name PalletEthereumFakeTransactionFinalizer */1021export interface PalletEthereumFakeTransactionFinalizer extends Null {}10221023/** @name PalletEthereumRawOrigin */1024export interface PalletEthereumRawOrigin extends Enum {1025 readonly isEthereumTransaction: boolean;1026 readonly asEthereumTransaction: H160;1027 readonly type: 'EthereumTransaction';1028}10291030/** @name PalletEvmAccountBasicCrossAccountIdRepr */1031export interface PalletEvmAccountBasicCrossAccountIdRepr extends Enum {1032 readonly isSubstrate: boolean;1033 readonly asSubstrate: AccountId32;1034 readonly isEthereum: boolean;1035 readonly asEthereum: H160;1036 readonly type: 'Substrate' | 'Ethereum';1037}10381039/** @name PalletEvmCall */1040export interface PalletEvmCall extends Enum {1041 readonly isWithdraw: boolean;1042 readonly asWithdraw: {1043 readonly address: H160;1044 readonly value: u128;1045 } & Struct;1046 readonly isCall: boolean;1047 readonly asCall: {1048 readonly source: H160;1049 readonly target: H160;1050 readonly input: Bytes;1051 readonly value: U256;1052 readonly gasLimit: u64;1053 readonly maxFeePerGas: U256;1054 readonly maxPriorityFeePerGas: Option<U256>;1055 readonly nonce: Option<U256>;1056 readonly accessList: Vec<ITuple<[H160, Vec<H256>]>>;1057 } & Struct;1058 readonly isCreate: boolean;1059 readonly asCreate: {1060 readonly source: H160;1061 readonly init: Bytes;1062 readonly value: U256;1063 readonly gasLimit: u64;1064 readonly maxFeePerGas: U256;1065 readonly maxPriorityFeePerGas: Option<U256>;1066 readonly nonce: Option<U256>;1067 readonly accessList: Vec<ITuple<[H160, Vec<H256>]>>;1068 } & Struct;1069 readonly isCreate2: boolean;1070 readonly asCreate2: {1071 readonly source: H160;1072 readonly init: Bytes;1073 readonly salt: H256;1074 readonly value: U256;1075 readonly gasLimit: u64;1076 readonly maxFeePerGas: U256;1077 readonly maxPriorityFeePerGas: Option<U256>;1078 readonly nonce: Option<U256>;1079 readonly accessList: Vec<ITuple<[H160, Vec<H256>]>>;1080 } & Struct;1081 readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2';1082}10831084/** @name PalletEvmCoderSubstrateError */1085export interface PalletEvmCoderSubstrateError extends Enum {1086 readonly isOutOfGas: boolean;1087 readonly isOutOfFund: boolean;1088 readonly type: 'OutOfGas' | 'OutOfFund';1089}10901091/** @name PalletEvmContractHelpersError */1092export interface PalletEvmContractHelpersError extends Enum {1093 readonly isNoPermission: boolean;1094 readonly type: 'NoPermission';1095}10961097/** @name PalletEvmContractHelpersSponsoringModeT */1098export interface PalletEvmContractHelpersSponsoringModeT extends Enum {1099 readonly isDisabled: boolean;1100 readonly isAllowlisted: boolean;1101 readonly isGenerous: boolean;1102 readonly type: 'Disabled' | 'Allowlisted' | 'Generous';1103}11041105/** @name PalletEvmError */1106export interface PalletEvmError extends Enum {1107 readonly isBalanceLow: boolean;1108 readonly isFeeOverflow: boolean;1109 readonly isPaymentOverflow: boolean;1110 readonly isWithdrawFailed: boolean;1111 readonly isGasPriceTooLow: boolean;1112 readonly isInvalidNonce: boolean;1113 readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';1114}11151116/** @name PalletEvmEvent */1117export interface PalletEvmEvent extends Enum {1118 readonly isLog: boolean;1119 readonly asLog: EthereumLog;1120 readonly isCreated: boolean;1121 readonly asCreated: H160;1122 readonly isCreatedFailed: boolean;1123 readonly asCreatedFailed: H160;1124 readonly isExecuted: boolean;1125 readonly asExecuted: H160;1126 readonly isExecutedFailed: boolean;1127 readonly asExecutedFailed: H160;1128 readonly isBalanceDeposit: boolean;1129 readonly asBalanceDeposit: ITuple<[AccountId32, H160, U256]>;1130 readonly isBalanceWithdraw: boolean;1131 readonly asBalanceWithdraw: ITuple<[AccountId32, H160, U256]>;1132 readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';1133}11341135/** @name PalletEvmMigrationCall */1136export interface PalletEvmMigrationCall extends Enum {1137 readonly isBegin: boolean;1138 readonly asBegin: {1139 readonly address: H160;1140 } & Struct;1141 readonly isSetData: boolean;1142 readonly asSetData: {1143 readonly address: H160;1144 readonly data: Vec<ITuple<[H256, H256]>>;1145 } & Struct;1146 readonly isFinish: boolean;1147 readonly asFinish: {1148 readonly address: H160;1149 readonly code: Bytes;1150 } & Struct;1151 readonly type: 'Begin' | 'SetData' | 'Finish';1152}11531154/** @name PalletEvmMigrationError */1155export interface PalletEvmMigrationError extends Enum {1156 readonly isAccountNotEmpty: boolean;1157 readonly isAccountIsNotMigrating: boolean;1158 readonly type: 'AccountNotEmpty' | 'AccountIsNotMigrating';1159}11601161/** @name PalletFungibleError */1162export interface PalletFungibleError extends Enum {1163 readonly isNotFungibleDataUsedToMintFungibleCollectionToken: boolean;1164 readonly isFungibleItemsHaveNoId: boolean;1165 readonly isFungibleItemsDontHaveData: boolean;1166 readonly isFungibleDisallowsNesting: boolean;1167 readonly isSettingPropertiesNotAllowed: boolean;1168 readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';1169}11701171/** @name PalletInflationCall */1172export interface PalletInflationCall extends Enum {1173 readonly isStartInflation: boolean;1174 readonly asStartInflation: {1175 readonly inflationStartRelayBlock: u32;1176 } & Struct;1177 readonly type: 'StartInflation';1178}11791180/** @name PalletNonfungibleError */1181export interface PalletNonfungibleError extends Enum {1182 readonly isNotNonfungibleDataUsedToMintFungibleCollectionToken: boolean;1183 readonly isNonfungibleItemsHaveNoAmount: boolean;1184 readonly isCantBurnNftWithChildren: boolean;1185 readonly type: 'NotNonfungibleDataUsedToMintFungibleCollectionToken' | 'NonfungibleItemsHaveNoAmount' | 'CantBurnNftWithChildren';1186}11871188/** @name PalletNonfungibleItemData */1189export interface PalletNonfungibleItemData extends Struct {1190 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;1191}11921193/** @name PalletRefungibleError */1194export interface PalletRefungibleError extends Enum {1195 readonly isNotRefungibleDataUsedToMintFungibleCollectionToken: boolean;1196 readonly isWrongRefungiblePieces: boolean;1197 readonly isRepartitionWhileNotOwningAllPieces: boolean;1198 readonly isRefungibleDisallowsNesting: boolean;1199 readonly isSettingPropertiesNotAllowed: boolean;1200 readonly type: 'NotRefungibleDataUsedToMintFungibleCollectionToken' | 'WrongRefungiblePieces' | 'RepartitionWhileNotOwningAllPieces' | 'RefungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';1201}12021203/** @name PalletRefungibleItemData */1204export interface PalletRefungibleItemData extends Struct {1205 readonly constData: Bytes;1206}12071208/** @name PalletRmrkCoreCall */1209export interface PalletRmrkCoreCall extends Enum {1210 readonly isCreateCollection: boolean;1211 readonly asCreateCollection: {1212 readonly metadata: Bytes;1213 readonly max: Option<u32>;1214 readonly symbol: Bytes;1215 } & Struct;1216 readonly isDestroyCollection: boolean;1217 readonly asDestroyCollection: {1218 readonly collectionId: u32;1219 } & Struct;1220 readonly isChangeCollectionIssuer: boolean;1221 readonly asChangeCollectionIssuer: {1222 readonly collectionId: u32;1223 readonly newIssuer: MultiAddress;1224 } & Struct;1225 readonly isLockCollection: boolean;1226 readonly asLockCollection: {1227 readonly collectionId: u32;1228 } & Struct;1229 readonly isMintNft: boolean;1230 readonly asMintNft: {1231 readonly owner: Option<AccountId32>;1232 readonly collectionId: u32;1233 readonly recipient: Option<AccountId32>;1234 readonly royaltyAmount: Option<Permill>;1235 readonly metadata: Bytes;1236 readonly transferable: bool;1237 readonly resources: Option<Vec<RmrkTraitsResourceResourceTypes>>;1238 } & Struct;1239 readonly isBurnNft: boolean;1240 readonly asBurnNft: {1241 readonly collectionId: u32;1242 readonly nftId: u32;1243 readonly maxBurns: u32;1244 } & Struct;1245 readonly isSend: boolean;1246 readonly asSend: {1247 readonly rmrkCollectionId: u32;1248 readonly rmrkNftId: u32;1249 readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;1250 } & Struct;1251 readonly isAcceptNft: boolean;1252 readonly asAcceptNft: {1253 readonly rmrkCollectionId: u32;1254 readonly rmrkNftId: u32;1255 readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;1256 } & Struct;1257 readonly isRejectNft: boolean;1258 readonly asRejectNft: {1259 readonly rmrkCollectionId: u32;1260 readonly rmrkNftId: u32;1261 } & Struct;1262 readonly isAcceptResource: boolean;1263 readonly asAcceptResource: {1264 readonly rmrkCollectionId: u32;1265 readonly rmrkNftId: u32;1266 readonly resourceId: u32;1267 } & Struct;1268 readonly isAcceptResourceRemoval: boolean;1269 readonly asAcceptResourceRemoval: {1270 readonly rmrkCollectionId: u32;1271 readonly rmrkNftId: u32;1272 readonly resourceId: u32;1273 } & Struct;1274 readonly isSetProperty: boolean;1275 readonly asSetProperty: {1276 readonly rmrkCollectionId: Compact<u32>;1277 readonly maybeNftId: Option<u32>;1278 readonly key: Bytes;1279 readonly value: Bytes;1280 } & Struct;1281 readonly isSetPriority: boolean;1282 readonly asSetPriority: {1283 readonly rmrkCollectionId: u32;1284 readonly rmrkNftId: u32;1285 readonly priorities: Vec<u32>;1286 } & Struct;1287 readonly isAddBasicResource: boolean;1288 readonly asAddBasicResource: {1289 readonly rmrkCollectionId: u32;1290 readonly nftId: u32;1291 readonly resource: RmrkTraitsResourceBasicResource;1292 } & Struct;1293 readonly isAddComposableResource: boolean;1294 readonly asAddComposableResource: {1295 readonly rmrkCollectionId: u32;1296 readonly nftId: u32;1297 readonly resource: RmrkTraitsResourceComposableResource;1298 } & Struct;1299 readonly isAddSlotResource: boolean;1300 readonly asAddSlotResource: {1301 readonly rmrkCollectionId: u32;1302 readonly nftId: u32;1303 readonly resource: RmrkTraitsResourceSlotResource;1304 } & Struct;1305 readonly isRemoveResource: boolean;1306 readonly asRemoveResource: {1307 readonly rmrkCollectionId: u32;1308 readonly nftId: u32;1309 readonly resourceId: u32;1310 } & Struct;1311 readonly type: 'CreateCollection' | 'DestroyCollection' | 'ChangeCollectionIssuer' | 'LockCollection' | 'MintNft' | 'BurnNft' | 'Send' | 'AcceptNft' | 'RejectNft' | 'AcceptResource' | 'AcceptResourceRemoval' | 'SetProperty' | 'SetPriority' | 'AddBasicResource' | 'AddComposableResource' | 'AddSlotResource' | 'RemoveResource';1312}13131314/** @name PalletRmrkCoreError */1315export interface PalletRmrkCoreError extends Enum {1316 readonly isCorruptedCollectionType: boolean;1317 readonly isRmrkPropertyKeyIsTooLong: boolean;1318 readonly isRmrkPropertyValueIsTooLong: boolean;1319 readonly isRmrkPropertyIsNotFound: boolean;1320 readonly isUnableToDecodeRmrkData: boolean;1321 readonly isCollectionNotEmpty: boolean;1322 readonly isNoAvailableCollectionId: boolean;1323 readonly isNoAvailableNftId: boolean;1324 readonly isCollectionUnknown: boolean;1325 readonly isNoPermission: boolean;1326 readonly isNonTransferable: boolean;1327 readonly isCollectionFullOrLocked: boolean;1328 readonly isResourceDoesntExist: boolean;1329 readonly isCannotSendToDescendentOrSelf: boolean;1330 readonly isCannotAcceptNonOwnedNft: boolean;1331 readonly isCannotRejectNonOwnedNft: boolean;1332 readonly isCannotRejectNonPendingNft: boolean;1333 readonly isResourceNotPending: boolean;1334 readonly isNoAvailableResourceId: boolean;1335 readonly type: 'CorruptedCollectionType' | 'RmrkPropertyKeyIsTooLong' | 'RmrkPropertyValueIsTooLong' | 'RmrkPropertyIsNotFound' | 'UnableToDecodeRmrkData' | 'CollectionNotEmpty' | 'NoAvailableCollectionId' | 'NoAvailableNftId' | 'CollectionUnknown' | 'NoPermission' | 'NonTransferable' | 'CollectionFullOrLocked' | 'ResourceDoesntExist' | 'CannotSendToDescendentOrSelf' | 'CannotAcceptNonOwnedNft' | 'CannotRejectNonOwnedNft' | 'CannotRejectNonPendingNft' | 'ResourceNotPending' | 'NoAvailableResourceId';1336}13371338/** @name PalletRmrkCoreEvent */1339export interface PalletRmrkCoreEvent extends Enum {1340 readonly isCollectionCreated: boolean;1341 readonly asCollectionCreated: {1342 readonly issuer: AccountId32;1343 readonly collectionId: u32;1344 } & Struct;1345 readonly isCollectionDestroyed: boolean;1346 readonly asCollectionDestroyed: {1347 readonly issuer: AccountId32;1348 readonly collectionId: u32;1349 } & Struct;1350 readonly isIssuerChanged: boolean;1351 readonly asIssuerChanged: {1352 readonly oldIssuer: AccountId32;1353 readonly newIssuer: AccountId32;1354 readonly collectionId: u32;1355 } & Struct;1356 readonly isCollectionLocked: boolean;1357 readonly asCollectionLocked: {1358 readonly issuer: AccountId32;1359 readonly collectionId: u32;1360 } & Struct;1361 readonly isNftMinted: boolean;1362 readonly asNftMinted: {1363 readonly owner: AccountId32;1364 readonly collectionId: u32;1365 readonly nftId: u32;1366 } & Struct;1367 readonly isNftBurned: boolean;1368 readonly asNftBurned: {1369 readonly owner: AccountId32;1370 readonly nftId: u32;1371 } & Struct;1372 readonly isNftSent: boolean;1373 readonly asNftSent: {1374 readonly sender: AccountId32;1375 readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;1376 readonly collectionId: u32;1377 readonly nftId: u32;1378 readonly approvalRequired: bool;1379 } & Struct;1380 readonly isNftAccepted: boolean;1381 readonly asNftAccepted: {1382 readonly sender: AccountId32;1383 readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;1384 readonly collectionId: u32;1385 readonly nftId: u32;1386 } & Struct;1387 readonly isNftRejected: boolean;1388 readonly asNftRejected: {1389 readonly sender: AccountId32;1390 readonly collectionId: u32;1391 readonly nftId: u32;1392 } & Struct;1393 readonly isPropertySet: boolean;1394 readonly asPropertySet: {1395 readonly collectionId: u32;1396 readonly maybeNftId: Option<u32>;1397 readonly key: Bytes;1398 readonly value: Bytes;1399 } & Struct;1400 readonly isResourceAdded: boolean;1401 readonly asResourceAdded: {1402 readonly nftId: u32;1403 readonly resourceId: u32;1404 } & Struct;1405 readonly isResourceRemoval: boolean;1406 readonly asResourceRemoval: {1407 readonly nftId: u32;1408 readonly resourceId: u32;1409 } & Struct;1410 readonly isResourceAccepted: boolean;1411 readonly asResourceAccepted: {1412 readonly nftId: u32;1413 readonly resourceId: u32;1414 } & Struct;1415 readonly isResourceRemovalAccepted: boolean;1416 readonly asResourceRemovalAccepted: {1417 readonly nftId: u32;1418 readonly resourceId: u32;1419 } & Struct;1420 readonly isPrioritySet: boolean;1421 readonly asPrioritySet: {1422 readonly collectionId: u32;1423 readonly nftId: u32;1424 } & Struct;1425 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';1426}14271428/** @name PalletRmrkEquipCall */1429export interface PalletRmrkEquipCall extends Enum {1430 readonly isCreateBase: boolean;1431 readonly asCreateBase: {1432 readonly baseType: Bytes;1433 readonly symbol: Bytes;1434 readonly parts: Vec<RmrkTraitsPartPartType>;1435 } & Struct;1436 readonly isThemeAdd: boolean;1437 readonly asThemeAdd: {1438 readonly baseId: u32;1439 readonly theme: RmrkTraitsTheme;1440 } & Struct;1441 readonly isEquippable: boolean;1442 readonly asEquippable: {1443 readonly baseId: u32;1444 readonly slotId: u32;1445 readonly equippables: RmrkTraitsPartEquippableList;1446 } & Struct;1447 readonly type: 'CreateBase' | 'ThemeAdd' | 'Equippable';1448}14491450/** @name PalletRmrkEquipError */1451export interface PalletRmrkEquipError extends Enum {1452 readonly isPermissionError: boolean;1453 readonly isNoAvailableBaseId: boolean;1454 readonly isNoAvailablePartId: boolean;1455 readonly isBaseDoesntExist: boolean;1456 readonly isNeedsDefaultThemeFirst: boolean;1457 readonly isPartDoesntExist: boolean;1458 readonly isNoEquippableOnFixedPart: boolean;1459 readonly type: 'PermissionError' | 'NoAvailableBaseId' | 'NoAvailablePartId' | 'BaseDoesntExist' | 'NeedsDefaultThemeFirst' | 'PartDoesntExist' | 'NoEquippableOnFixedPart';1460}14611462/** @name PalletRmrkEquipEvent */1463export interface PalletRmrkEquipEvent extends Enum {1464 readonly isBaseCreated: boolean;1465 readonly asBaseCreated: {1466 readonly issuer: AccountId32;1467 readonly baseId: u32;1468 } & Struct;1469 readonly isEquippablesUpdated: boolean;1470 readonly asEquippablesUpdated: {1471 readonly baseId: u32;1472 readonly slotId: u32;1473 } & Struct;1474 readonly type: 'BaseCreated' | 'EquippablesUpdated';1475}14761477/** @name PalletStructureCall */1478export interface PalletStructureCall extends Null {}14791480/** @name PalletStructureError */1481export interface PalletStructureError extends Enum {1482 readonly isOuroborosDetected: boolean;1483 readonly isDepthLimit: boolean;1484 readonly isBreadthLimit: boolean;1485 readonly isTokenNotFound: boolean;1486 readonly type: 'OuroborosDetected' | 'DepthLimit' | 'BreadthLimit' | 'TokenNotFound';1487}14881489/** @name PalletStructureEvent */1490export interface PalletStructureEvent extends Enum {1491 readonly isExecuted: boolean;1492 readonly asExecuted: Result<Null, SpRuntimeDispatchError>;1493 readonly type: 'Executed';1494}14951496/** @name PalletSudoCall */1497export interface PalletSudoCall extends Enum {1498 readonly isSudo: boolean;1499 readonly asSudo: {1500 readonly call: Call;1501 } & Struct;1502 readonly isSudoUncheckedWeight: boolean;1503 readonly asSudoUncheckedWeight: {1504 readonly call: Call;1505 readonly weight: u64;1506 } & Struct;1507 readonly isSetKey: boolean;1508 readonly asSetKey: {1509 readonly new_: MultiAddress;1510 } & Struct;1511 readonly isSudoAs: boolean;1512 readonly asSudoAs: {1513 readonly who: MultiAddress;1514 readonly call: Call;1515 } & Struct;1516 readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs';1517}15181519/** @name PalletSudoError */1520export interface PalletSudoError extends Enum {1521 readonly isRequireSudo: boolean;1522 readonly type: 'RequireSudo';1523}15241525/** @name PalletSudoEvent */1526export interface PalletSudoEvent extends Enum {1527 readonly isSudid: boolean;1528 readonly asSudid: {1529 readonly sudoResult: Result<Null, SpRuntimeDispatchError>;1530 } & Struct;1531 readonly isKeyChanged: boolean;1532 readonly asKeyChanged: {1533 readonly oldSudoer: Option<AccountId32>;1534 } & Struct;1535 readonly isSudoAsDone: boolean;1536 readonly asSudoAsDone: {1537 readonly sudoResult: Result<Null, SpRuntimeDispatchError>;1538 } & Struct;1539 readonly type: 'Sudid' | 'KeyChanged' | 'SudoAsDone';1540}15411542/** @name PalletTemplateTransactionPaymentCall */1543export interface PalletTemplateTransactionPaymentCall extends Null {}15441545/** @name PalletTemplateTransactionPaymentChargeTransactionPayment */1546export interface PalletTemplateTransactionPaymentChargeTransactionPayment extends Compact<u128> {}15471548/** @name PalletTimestampCall */1549export interface PalletTimestampCall extends Enum {1550 readonly isSet: boolean;1551 readonly asSet: {1552 readonly now: Compact<u64>;1553 } & Struct;1554 readonly type: 'Set';1555}15561557/** @name PalletTransactionPaymentReleases */1558export interface PalletTransactionPaymentReleases extends Enum {1559 readonly isV1Ancient: boolean;1560 readonly isV2: boolean;1561 readonly type: 'V1Ancient' | 'V2';1562}15631564/** @name PalletTreasuryCall */1565export interface PalletTreasuryCall extends Enum {1566 readonly isProposeSpend: boolean;1567 readonly asProposeSpend: {1568 readonly value: Compact<u128>;1569 readonly beneficiary: MultiAddress;1570 } & Struct;1571 readonly isRejectProposal: boolean;1572 readonly asRejectProposal: {1573 readonly proposalId: Compact<u32>;1574 } & Struct;1575 readonly isApproveProposal: boolean;1576 readonly asApproveProposal: {1577 readonly proposalId: Compact<u32>;1578 } & Struct;1579 readonly isRemoveApproval: boolean;1580 readonly asRemoveApproval: {1581 readonly proposalId: Compact<u32>;1582 } & Struct;1583 readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal' | 'RemoveApproval';1584}15851586/** @name PalletTreasuryError */1587export interface PalletTreasuryError extends Enum {1588 readonly isInsufficientProposersBalance: boolean;1589 readonly isInvalidIndex: boolean;1590 readonly isTooManyApprovals: boolean;1591 readonly isProposalNotApproved: boolean;1592 readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals' | 'ProposalNotApproved';1593}15941595/** @name PalletTreasuryEvent */1596export interface PalletTreasuryEvent extends Enum {1597 readonly isProposed: boolean;1598 readonly asProposed: {1599 readonly proposalIndex: u32;1600 } & Struct;1601 readonly isSpending: boolean;1602 readonly asSpending: {1603 readonly budgetRemaining: u128;1604 } & Struct;1605 readonly isAwarded: boolean;1606 readonly asAwarded: {1607 readonly proposalIndex: u32;1608 readonly award: u128;1609 readonly account: AccountId32;1610 } & Struct;1611 readonly isRejected: boolean;1612 readonly asRejected: {1613 readonly proposalIndex: u32;1614 readonly slashed: u128;1615 } & Struct;1616 readonly isBurnt: boolean;1617 readonly asBurnt: {1618 readonly burntFunds: u128;1619 } & Struct;1620 readonly isRollover: boolean;1621 readonly asRollover: {1622 readonly rolloverBalance: u128;1623 } & Struct;1624 readonly isDeposit: boolean;1625 readonly asDeposit: {1626 readonly value: u128;1627 } & Struct;1628 readonly type: 'Proposed' | 'Spending' | 'Awarded' | 'Rejected' | 'Burnt' | 'Rollover' | 'Deposit';1629}16301631/** @name PalletTreasuryProposal */1632export interface PalletTreasuryProposal extends Struct {1633 readonly proposer: AccountId32;1634 readonly value: u128;1635 readonly beneficiary: AccountId32;1636 readonly bond: u128;1637}16381639/** @name PalletUniqueCall */1640export interface PalletUniqueCall extends Enum {1641 readonly isCreateCollection: boolean;1642 readonly asCreateCollection: {1643 readonly collectionName: Vec<u16>;1644 readonly collectionDescription: Vec<u16>;1645 readonly tokenPrefix: Bytes;1646 readonly mode: UpDataStructsCollectionMode;1647 } & Struct;1648 readonly isCreateCollectionEx: boolean;1649 readonly asCreateCollectionEx: {1650 readonly data: UpDataStructsCreateCollectionData;1651 } & Struct;1652 readonly isDestroyCollection: boolean;1653 readonly asDestroyCollection: {1654 readonly collectionId: u32;1655 } & Struct;1656 readonly isAddToAllowList: boolean;1657 readonly asAddToAllowList: {1658 readonly collectionId: u32;1659 readonly address: PalletEvmAccountBasicCrossAccountIdRepr;1660 } & Struct;1661 readonly isRemoveFromAllowList: boolean;1662 readonly asRemoveFromAllowList: {1663 readonly collectionId: u32;1664 readonly address: PalletEvmAccountBasicCrossAccountIdRepr;1665 } & Struct;1666 readonly isChangeCollectionOwner: boolean;1667 readonly asChangeCollectionOwner: {1668 readonly collectionId: u32;1669 readonly newOwner: AccountId32;1670 } & Struct;1671 readonly isAddCollectionAdmin: boolean;1672 readonly asAddCollectionAdmin: {1673 readonly collectionId: u32;1674 readonly newAdmin: PalletEvmAccountBasicCrossAccountIdRepr;1675 } & Struct;1676 readonly isRemoveCollectionAdmin: boolean;1677 readonly asRemoveCollectionAdmin: {1678 readonly collectionId: u32;1679 readonly accountId: PalletEvmAccountBasicCrossAccountIdRepr;1680 } & Struct;1681 readonly isSetCollectionSponsor: boolean;1682 readonly asSetCollectionSponsor: {1683 readonly collectionId: u32;1684 readonly newSponsor: AccountId32;1685 } & Struct;1686 readonly isConfirmSponsorship: boolean;1687 readonly asConfirmSponsorship: {1688 readonly collectionId: u32;1689 } & Struct;1690 readonly isRemoveCollectionSponsor: boolean;1691 readonly asRemoveCollectionSponsor: {1692 readonly collectionId: u32;1693 } & Struct;1694 readonly isCreateItem: boolean;1695 readonly asCreateItem: {1696 readonly collectionId: u32;1697 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;1698 readonly data: UpDataStructsCreateItemData;1699 } & Struct;1700 readonly isCreateMultipleItems: boolean;1701 readonly asCreateMultipleItems: {1702 readonly collectionId: u32;1703 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;1704 readonly itemsData: Vec<UpDataStructsCreateItemData>;1705 } & Struct;1706 readonly isSetCollectionProperties: boolean;1707 readonly asSetCollectionProperties: {1708 readonly collectionId: u32;1709 readonly properties: Vec<UpDataStructsProperty>;1710 } & Struct;1711 readonly isDeleteCollectionProperties: boolean;1712 readonly asDeleteCollectionProperties: {1713 readonly collectionId: u32;1714 readonly propertyKeys: Vec<Bytes>;1715 } & Struct;1716 readonly isSetTokenProperties: boolean;1717 readonly asSetTokenProperties: {1718 readonly collectionId: u32;1719 readonly tokenId: u32;1720 readonly properties: Vec<UpDataStructsProperty>;1721 } & Struct;1722 readonly isDeleteTokenProperties: boolean;1723 readonly asDeleteTokenProperties: {1724 readonly collectionId: u32;1725 readonly tokenId: u32;1726 readonly propertyKeys: Vec<Bytes>;1727 } & Struct;1728 readonly isSetTokenPropertyPermissions: boolean;1729 readonly asSetTokenPropertyPermissions: {1730 readonly collectionId: u32;1731 readonly propertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;1732 } & Struct;1733 readonly isCreateMultipleItemsEx: boolean;1734 readonly asCreateMultipleItemsEx: {1735 readonly collectionId: u32;1736 readonly data: UpDataStructsCreateItemExData;1737 } & Struct;1738 readonly isSetTransfersEnabledFlag: boolean;1739 readonly asSetTransfersEnabledFlag: {1740 readonly collectionId: u32;1741 readonly value: bool;1742 } & Struct;1743 readonly isBurnItem: boolean;1744 readonly asBurnItem: {1745 readonly collectionId: u32;1746 readonly itemId: u32;1747 readonly value: u128;1748 } & Struct;1749 readonly isBurnFrom: boolean;1750 readonly asBurnFrom: {1751 readonly collectionId: u32;1752 readonly from: PalletEvmAccountBasicCrossAccountIdRepr;1753 readonly itemId: u32;1754 readonly value: u128;1755 } & Struct;1756 readonly isTransfer: boolean;1757 readonly asTransfer: {1758 readonly recipient: PalletEvmAccountBasicCrossAccountIdRepr;1759 readonly collectionId: u32;1760 readonly itemId: u32;1761 readonly value: u128;1762 } & Struct;1763 readonly isApprove: boolean;1764 readonly asApprove: {1765 readonly spender: PalletEvmAccountBasicCrossAccountIdRepr;1766 readonly collectionId: u32;1767 readonly itemId: u32;1768 readonly amount: u128;1769 } & Struct;1770 readonly isTransferFrom: boolean;1771 readonly asTransferFrom: {1772 readonly from: PalletEvmAccountBasicCrossAccountIdRepr;1773 readonly recipient: PalletEvmAccountBasicCrossAccountIdRepr;1774 readonly collectionId: u32;1775 readonly itemId: u32;1776 readonly value: u128;1777 } & Struct;1778 readonly isSetCollectionLimits: boolean;1779 readonly asSetCollectionLimits: {1780 readonly collectionId: u32;1781 readonly newLimit: UpDataStructsCollectionLimits;1782 } & Struct;1783 readonly isSetCollectionPermissions: boolean;1784 readonly asSetCollectionPermissions: {1785 readonly collectionId: u32;1786 readonly newPermission: UpDataStructsCollectionPermissions;1787 } & Struct;1788 readonly isRepartition: boolean;1789 readonly asRepartition: {1790 readonly collectionId: u32;1791 readonly tokenId: u32;1792 readonly amount: u128;1793 } & Struct;1794 readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';1795}17961797/** @name PalletUniqueError */1798export interface PalletUniqueError extends Enum {1799 readonly isCollectionDecimalPointLimitExceeded: boolean;1800 readonly isConfirmUnsetSponsorFail: boolean;1801 readonly isEmptyArgument: boolean;1802 readonly isRepartitionCalledOnNonRefungibleCollection: boolean;1803 readonly type: 'CollectionDecimalPointLimitExceeded' | 'ConfirmUnsetSponsorFail' | 'EmptyArgument' | 'RepartitionCalledOnNonRefungibleCollection';1804}18051806/** @name PalletUniqueRawEvent */1807export interface PalletUniqueRawEvent extends Enum {1808 readonly isCollectionSponsorRemoved: boolean;1809 readonly asCollectionSponsorRemoved: u32;1810 readonly isCollectionAdminAdded: boolean;1811 readonly asCollectionAdminAdded: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1812 readonly isCollectionOwnedChanged: boolean;1813 readonly asCollectionOwnedChanged: ITuple<[u32, AccountId32]>;1814 readonly isCollectionSponsorSet: boolean;1815 readonly asCollectionSponsorSet: ITuple<[u32, AccountId32]>;1816 readonly isSponsorshipConfirmed: boolean;1817 readonly asSponsorshipConfirmed: ITuple<[u32, AccountId32]>;1818 readonly isCollectionAdminRemoved: boolean;1819 readonly asCollectionAdminRemoved: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1820 readonly isAllowListAddressRemoved: boolean;1821 readonly asAllowListAddressRemoved: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1822 readonly isAllowListAddressAdded: boolean;1823 readonly asAllowListAddressAdded: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1824 readonly isCollectionLimitSet: boolean;1825 readonly asCollectionLimitSet: u32;1826 readonly isCollectionPermissionSet: boolean;1827 readonly asCollectionPermissionSet: u32;1828 readonly type: 'CollectionSponsorRemoved' | 'CollectionAdminAdded' | 'CollectionOwnedChanged' | 'CollectionSponsorSet' | 'SponsorshipConfirmed' | 'CollectionAdminRemoved' | 'AllowListAddressRemoved' | 'AllowListAddressAdded' | 'CollectionLimitSet' | 'CollectionPermissionSet';1829}18301831/** @name PalletUniqueSchedulerCall */1832export interface PalletUniqueSchedulerCall extends Enum {1833 readonly isScheduleNamed: boolean;1834 readonly asScheduleNamed: {1835 readonly id: U8aFixed;1836 readonly when: u32;1837 readonly maybePeriodic: Option<ITuple<[u32, u32]>>;1838 readonly priority: u8;1839 readonly call: FrameSupportScheduleMaybeHashed;1840 } & Struct;1841 readonly isCancelNamed: boolean;1842 readonly asCancelNamed: {1843 readonly id: U8aFixed;1844 } & Struct;1845 readonly isScheduleNamedAfter: boolean;1846 readonly asScheduleNamedAfter: {1847 readonly id: U8aFixed;1848 readonly after: u32;1849 readonly maybePeriodic: Option<ITuple<[u32, u32]>>;1850 readonly priority: u8;1851 readonly call: FrameSupportScheduleMaybeHashed;1852 } & Struct;1853 readonly type: 'ScheduleNamed' | 'CancelNamed' | 'ScheduleNamedAfter';1854}18551856/** @name PalletUniqueSchedulerError */1857export interface PalletUniqueSchedulerError extends Enum {1858 readonly isFailedToSchedule: boolean;1859 readonly isNotFound: boolean;1860 readonly isTargetBlockNumberInPast: boolean;1861 readonly isRescheduleNoChange: boolean;1862 readonly type: 'FailedToSchedule' | 'NotFound' | 'TargetBlockNumberInPast' | 'RescheduleNoChange';1863}18641865/** @name PalletUniqueSchedulerEvent */1866export interface PalletUniqueSchedulerEvent extends Enum {1867 readonly isScheduled: boolean;1868 readonly asScheduled: {1869 readonly when: u32;1870 readonly index: u32;1871 } & Struct;1872 readonly isCanceled: boolean;1873 readonly asCanceled: {1874 readonly when: u32;1875 readonly index: u32;1876 } & Struct;1877 readonly isDispatched: boolean;1878 readonly asDispatched: {1879 readonly task: ITuple<[u32, u32]>;1880 readonly id: Option<U8aFixed>;1881 readonly result: Result<Null, SpRuntimeDispatchError>;1882 } & Struct;1883 readonly isCallLookupFailed: boolean;1884 readonly asCallLookupFailed: {1885 readonly task: ITuple<[u32, u32]>;1886 readonly id: Option<U8aFixed>;1887 readonly error: FrameSupportScheduleLookupError;1888 } & Struct;1889 readonly type: 'Scheduled' | 'Canceled' | 'Dispatched' | 'CallLookupFailed';1890}18911892/** @name PalletUniqueSchedulerScheduledV3 */1893export interface PalletUniqueSchedulerScheduledV3 extends Struct {1894 readonly maybeId: Option<U8aFixed>;1895 readonly priority: u8;1896 readonly call: FrameSupportScheduleMaybeHashed;1897 readonly maybePeriodic: Option<ITuple<[u32, u32]>>;1898 readonly origin: OpalRuntimeOriginCaller;1899}19001901/** @name PalletXcmCall */1902export interface PalletXcmCall extends Enum {1903 readonly isSend: boolean;1904 readonly asSend: {1905 readonly dest: XcmVersionedMultiLocation;1906 readonly message: XcmVersionedXcm;1907 } & Struct;1908 readonly isTeleportAssets: boolean;1909 readonly asTeleportAssets: {1910 readonly dest: XcmVersionedMultiLocation;1911 readonly beneficiary: XcmVersionedMultiLocation;1912 readonly assets: XcmVersionedMultiAssets;1913 readonly feeAssetItem: u32;1914 } & Struct;1915 readonly isReserveTransferAssets: boolean;1916 readonly asReserveTransferAssets: {1917 readonly dest: XcmVersionedMultiLocation;1918 readonly beneficiary: XcmVersionedMultiLocation;1919 readonly assets: XcmVersionedMultiAssets;1920 readonly feeAssetItem: u32;1921 } & Struct;1922 readonly isExecute: boolean;1923 readonly asExecute: {1924 readonly message: XcmVersionedXcm;1925 readonly maxWeight: u64;1926 } & Struct;1927 readonly isForceXcmVersion: boolean;1928 readonly asForceXcmVersion: {1929 readonly location: XcmV1MultiLocation;1930 readonly xcmVersion: u32;1931 } & Struct;1932 readonly isForceDefaultXcmVersion: boolean;1933 readonly asForceDefaultXcmVersion: {1934 readonly maybeXcmVersion: Option<u32>;1935 } & Struct;1936 readonly isForceSubscribeVersionNotify: boolean;1937 readonly asForceSubscribeVersionNotify: {1938 readonly location: XcmVersionedMultiLocation;1939 } & Struct;1940 readonly isForceUnsubscribeVersionNotify: boolean;1941 readonly asForceUnsubscribeVersionNotify: {1942 readonly location: XcmVersionedMultiLocation;1943 } & Struct;1944 readonly isLimitedReserveTransferAssets: boolean;1945 readonly asLimitedReserveTransferAssets: {1946 readonly dest: XcmVersionedMultiLocation;1947 readonly beneficiary: XcmVersionedMultiLocation;1948 readonly assets: XcmVersionedMultiAssets;1949 readonly feeAssetItem: u32;1950 readonly weightLimit: XcmV2WeightLimit;1951 } & Struct;1952 readonly isLimitedTeleportAssets: boolean;1953 readonly asLimitedTeleportAssets: {1954 readonly dest: XcmVersionedMultiLocation;1955 readonly beneficiary: XcmVersionedMultiLocation;1956 readonly assets: XcmVersionedMultiAssets;1957 readonly feeAssetItem: u32;1958 readonly weightLimit: XcmV2WeightLimit;1959 } & Struct;1960 readonly type: 'Send' | 'TeleportAssets' | 'ReserveTransferAssets' | 'Execute' | 'ForceXcmVersion' | 'ForceDefaultXcmVersion' | 'ForceSubscribeVersionNotify' | 'ForceUnsubscribeVersionNotify' | 'LimitedReserveTransferAssets' | 'LimitedTeleportAssets';1961}19621963/** @name PalletXcmError */1964export interface PalletXcmError extends Enum {1965 readonly isUnreachable: boolean;1966 readonly isSendFailure: boolean;1967 readonly isFiltered: boolean;1968 readonly isUnweighableMessage: boolean;1969 readonly isDestinationNotInvertible: boolean;1970 readonly isEmpty: boolean;1971 readonly isCannotReanchor: boolean;1972 readonly isTooManyAssets: boolean;1973 readonly isInvalidOrigin: boolean;1974 readonly isBadVersion: boolean;1975 readonly isBadLocation: boolean;1976 readonly isNoSubscription: boolean;1977 readonly isAlreadySubscribed: boolean;1978 readonly type: 'Unreachable' | 'SendFailure' | 'Filtered' | 'UnweighableMessage' | 'DestinationNotInvertible' | 'Empty' | 'CannotReanchor' | 'TooManyAssets' | 'InvalidOrigin' | 'BadVersion' | 'BadLocation' | 'NoSubscription' | 'AlreadySubscribed';1979}19801981/** @name PalletXcmEvent */1982export interface PalletXcmEvent extends Enum {1983 readonly isAttempted: boolean;1984 readonly asAttempted: XcmV2TraitsOutcome;1985 readonly isSent: boolean;1986 readonly asSent: ITuple<[XcmV1MultiLocation, XcmV1MultiLocation, XcmV2Xcm]>;1987 readonly isUnexpectedResponse: boolean;1988 readonly asUnexpectedResponse: ITuple<[XcmV1MultiLocation, u64]>;1989 readonly isResponseReady: boolean;1990 readonly asResponseReady: ITuple<[u64, XcmV2Response]>;1991 readonly isNotified: boolean;1992 readonly asNotified: ITuple<[u64, u8, u8]>;1993 readonly isNotifyOverweight: boolean;1994 readonly asNotifyOverweight: ITuple<[u64, u8, u8, u64, u64]>;1995 readonly isNotifyDispatchError: boolean;1996 readonly asNotifyDispatchError: ITuple<[u64, u8, u8]>;1997 readonly isNotifyDecodeFailed: boolean;1998 readonly asNotifyDecodeFailed: ITuple<[u64, u8, u8]>;1999 readonly isInvalidResponder: boolean;2000 readonly asInvalidResponder: ITuple<[XcmV1MultiLocation, u64, Option<XcmV1MultiLocation>]>;2001 readonly isInvalidResponderVersion: boolean;2002 readonly asInvalidResponderVersion: ITuple<[XcmV1MultiLocation, u64]>;2003 readonly isResponseTaken: boolean;2004 readonly asResponseTaken: u64;2005 readonly isAssetsTrapped: boolean;2006 readonly asAssetsTrapped: ITuple<[H256, XcmV1MultiLocation, XcmVersionedMultiAssets]>;2007 readonly isVersionChangeNotified: boolean;2008 readonly asVersionChangeNotified: ITuple<[XcmV1MultiLocation, u32]>;2009 readonly isSupportedVersionChanged: boolean;2010 readonly asSupportedVersionChanged: ITuple<[XcmV1MultiLocation, u32]>;2011 readonly isNotifyTargetSendFail: boolean;2012 readonly asNotifyTargetSendFail: ITuple<[XcmV1MultiLocation, u64, XcmV2TraitsError]>;2013 readonly isNotifyTargetMigrationFail: boolean;2014 readonly asNotifyTargetMigrationFail: ITuple<[XcmVersionedMultiLocation, u64]>;2015 readonly type: 'Attempted' | 'Sent' | 'UnexpectedResponse' | 'ResponseReady' | 'Notified' | 'NotifyOverweight' | 'NotifyDispatchError' | 'NotifyDecodeFailed' | 'InvalidResponder' | 'InvalidResponderVersion' | 'ResponseTaken' | 'AssetsTrapped' | 'VersionChangeNotified' | 'SupportedVersionChanged' | 'NotifyTargetSendFail' | 'NotifyTargetMigrationFail';2016}20172018/** @name PalletXcmOrigin */2019export interface PalletXcmOrigin extends Enum {2020 readonly isXcm: boolean;2021 readonly asXcm: XcmV1MultiLocation;2022 readonly isResponse: boolean;2023 readonly asResponse: XcmV1MultiLocation;2024 readonly type: 'Xcm' | 'Response';2025}20262027/** @name PhantomTypeUpDataStructs */2028export interface PhantomTypeUpDataStructs extends Vec<ITuple<[UpDataStructsTokenData, UpDataStructsRpcCollection, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftNftInfo, RmrkTraitsResourceResourceInfo, RmrkTraitsPropertyPropertyInfo, RmrkTraitsBaseBaseInfo, RmrkTraitsPartPartType, RmrkTraitsTheme, RmrkTraitsNftNftChild]>> {}20292030/** @name PolkadotCorePrimitivesInboundDownwardMessage */2031export interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {2032 readonly sentAt: u32;2033 readonly msg: Bytes;2034}20352036/** @name PolkadotCorePrimitivesInboundHrmpMessage */2037export interface PolkadotCorePrimitivesInboundHrmpMessage extends Struct {2038 readonly sentAt: u32;2039 readonly data: Bytes;2040}20412042/** @name PolkadotCorePrimitivesOutboundHrmpMessage */2043export interface PolkadotCorePrimitivesOutboundHrmpMessage extends Struct {2044 readonly recipient: u32;2045 readonly data: Bytes;2046}20472048/** @name PolkadotParachainPrimitivesXcmpMessageFormat */2049export interface PolkadotParachainPrimitivesXcmpMessageFormat extends Enum {2050 readonly isConcatenatedVersionedXcm: boolean;2051 readonly isConcatenatedEncodedBlob: boolean;2052 readonly isSignals: boolean;2053 readonly type: 'ConcatenatedVersionedXcm' | 'ConcatenatedEncodedBlob' | 'Signals';2054}20552056/** @name PolkadotPrimitivesV2AbridgedHostConfiguration */2057export interface PolkadotPrimitivesV2AbridgedHostConfiguration extends Struct {2058 readonly maxCodeSize: u32;2059 readonly maxHeadDataSize: u32;2060 readonly maxUpwardQueueCount: u32;2061 readonly maxUpwardQueueSize: u32;2062 readonly maxUpwardMessageSize: u32;2063 readonly maxUpwardMessageNumPerCandidate: u32;2064 readonly hrmpMaxMessageNumPerCandidate: u32;2065 readonly validationUpgradeCooldown: u32;2066 readonly validationUpgradeDelay: u32;2067}20682069/** @name PolkadotPrimitivesV2AbridgedHrmpChannel */2070export interface PolkadotPrimitivesV2AbridgedHrmpChannel extends Struct {2071 readonly maxCapacity: u32;2072 readonly maxTotalSize: u32;2073 readonly maxMessageSize: u32;2074 readonly msgCount: u32;2075 readonly totalSize: u32;2076 readonly mqcHead: Option<H256>;2077}20782079/** @name PolkadotPrimitivesV2PersistedValidationData */2080export interface PolkadotPrimitivesV2PersistedValidationData extends Struct {2081 readonly parentHead: Bytes;2082 readonly relayParentNumber: u32;2083 readonly relayParentStorageRoot: H256;2084 readonly maxPovSize: u32;2085}20862087/** @name PolkadotPrimitivesV2UpgradeRestriction */2088export interface PolkadotPrimitivesV2UpgradeRestriction extends Enum {2089 readonly isPresent: boolean;2090 readonly type: 'Present';2091}20922093/** @name RmrkTraitsBaseBaseInfo */2094export interface RmrkTraitsBaseBaseInfo extends Struct {2095 readonly issuer: AccountId32;2096 readonly baseType: Bytes;2097 readonly symbol: Bytes;2098}20992100/** @name RmrkTraitsCollectionCollectionInfo */2101export interface RmrkTraitsCollectionCollectionInfo extends Struct {2102 readonly issuer: AccountId32;2103 readonly metadata: Bytes;2104 readonly max: Option<u32>;2105 readonly symbol: Bytes;2106 readonly nftsCount: u32;2107}21082109/** @name RmrkTraitsNftAccountIdOrCollectionNftTuple */2110export interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {2111 readonly isAccountId: boolean;2112 readonly asAccountId: AccountId32;2113 readonly isCollectionAndNftTuple: boolean;2114 readonly asCollectionAndNftTuple: ITuple<[u32, u32]>;2115 readonly type: 'AccountId' | 'CollectionAndNftTuple';2116}21172118/** @name RmrkTraitsNftNftChild */2119export interface RmrkTraitsNftNftChild extends Struct {2120 readonly collectionId: u32;2121 readonly nftId: u32;2122}21232124/** @name RmrkTraitsNftNftInfo */2125export interface RmrkTraitsNftNftInfo extends Struct {2126 readonly owner: RmrkTraitsNftAccountIdOrCollectionNftTuple;2127 readonly royalty: Option<RmrkTraitsNftRoyaltyInfo>;2128 readonly metadata: Bytes;2129 readonly equipped: bool;2130 readonly pending: bool;2131}21322133/** @name RmrkTraitsNftRoyaltyInfo */2134export interface RmrkTraitsNftRoyaltyInfo extends Struct {2135 readonly recipient: AccountId32;2136 readonly amount: Permill;2137}21382139/** @name RmrkTraitsPartEquippableList */2140export interface RmrkTraitsPartEquippableList extends Enum {2141 readonly isAll: boolean;2142 readonly isEmpty: boolean;2143 readonly isCustom: boolean;2144 readonly asCustom: Vec<u32>;2145 readonly type: 'All' | 'Empty' | 'Custom';2146}21472148/** @name RmrkTraitsPartFixedPart */2149export interface RmrkTraitsPartFixedPart extends Struct {2150 readonly id: u32;2151 readonly z: u32;2152 readonly src: Bytes;2153}21542155/** @name RmrkTraitsPartPartType */2156export interface RmrkTraitsPartPartType extends Enum {2157 readonly isFixedPart: boolean;2158 readonly asFixedPart: RmrkTraitsPartFixedPart;2159 readonly isSlotPart: boolean;2160 readonly asSlotPart: RmrkTraitsPartSlotPart;2161 readonly type: 'FixedPart' | 'SlotPart';2162}21632164/** @name RmrkTraitsPartSlotPart */2165export interface RmrkTraitsPartSlotPart extends Struct {2166 readonly id: u32;2167 readonly equippable: RmrkTraitsPartEquippableList;2168 readonly src: Bytes;2169 readonly z: u32;2170}21712172/** @name RmrkTraitsPropertyPropertyInfo */2173export interface RmrkTraitsPropertyPropertyInfo extends Struct {2174 readonly key: Bytes;2175 readonly value: Bytes;2176}21772178/** @name RmrkTraitsResourceBasicResource */2179export interface RmrkTraitsResourceBasicResource extends Struct {2180 readonly src: Option<Bytes>;2181 readonly metadata: Option<Bytes>;2182 readonly license: Option<Bytes>;2183 readonly thumb: Option<Bytes>;2184}21852186/** @name RmrkTraitsResourceComposableResource */2187export interface RmrkTraitsResourceComposableResource extends Struct {2188 readonly parts: Vec<u32>;2189 readonly base: u32;2190 readonly src: Option<Bytes>;2191 readonly metadata: Option<Bytes>;2192 readonly license: Option<Bytes>;2193 readonly thumb: Option<Bytes>;2194}21952196/** @name RmrkTraitsResourceResourceInfo */2197export interface RmrkTraitsResourceResourceInfo extends Struct {2198 readonly id: u32;2199 readonly resource: RmrkTraitsResourceResourceTypes;2200 readonly pending: bool;2201 readonly pendingRemoval: bool;2202}22032204/** @name RmrkTraitsResourceResourceTypes */2205export interface RmrkTraitsResourceResourceTypes extends Enum {2206 readonly isBasic: boolean;2207 readonly asBasic: RmrkTraitsResourceBasicResource;2208 readonly isComposable: boolean;2209 readonly asComposable: RmrkTraitsResourceComposableResource;2210 readonly isSlot: boolean;2211 readonly asSlot: RmrkTraitsResourceSlotResource;2212 readonly type: 'Basic' | 'Composable' | 'Slot';2213}22142215/** @name RmrkTraitsResourceSlotResource */2216export interface RmrkTraitsResourceSlotResource extends Struct {2217 readonly base: u32;2218 readonly src: Option<Bytes>;2219 readonly metadata: Option<Bytes>;2220 readonly slot: u32;2221 readonly license: Option<Bytes>;2222 readonly thumb: Option<Bytes>;2223}22242225/** @name RmrkTraitsTheme */2226export interface RmrkTraitsTheme extends Struct {2227 readonly name: Bytes;2228 readonly properties: Vec<RmrkTraitsThemeThemeProperty>;2229 readonly inherit: bool;2230}22312232/** @name RmrkTraitsThemeThemeProperty */2233export interface RmrkTraitsThemeThemeProperty extends Struct {2234 readonly key: Bytes;2235 readonly value: Bytes;2236}22372238/** @name SpCoreEcdsaSignature */2239export interface SpCoreEcdsaSignature extends U8aFixed {}22402241/** @name SpCoreEd25519Signature */2242export interface SpCoreEd25519Signature extends U8aFixed {}22432244/** @name SpCoreSr25519Signature */2245export interface SpCoreSr25519Signature extends U8aFixed {}22462247/** @name SpCoreVoid */2248export interface SpCoreVoid extends Null {}22492250/** @name SpRuntimeArithmeticError */2251export interface SpRuntimeArithmeticError extends Enum {2252 readonly isUnderflow: boolean;2253 readonly isOverflow: boolean;2254 readonly isDivisionByZero: boolean;2255 readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero';2256}22572258/** @name SpRuntimeDigest */2259export interface SpRuntimeDigest extends Struct {2260 readonly logs: Vec<SpRuntimeDigestDigestItem>;2261}22622263/** @name SpRuntimeDigestDigestItem */2264export interface SpRuntimeDigestDigestItem extends Enum {2265 readonly isOther: boolean;2266 readonly asOther: Bytes;2267 readonly isConsensus: boolean;2268 readonly asConsensus: ITuple<[U8aFixed, Bytes]>;2269 readonly isSeal: boolean;2270 readonly asSeal: ITuple<[U8aFixed, Bytes]>;2271 readonly isPreRuntime: boolean;2272 readonly asPreRuntime: ITuple<[U8aFixed, Bytes]>;2273 readonly isRuntimeEnvironmentUpdated: boolean;2274 readonly type: 'Other' | 'Consensus' | 'Seal' | 'PreRuntime' | 'RuntimeEnvironmentUpdated';2275}22762277/** @name SpRuntimeDispatchError */2278export interface SpRuntimeDispatchError extends Enum {2279 readonly isOther: boolean;2280 readonly isCannotLookup: boolean;2281 readonly isBadOrigin: boolean;2282 readonly isModule: boolean;2283 readonly asModule: SpRuntimeModuleError;2284 readonly isConsumerRemaining: boolean;2285 readonly isNoProviders: boolean;2286 readonly isTooManyConsumers: boolean;2287 readonly isToken: boolean;2288 readonly asToken: SpRuntimeTokenError;2289 readonly isArithmetic: boolean;2290 readonly asArithmetic: SpRuntimeArithmeticError;2291 readonly isTransactional: boolean;2292 readonly asTransactional: SpRuntimeTransactionalError;2293 readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic' | 'Transactional';2294}22952296/** @name SpRuntimeModuleError */2297export interface SpRuntimeModuleError extends Struct {2298 readonly index: u8;2299 readonly error: U8aFixed;2300}23012302/** @name SpRuntimeMultiSignature */2303export interface SpRuntimeMultiSignature extends Enum {2304 readonly isEd25519: boolean;2305 readonly asEd25519: SpCoreEd25519Signature;2306 readonly isSr25519: boolean;2307 readonly asSr25519: SpCoreSr25519Signature;2308 readonly isEcdsa: boolean;2309 readonly asEcdsa: SpCoreEcdsaSignature;2310 readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa';2311}23122313/** @name SpRuntimeTokenError */2314export interface SpRuntimeTokenError extends Enum {2315 readonly isNoFunds: boolean;2316 readonly isWouldDie: boolean;2317 readonly isBelowMinimum: boolean;2318 readonly isCannotCreate: boolean;2319 readonly isUnknownAsset: boolean;2320 readonly isFrozen: boolean;2321 readonly isUnsupported: boolean;2322 readonly type: 'NoFunds' | 'WouldDie' | 'BelowMinimum' | 'CannotCreate' | 'UnknownAsset' | 'Frozen' | 'Unsupported';2323}23242325/** @name SpRuntimeTransactionalError */2326export interface SpRuntimeTransactionalError extends Enum {2327 readonly isLimitReached: boolean;2328 readonly isNoLayer: boolean;2329 readonly type: 'LimitReached' | 'NoLayer';2330}23312332/** @name SpTrieStorageProof */2333export interface SpTrieStorageProof extends Struct {2334 readonly trieNodes: BTreeSet<Bytes>;2335}23362337/** @name SpVersionRuntimeVersion */2338export interface SpVersionRuntimeVersion extends Struct {2339 readonly specName: Text;2340 readonly implName: Text;2341 readonly authoringVersion: u32;2342 readonly specVersion: u32;2343 readonly implVersion: u32;2344 readonly apis: Vec<ITuple<[U8aFixed, u32]>>;2345 readonly transactionVersion: u32;2346 readonly stateVersion: u8;2347}23482349/** @name UpDataStructsAccessMode */2350export interface UpDataStructsAccessMode extends Enum {2351 readonly isNormal: boolean;2352 readonly isAllowList: boolean;2353 readonly type: 'Normal' | 'AllowList';2354}23552356/** @name UpDataStructsCollection */2357export interface UpDataStructsCollection extends Struct {2358 readonly owner: AccountId32;2359 readonly mode: UpDataStructsCollectionMode;2360 readonly name: Vec<u16>;2361 readonly description: Vec<u16>;2362 readonly tokenPrefix: Bytes;2363 readonly sponsorship: UpDataStructsSponsorshipState;2364 readonly limits: UpDataStructsCollectionLimits;2365 readonly permissions: UpDataStructsCollectionPermissions;2366 readonly externalCollection: bool;2367}23682369/** @name UpDataStructsCollectionLimits */2370export interface UpDataStructsCollectionLimits extends Struct {2371 readonly accountTokenOwnershipLimit: Option<u32>;2372 readonly sponsoredDataSize: Option<u32>;2373 readonly sponsoredDataRateLimit: Option<UpDataStructsSponsoringRateLimit>;2374 readonly tokenLimit: Option<u32>;2375 readonly sponsorTransferTimeout: Option<u32>;2376 readonly sponsorApproveTimeout: Option<u32>;2377 readonly ownerCanTransfer: Option<bool>;2378 readonly ownerCanDestroy: Option<bool>;2379 readonly transfersEnabled: Option<bool>;2380}23812382/** @name UpDataStructsCollectionMode */2383export interface UpDataStructsCollectionMode extends Enum {2384 readonly isNft: boolean;2385 readonly isFungible: boolean;2386 readonly asFungible: u8;2387 readonly isReFungible: boolean;2388 readonly type: 'Nft' | 'Fungible' | 'ReFungible';2389}23902391/** @name UpDataStructsCollectionPermissions */2392export interface UpDataStructsCollectionPermissions extends Struct {2393 readonly access: Option<UpDataStructsAccessMode>;2394 readonly mintMode: Option<bool>;2395 readonly nesting: Option<UpDataStructsNestingPermissions>;2396}23972398/** @name UpDataStructsCollectionStats */2399export interface UpDataStructsCollectionStats extends Struct {2400 readonly created: u32;2401 readonly destroyed: u32;2402 readonly alive: u32;2403}24042405/** @name UpDataStructsCreateCollectionData */2406export interface UpDataStructsCreateCollectionData extends Struct {2407 readonly mode: UpDataStructsCollectionMode;2408 readonly access: Option<UpDataStructsAccessMode>;2409 readonly name: Vec<u16>;2410 readonly description: Vec<u16>;2411 readonly tokenPrefix: Bytes;2412 readonly pendingSponsor: Option<AccountId32>;2413 readonly limits: Option<UpDataStructsCollectionLimits>;2414 readonly permissions: Option<UpDataStructsCollectionPermissions>;2415 readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;2416 readonly properties: Vec<UpDataStructsProperty>;2417}24182419/** @name UpDataStructsCreateFungibleData */2420export interface UpDataStructsCreateFungibleData extends Struct {2421 readonly value: u128;2422}24232424/** @name UpDataStructsCreateItemData */2425export interface UpDataStructsCreateItemData extends Enum {2426 readonly isNft: boolean;2427 readonly asNft: UpDataStructsCreateNftData;2428 readonly isFungible: boolean;2429 readonly asFungible: UpDataStructsCreateFungibleData;2430 readonly isReFungible: boolean;2431 readonly asReFungible: UpDataStructsCreateReFungibleData;2432 readonly type: 'Nft' | 'Fungible' | 'ReFungible';2433}24342435/** @name UpDataStructsCreateItemExData */2436export interface UpDataStructsCreateItemExData extends Enum {2437 readonly isNft: boolean;2438 readonly asNft: Vec<UpDataStructsCreateNftExData>;2439 readonly isFungible: boolean;2440 readonly asFungible: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr,u128>;2441 readonly isRefungibleMultipleItems: boolean;2442 readonly asRefungibleMultipleItems: Vec<UpDataStructsCreateRefungibleExSingleOwner>;2443 readonly isRefungibleMultipleOwners: boolean;2444 readonly asRefungibleMultipleOwners: UpDataStructsCreateRefungibleExMultipleOwners;2445 readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';2446}24472448/** @name UpDataStructsCreateNftData */2449export interface UpDataStructsCreateNftData extends Struct {2450 readonly properties: Vec<UpDataStructsProperty>;2451}24522453/** @name UpDataStructsCreateNftExData */2454export interface UpDataStructsCreateNftExData extends Struct {2455 readonly properties: Vec<UpDataStructsProperty>;2456 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;2457}24582459/** @name UpDataStructsCreateReFungibleData */2460export interface UpDataStructsCreateReFungibleData extends Struct {2461 readonly pieces: u128;2462 readonly properties: Vec<UpDataStructsProperty>;2463}24642465/** @name UpDataStructsCreateRefungibleExMultipleOwners */2466export interface UpDataStructsCreateRefungibleExMultipleOwners extends Struct {2467 readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;2468 readonly properties: Vec<UpDataStructsProperty>;2469}24702471/** @name UpDataStructsCreateRefungibleExSingleOwner */2472export interface UpDataStructsCreateRefungibleExSingleOwner extends Struct {2473 readonly user: PalletEvmAccountBasicCrossAccountIdRepr;2474 readonly pieces: u128;2475 readonly properties: Vec<UpDataStructsProperty>;2476}24772478/** @name UpDataStructsNestingPermissions */2479export interface UpDataStructsNestingPermissions extends Struct {2480 readonly tokenOwner: bool;2481 readonly collectionAdmin: bool;2482 readonly restricted: Option<UpDataStructsOwnerRestrictedSet>;2483}24842485/** @name UpDataStructsOwnerRestrictedSet */2486export interface UpDataStructsOwnerRestrictedSet extends BTreeSet<u32> {}24872488/** @name UpDataStructsProperties */2489export interface UpDataStructsProperties extends Struct {2490 readonly map: UpDataStructsPropertiesMapBoundedVec;2491 readonly consumedSpace: u32;2492 readonly spaceLimit: u32;2493}24942495/** @name UpDataStructsPropertiesMapBoundedVec */2496export interface UpDataStructsPropertiesMapBoundedVec extends BTreeMap<Bytes, Bytes> {}24972498/** @name UpDataStructsPropertiesMapPropertyPermission */2499export interface UpDataStructsPropertiesMapPropertyPermission extends BTreeMap<Bytes, UpDataStructsPropertyPermission> {}25002501/** @name UpDataStructsProperty */2502export interface UpDataStructsProperty extends Struct {2503 readonly key: Bytes;2504 readonly value: Bytes;2505}25062507/** @name UpDataStructsPropertyKeyPermission */2508export interface UpDataStructsPropertyKeyPermission extends Struct {2509 readonly key: Bytes;2510 readonly permission: UpDataStructsPropertyPermission;2511}25122513/** @name UpDataStructsPropertyPermission */2514export interface UpDataStructsPropertyPermission extends Struct {2515 readonly mutable: bool;2516 readonly collectionAdmin: bool;2517 readonly tokenOwner: bool;2518}25192520/** @name UpDataStructsPropertyScope */2521export interface UpDataStructsPropertyScope extends Enum {2522 readonly isNone: boolean;2523 readonly isRmrk: boolean;2524 readonly type: 'None' | 'Rmrk';2525}25262527/** @name UpDataStructsRpcCollection */2528export interface UpDataStructsRpcCollection extends Struct {2529 readonly owner: AccountId32;2530 readonly mode: UpDataStructsCollectionMode;2531 readonly name: Vec<u16>;2532 readonly description: Vec<u16>;2533 readonly tokenPrefix: Bytes;2534 readonly sponsorship: UpDataStructsSponsorshipState;2535 readonly limits: UpDataStructsCollectionLimits;2536 readonly permissions: UpDataStructsCollectionPermissions;2537 readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;2538 readonly properties: Vec<UpDataStructsProperty>;2539 readonly readOnly: bool;2540}25412542/** @name UpDataStructsSponsoringRateLimit */2543export interface UpDataStructsSponsoringRateLimit extends Enum {2544 readonly isSponsoringDisabled: boolean;2545 readonly isBlocks: boolean;2546 readonly asBlocks: u32;2547 readonly type: 'SponsoringDisabled' | 'Blocks';2548}25492550/** @name UpDataStructsSponsorshipState */2551export interface UpDataStructsSponsorshipState extends Enum {2552 readonly isDisabled: boolean;2553 readonly isUnconfirmed: boolean;2554 readonly asUnconfirmed: AccountId32;2555 readonly isConfirmed: boolean;2556 readonly asConfirmed: AccountId32;2557 readonly type: 'Disabled' | 'Unconfirmed' | 'Confirmed';2558}25592560/** @name UpDataStructsTokenChild */2561export interface UpDataStructsTokenChild extends Struct {2562 readonly token: u32;2563 readonly collection: u32;2564}25652566/** @name UpDataStructsTokenData */2567export interface UpDataStructsTokenData extends Struct {2568 readonly properties: Vec<UpDataStructsProperty>;2569 readonly owner: Option<PalletEvmAccountBasicCrossAccountIdRepr>;2570 readonly pieces: u128;2571}25722573/** @name XcmDoubleEncoded */2574export interface XcmDoubleEncoded extends Struct {2575 readonly encoded: Bytes;2576}25772578/** @name XcmV0Junction */2579export interface XcmV0Junction extends Enum {2580 readonly isParent: boolean;2581 readonly isParachain: boolean;2582 readonly asParachain: Compact<u32>;2583 readonly isAccountId32: boolean;2584 readonly asAccountId32: {2585 readonly network: XcmV0JunctionNetworkId;2586 readonly id: U8aFixed;2587 } & Struct;2588 readonly isAccountIndex64: boolean;2589 readonly asAccountIndex64: {2590 readonly network: XcmV0JunctionNetworkId;2591 readonly index: Compact<u64>;2592 } & Struct;2593 readonly isAccountKey20: boolean;2594 readonly asAccountKey20: {2595 readonly network: XcmV0JunctionNetworkId;2596 readonly key: U8aFixed;2597 } & Struct;2598 readonly isPalletInstance: boolean;2599 readonly asPalletInstance: u8;2600 readonly isGeneralIndex: boolean;2601 readonly asGeneralIndex: Compact<u128>;2602 readonly isGeneralKey: boolean;2603 readonly asGeneralKey: Bytes;2604 readonly isOnlyChild: boolean;2605 readonly isPlurality: boolean;2606 readonly asPlurality: {2607 readonly id: XcmV0JunctionBodyId;2608 readonly part: XcmV0JunctionBodyPart;2609 } & Struct;2610 readonly type: 'Parent' | 'Parachain' | 'AccountId32' | 'AccountIndex64' | 'AccountKey20' | 'PalletInstance' | 'GeneralIndex' | 'GeneralKey' | 'OnlyChild' | 'Plurality';2611}26122613/** @name XcmV0JunctionBodyId */2614export interface XcmV0JunctionBodyId extends Enum {2615 readonly isUnit: boolean;2616 readonly isNamed: boolean;2617 readonly asNamed: Bytes;2618 readonly isIndex: boolean;2619 readonly asIndex: Compact<u32>;2620 readonly isExecutive: boolean;2621 readonly isTechnical: boolean;2622 readonly isLegislative: boolean;2623 readonly isJudicial: boolean;2624 readonly type: 'Unit' | 'Named' | 'Index' | 'Executive' | 'Technical' | 'Legislative' | 'Judicial';2625}26262627/** @name XcmV0JunctionBodyPart */2628export interface XcmV0JunctionBodyPart extends Enum {2629 readonly isVoice: boolean;2630 readonly isMembers: boolean;2631 readonly asMembers: {2632 readonly count: Compact<u32>;2633 } & Struct;2634 readonly isFraction: boolean;2635 readonly asFraction: {2636 readonly nom: Compact<u32>;2637 readonly denom: Compact<u32>;2638 } & Struct;2639 readonly isAtLeastProportion: boolean;2640 readonly asAtLeastProportion: {2641 readonly nom: Compact<u32>;2642 readonly denom: Compact<u32>;2643 } & Struct;2644 readonly isMoreThanProportion: boolean;2645 readonly asMoreThanProportion: {2646 readonly nom: Compact<u32>;2647 readonly denom: Compact<u32>;2648 } & Struct;2649 readonly type: 'Voice' | 'Members' | 'Fraction' | 'AtLeastProportion' | 'MoreThanProportion';2650}26512652/** @name XcmV0JunctionNetworkId */2653export interface XcmV0JunctionNetworkId extends Enum {2654 readonly isAny: boolean;2655 readonly isNamed: boolean;2656 readonly asNamed: Bytes;2657 readonly isPolkadot: boolean;2658 readonly isKusama: boolean;2659 readonly type: 'Any' | 'Named' | 'Polkadot' | 'Kusama';2660}26612662/** @name XcmV0MultiAsset */2663export interface XcmV0MultiAsset extends Enum {2664 readonly isNone: boolean;2665 readonly isAll: boolean;2666 readonly isAllFungible: boolean;2667 readonly isAllNonFungible: boolean;2668 readonly isAllAbstractFungible: boolean;2669 readonly asAllAbstractFungible: {2670 readonly id: Bytes;2671 } & Struct;2672 readonly isAllAbstractNonFungible: boolean;2673 readonly asAllAbstractNonFungible: {2674 readonly class: Bytes;2675 } & Struct;2676 readonly isAllConcreteFungible: boolean;2677 readonly asAllConcreteFungible: {2678 readonly id: XcmV0MultiLocation;2679 } & Struct;2680 readonly isAllConcreteNonFungible: boolean;2681 readonly asAllConcreteNonFungible: {2682 readonly class: XcmV0MultiLocation;2683 } & Struct;2684 readonly isAbstractFungible: boolean;2685 readonly asAbstractFungible: {2686 readonly id: Bytes;2687 readonly amount: Compact<u128>;2688 } & Struct;2689 readonly isAbstractNonFungible: boolean;2690 readonly asAbstractNonFungible: {2691 readonly class: Bytes;2692 readonly instance: XcmV1MultiassetAssetInstance;2693 } & Struct;2694 readonly isConcreteFungible: boolean;2695 readonly asConcreteFungible: {2696 readonly id: XcmV0MultiLocation;2697 readonly amount: Compact<u128>;2698 } & Struct;2699 readonly isConcreteNonFungible: boolean;2700 readonly asConcreteNonFungible: {2701 readonly class: XcmV0MultiLocation;2702 readonly instance: XcmV1MultiassetAssetInstance;2703 } & Struct;2704 readonly type: 'None' | 'All' | 'AllFungible' | 'AllNonFungible' | 'AllAbstractFungible' | 'AllAbstractNonFungible' | 'AllConcreteFungible' | 'AllConcreteNonFungible' | 'AbstractFungible' | 'AbstractNonFungible' | 'ConcreteFungible' | 'ConcreteNonFungible';2705}27062707/** @name XcmV0MultiLocation */2708export interface XcmV0MultiLocation extends Enum {2709 readonly isNull: boolean;2710 readonly isX1: boolean;2711 readonly asX1: XcmV0Junction;2712 readonly isX2: boolean;2713 readonly asX2: ITuple<[XcmV0Junction, XcmV0Junction]>;2714 readonly isX3: boolean;2715 readonly asX3: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2716 readonly isX4: boolean;2717 readonly asX4: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2718 readonly isX5: boolean;2719 readonly asX5: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2720 readonly isX6: boolean;2721 readonly asX6: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2722 readonly isX7: boolean;2723 readonly asX7: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2724 readonly isX8: boolean;2725 readonly asX8: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2726 readonly type: 'Null' | 'X1' | 'X2' | 'X3' | 'X4' | 'X5' | 'X6' | 'X7' | 'X8';2727}27282729/** @name XcmV0Order */2730export interface XcmV0Order extends Enum {2731 readonly isNull: boolean;2732 readonly isDepositAsset: boolean;2733 readonly asDepositAsset: {2734 readonly assets: Vec<XcmV0MultiAsset>;2735 readonly dest: XcmV0MultiLocation;2736 } & Struct;2737 readonly isDepositReserveAsset: boolean;2738 readonly asDepositReserveAsset: {2739 readonly assets: Vec<XcmV0MultiAsset>;2740 readonly dest: XcmV0MultiLocation;2741 readonly effects: Vec<XcmV0Order>;2742 } & Struct;2743 readonly isExchangeAsset: boolean;2744 readonly asExchangeAsset: {2745 readonly give: Vec<XcmV0MultiAsset>;2746 readonly receive: Vec<XcmV0MultiAsset>;2747 } & Struct;2748 readonly isInitiateReserveWithdraw: boolean;2749 readonly asInitiateReserveWithdraw: {2750 readonly assets: Vec<XcmV0MultiAsset>;2751 readonly reserve: XcmV0MultiLocation;2752 readonly effects: Vec<XcmV0Order>;2753 } & Struct;2754 readonly isInitiateTeleport: boolean;2755 readonly asInitiateTeleport: {2756 readonly assets: Vec<XcmV0MultiAsset>;2757 readonly dest: XcmV0MultiLocation;2758 readonly effects: Vec<XcmV0Order>;2759 } & Struct;2760 readonly isQueryHolding: boolean;2761 readonly asQueryHolding: {2762 readonly queryId: Compact<u64>;2763 readonly dest: XcmV0MultiLocation;2764 readonly assets: Vec<XcmV0MultiAsset>;2765 } & Struct;2766 readonly isBuyExecution: boolean;2767 readonly asBuyExecution: {2768 readonly fees: XcmV0MultiAsset;2769 readonly weight: u64;2770 readonly debt: u64;2771 readonly haltOnError: bool;2772 readonly xcm: Vec<XcmV0Xcm>;2773 } & Struct;2774 readonly type: 'Null' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';2775}27762777/** @name XcmV0OriginKind */2778export interface XcmV0OriginKind extends Enum {2779 readonly isNative: boolean;2780 readonly isSovereignAccount: boolean;2781 readonly isSuperuser: boolean;2782 readonly isXcm: boolean;2783 readonly type: 'Native' | 'SovereignAccount' | 'Superuser' | 'Xcm';2784}27852786/** @name XcmV0Response */2787export interface XcmV0Response extends Enum {2788 readonly isAssets: boolean;2789 readonly asAssets: Vec<XcmV0MultiAsset>;2790 readonly type: 'Assets';2791}27922793/** @name XcmV0Xcm */2794export interface XcmV0Xcm extends Enum {2795 readonly isWithdrawAsset: boolean;2796 readonly asWithdrawAsset: {2797 readonly assets: Vec<XcmV0MultiAsset>;2798 readonly effects: Vec<XcmV0Order>;2799 } & Struct;2800 readonly isReserveAssetDeposit: boolean;2801 readonly asReserveAssetDeposit: {2802 readonly assets: Vec<XcmV0MultiAsset>;2803 readonly effects: Vec<XcmV0Order>;2804 } & Struct;2805 readonly isTeleportAsset: boolean;2806 readonly asTeleportAsset: {2807 readonly assets: Vec<XcmV0MultiAsset>;2808 readonly effects: Vec<XcmV0Order>;2809 } & Struct;2810 readonly isQueryResponse: boolean;2811 readonly asQueryResponse: {2812 readonly queryId: Compact<u64>;2813 readonly response: XcmV0Response;2814 } & Struct;2815 readonly isTransferAsset: boolean;2816 readonly asTransferAsset: {2817 readonly assets: Vec<XcmV0MultiAsset>;2818 readonly dest: XcmV0MultiLocation;2819 } & Struct;2820 readonly isTransferReserveAsset: boolean;2821 readonly asTransferReserveAsset: {2822 readonly assets: Vec<XcmV0MultiAsset>;2823 readonly dest: XcmV0MultiLocation;2824 readonly effects: Vec<XcmV0Order>;2825 } & Struct;2826 readonly isTransact: boolean;2827 readonly asTransact: {2828 readonly originType: XcmV0OriginKind;2829 readonly requireWeightAtMost: u64;2830 readonly call: XcmDoubleEncoded;2831 } & Struct;2832 readonly isHrmpNewChannelOpenRequest: boolean;2833 readonly asHrmpNewChannelOpenRequest: {2834 readonly sender: Compact<u32>;2835 readonly maxMessageSize: Compact<u32>;2836 readonly maxCapacity: Compact<u32>;2837 } & Struct;2838 readonly isHrmpChannelAccepted: boolean;2839 readonly asHrmpChannelAccepted: {2840 readonly recipient: Compact<u32>;2841 } & Struct;2842 readonly isHrmpChannelClosing: boolean;2843 readonly asHrmpChannelClosing: {2844 readonly initiator: Compact<u32>;2845 readonly sender: Compact<u32>;2846 readonly recipient: Compact<u32>;2847 } & Struct;2848 readonly isRelayedFrom: boolean;2849 readonly asRelayedFrom: {2850 readonly who: XcmV0MultiLocation;2851 readonly message: XcmV0Xcm;2852 } & Struct;2853 readonly type: 'WithdrawAsset' | 'ReserveAssetDeposit' | 'TeleportAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom';2854}28552856/** @name XcmV1Junction */2857export interface XcmV1Junction extends Enum {2858 readonly isParachain: boolean;2859 readonly asParachain: Compact<u32>;2860 readonly isAccountId32: boolean;2861 readonly asAccountId32: {2862 readonly network: XcmV0JunctionNetworkId;2863 readonly id: U8aFixed;2864 } & Struct;2865 readonly isAccountIndex64: boolean;2866 readonly asAccountIndex64: {2867 readonly network: XcmV0JunctionNetworkId;2868 readonly index: Compact<u64>;2869 } & Struct;2870 readonly isAccountKey20: boolean;2871 readonly asAccountKey20: {2872 readonly network: XcmV0JunctionNetworkId;2873 readonly key: U8aFixed;2874 } & Struct;2875 readonly isPalletInstance: boolean;2876 readonly asPalletInstance: u8;2877 readonly isGeneralIndex: boolean;2878 readonly asGeneralIndex: Compact<u128>;2879 readonly isGeneralKey: boolean;2880 readonly asGeneralKey: Bytes;2881 readonly isOnlyChild: boolean;2882 readonly isPlurality: boolean;2883 readonly asPlurality: {2884 readonly id: XcmV0JunctionBodyId;2885 readonly part: XcmV0JunctionBodyPart;2886 } & Struct;2887 readonly type: 'Parachain' | 'AccountId32' | 'AccountIndex64' | 'AccountKey20' | 'PalletInstance' | 'GeneralIndex' | 'GeneralKey' | 'OnlyChild' | 'Plurality';2888}28892890/** @name XcmV1MultiAsset */2891export interface XcmV1MultiAsset extends Struct {2892 readonly id: XcmV1MultiassetAssetId;2893 readonly fun: XcmV1MultiassetFungibility;2894}28952896/** @name XcmV1MultiassetAssetId */2897export interface XcmV1MultiassetAssetId extends Enum {2898 readonly isConcrete: boolean;2899 readonly asConcrete: XcmV1MultiLocation;2900 readonly isAbstract: boolean;2901 readonly asAbstract: Bytes;2902 readonly type: 'Concrete' | 'Abstract';2903}29042905/** @name XcmV1MultiassetAssetInstance */2906export interface XcmV1MultiassetAssetInstance extends Enum {2907 readonly isUndefined: boolean;2908 readonly isIndex: boolean;2909 readonly asIndex: Compact<u128>;2910 readonly isArray4: boolean;2911 readonly asArray4: U8aFixed;2912 readonly isArray8: boolean;2913 readonly asArray8: U8aFixed;2914 readonly isArray16: boolean;2915 readonly asArray16: U8aFixed;2916 readonly isArray32: boolean;2917 readonly asArray32: U8aFixed;2918 readonly isBlob: boolean;2919 readonly asBlob: Bytes;2920 readonly type: 'Undefined' | 'Index' | 'Array4' | 'Array8' | 'Array16' | 'Array32' | 'Blob';2921}29222923/** @name XcmV1MultiassetFungibility */2924export interface XcmV1MultiassetFungibility extends Enum {2925 readonly isFungible: boolean;2926 readonly asFungible: Compact<u128>;2927 readonly isNonFungible: boolean;2928 readonly asNonFungible: XcmV1MultiassetAssetInstance;2929 readonly type: 'Fungible' | 'NonFungible';2930}29312932/** @name XcmV1MultiassetMultiAssetFilter */2933export interface XcmV1MultiassetMultiAssetFilter extends Enum {2934 readonly isDefinite: boolean;2935 readonly asDefinite: XcmV1MultiassetMultiAssets;2936 readonly isWild: boolean;2937 readonly asWild: XcmV1MultiassetWildMultiAsset;2938 readonly type: 'Definite' | 'Wild';2939}29402941/** @name XcmV1MultiassetMultiAssets */2942export interface XcmV1MultiassetMultiAssets extends Vec<XcmV1MultiAsset> {}29432944/** @name XcmV1MultiassetWildFungibility */2945export interface XcmV1MultiassetWildFungibility extends Enum {2946 readonly isFungible: boolean;2947 readonly isNonFungible: boolean;2948 readonly type: 'Fungible' | 'NonFungible';2949}29502951/** @name XcmV1MultiassetWildMultiAsset */2952export interface XcmV1MultiassetWildMultiAsset extends Enum {2953 readonly isAll: boolean;2954 readonly isAllOf: boolean;2955 readonly asAllOf: {2956 readonly id: XcmV1MultiassetAssetId;2957 readonly fun: XcmV1MultiassetWildFungibility;2958 } & Struct;2959 readonly type: 'All' | 'AllOf';2960}29612962/** @name XcmV1MultiLocation */2963export interface XcmV1MultiLocation extends Struct {2964 readonly parents: u8;2965 readonly interior: XcmV1MultilocationJunctions;2966}29672968/** @name XcmV1MultilocationJunctions */2969export interface XcmV1MultilocationJunctions extends Enum {2970 readonly isHere: boolean;2971 readonly isX1: boolean;2972 readonly asX1: XcmV1Junction;2973 readonly isX2: boolean;2974 readonly asX2: ITuple<[XcmV1Junction, XcmV1Junction]>;2975 readonly isX3: boolean;2976 readonly asX3: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2977 readonly isX4: boolean;2978 readonly asX4: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2979 readonly isX5: boolean;2980 readonly asX5: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2981 readonly isX6: boolean;2982 readonly asX6: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2983 readonly isX7: boolean;2984 readonly asX7: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2985 readonly isX8: boolean;2986 readonly asX8: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2987 readonly type: 'Here' | 'X1' | 'X2' | 'X3' | 'X4' | 'X5' | 'X6' | 'X7' | 'X8';2988}29892990/** @name XcmV1Order */2991export interface XcmV1Order extends Enum {2992 readonly isNoop: boolean;2993 readonly isDepositAsset: boolean;2994 readonly asDepositAsset: {2995 readonly assets: XcmV1MultiassetMultiAssetFilter;2996 readonly maxAssets: u32;2997 readonly beneficiary: XcmV1MultiLocation;2998 } & Struct;2999 readonly isDepositReserveAsset: boolean;3000 readonly asDepositReserveAsset: {3001 readonly assets: XcmV1MultiassetMultiAssetFilter;3002 readonly maxAssets: u32;3003 readonly dest: XcmV1MultiLocation;3004 readonly effects: Vec<XcmV1Order>;3005 } & Struct;3006 readonly isExchangeAsset: boolean;3007 readonly asExchangeAsset: {3008 readonly give: XcmV1MultiassetMultiAssetFilter;3009 readonly receive: XcmV1MultiassetMultiAssets;3010 } & Struct;3011 readonly isInitiateReserveWithdraw: boolean;3012 readonly asInitiateReserveWithdraw: {3013 readonly assets: XcmV1MultiassetMultiAssetFilter;3014 readonly reserve: XcmV1MultiLocation;3015 readonly effects: Vec<XcmV1Order>;3016 } & Struct;3017 readonly isInitiateTeleport: boolean;3018 readonly asInitiateTeleport: {3019 readonly assets: XcmV1MultiassetMultiAssetFilter;3020 readonly dest: XcmV1MultiLocation;3021 readonly effects: Vec<XcmV1Order>;3022 } & Struct;3023 readonly isQueryHolding: boolean;3024 readonly asQueryHolding: {3025 readonly queryId: Compact<u64>;3026 readonly dest: XcmV1MultiLocation;3027 readonly assets: XcmV1MultiassetMultiAssetFilter;3028 } & Struct;3029 readonly isBuyExecution: boolean;3030 readonly asBuyExecution: {3031 readonly fees: XcmV1MultiAsset;3032 readonly weight: u64;3033 readonly debt: u64;3034 readonly haltOnError: bool;3035 readonly instructions: Vec<XcmV1Xcm>;3036 } & Struct;3037 readonly type: 'Noop' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';3038}30393040/** @name XcmV1Response */3041export interface XcmV1Response extends Enum {3042 readonly isAssets: boolean;3043 readonly asAssets: XcmV1MultiassetMultiAssets;3044 readonly isVersion: boolean;3045 readonly asVersion: u32;3046 readonly type: 'Assets' | 'Version';3047}30483049/** @name XcmV1Xcm */3050export interface XcmV1Xcm extends Enum {3051 readonly isWithdrawAsset: boolean;3052 readonly asWithdrawAsset: {3053 readonly assets: XcmV1MultiassetMultiAssets;3054 readonly effects: Vec<XcmV1Order>;3055 } & Struct;3056 readonly isReserveAssetDeposited: boolean;3057 readonly asReserveAssetDeposited: {3058 readonly assets: XcmV1MultiassetMultiAssets;3059 readonly effects: Vec<XcmV1Order>;3060 } & Struct;3061 readonly isReceiveTeleportedAsset: boolean;3062 readonly asReceiveTeleportedAsset: {3063 readonly assets: XcmV1MultiassetMultiAssets;3064 readonly effects: Vec<XcmV1Order>;3065 } & Struct;3066 readonly isQueryResponse: boolean;3067 readonly asQueryResponse: {3068 readonly queryId: Compact<u64>;3069 readonly response: XcmV1Response;3070 } & Struct;3071 readonly isTransferAsset: boolean;3072 readonly asTransferAsset: {3073 readonly assets: XcmV1MultiassetMultiAssets;3074 readonly beneficiary: XcmV1MultiLocation;3075 } & Struct;3076 readonly isTransferReserveAsset: boolean;3077 readonly asTransferReserveAsset: {3078 readonly assets: XcmV1MultiassetMultiAssets;3079 readonly dest: XcmV1MultiLocation;3080 readonly effects: Vec<XcmV1Order>;3081 } & Struct;3082 readonly isTransact: boolean;3083 readonly asTransact: {3084 readonly originType: XcmV0OriginKind;3085 readonly requireWeightAtMost: u64;3086 readonly call: XcmDoubleEncoded;3087 } & Struct;3088 readonly isHrmpNewChannelOpenRequest: boolean;3089 readonly asHrmpNewChannelOpenRequest: {3090 readonly sender: Compact<u32>;3091 readonly maxMessageSize: Compact<u32>;3092 readonly maxCapacity: Compact<u32>;3093 } & Struct;3094 readonly isHrmpChannelAccepted: boolean;3095 readonly asHrmpChannelAccepted: {3096 readonly recipient: Compact<u32>;3097 } & Struct;3098 readonly isHrmpChannelClosing: boolean;3099 readonly asHrmpChannelClosing: {3100 readonly initiator: Compact<u32>;3101 readonly sender: Compact<u32>;3102 readonly recipient: Compact<u32>;3103 } & Struct;3104 readonly isRelayedFrom: boolean;3105 readonly asRelayedFrom: {3106 readonly who: XcmV1MultilocationJunctions;3107 readonly message: XcmV1Xcm;3108 } & Struct;3109 readonly isSubscribeVersion: boolean;3110 readonly asSubscribeVersion: {3111 readonly queryId: Compact<u64>;3112 readonly maxResponseWeight: Compact<u64>;3113 } & Struct;3114 readonly isUnsubscribeVersion: boolean;3115 readonly type: 'WithdrawAsset' | 'ReserveAssetDeposited' | 'ReceiveTeleportedAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom' | 'SubscribeVersion' | 'UnsubscribeVersion';3116}31173118/** @name XcmV2Instruction */3119export interface XcmV2Instruction extends Enum {3120 readonly isWithdrawAsset: boolean;3121 readonly asWithdrawAsset: XcmV1MultiassetMultiAssets;3122 readonly isReserveAssetDeposited: boolean;3123 readonly asReserveAssetDeposited: XcmV1MultiassetMultiAssets;3124 readonly isReceiveTeleportedAsset: boolean;3125 readonly asReceiveTeleportedAsset: XcmV1MultiassetMultiAssets;3126 readonly isQueryResponse: boolean;3127 readonly asQueryResponse: {3128 readonly queryId: Compact<u64>;3129 readonly response: XcmV2Response;3130 readonly maxWeight: Compact<u64>;3131 } & Struct;3132 readonly isTransferAsset: boolean;3133 readonly asTransferAsset: {3134 readonly assets: XcmV1MultiassetMultiAssets;3135 readonly beneficiary: XcmV1MultiLocation;3136 } & Struct;3137 readonly isTransferReserveAsset: boolean;3138 readonly asTransferReserveAsset: {3139 readonly assets: XcmV1MultiassetMultiAssets;3140 readonly dest: XcmV1MultiLocation;3141 readonly xcm: XcmV2Xcm;3142 } & Struct;3143 readonly isTransact: boolean;3144 readonly asTransact: {3145 readonly originType: XcmV0OriginKind;3146 readonly requireWeightAtMost: Compact<u64>;3147 readonly call: XcmDoubleEncoded;3148 } & Struct;3149 readonly isHrmpNewChannelOpenRequest: boolean;3150 readonly asHrmpNewChannelOpenRequest: {3151 readonly sender: Compact<u32>;3152 readonly maxMessageSize: Compact<u32>;3153 readonly maxCapacity: Compact<u32>;3154 } & Struct;3155 readonly isHrmpChannelAccepted: boolean;3156 readonly asHrmpChannelAccepted: {3157 readonly recipient: Compact<u32>;3158 } & Struct;3159 readonly isHrmpChannelClosing: boolean;3160 readonly asHrmpChannelClosing: {3161 readonly initiator: Compact<u32>;3162 readonly sender: Compact<u32>;3163 readonly recipient: Compact<u32>;3164 } & Struct;3165 readonly isClearOrigin: boolean;3166 readonly isDescendOrigin: boolean;3167 readonly asDescendOrigin: XcmV1MultilocationJunctions;3168 readonly isReportError: boolean;3169 readonly asReportError: {3170 readonly queryId: Compact<u64>;3171 readonly dest: XcmV1MultiLocation;3172 readonly maxResponseWeight: Compact<u64>;3173 } & Struct;3174 readonly isDepositAsset: boolean;3175 readonly asDepositAsset: {3176 readonly assets: XcmV1MultiassetMultiAssetFilter;3177 readonly maxAssets: Compact<u32>;3178 readonly beneficiary: XcmV1MultiLocation;3179 } & Struct;3180 readonly isDepositReserveAsset: boolean;3181 readonly asDepositReserveAsset: {3182 readonly assets: XcmV1MultiassetMultiAssetFilter;3183 readonly maxAssets: Compact<u32>;3184 readonly dest: XcmV1MultiLocation;3185 readonly xcm: XcmV2Xcm;3186 } & Struct;3187 readonly isExchangeAsset: boolean;3188 readonly asExchangeAsset: {3189 readonly give: XcmV1MultiassetMultiAssetFilter;3190 readonly receive: XcmV1MultiassetMultiAssets;3191 } & Struct;3192 readonly isInitiateReserveWithdraw: boolean;3193 readonly asInitiateReserveWithdraw: {3194 readonly assets: XcmV1MultiassetMultiAssetFilter;3195 readonly reserve: XcmV1MultiLocation;3196 readonly xcm: XcmV2Xcm;3197 } & Struct;3198 readonly isInitiateTeleport: boolean;3199 readonly asInitiateTeleport: {3200 readonly assets: XcmV1MultiassetMultiAssetFilter;3201 readonly dest: XcmV1MultiLocation;3202 readonly xcm: XcmV2Xcm;3203 } & Struct;3204 readonly isQueryHolding: boolean;3205 readonly asQueryHolding: {3206 readonly queryId: Compact<u64>;3207 readonly dest: XcmV1MultiLocation;3208 readonly assets: XcmV1MultiassetMultiAssetFilter;3209 readonly maxResponseWeight: Compact<u64>;3210 } & Struct;3211 readonly isBuyExecution: boolean;3212 readonly asBuyExecution: {3213 readonly fees: XcmV1MultiAsset;3214 readonly weightLimit: XcmV2WeightLimit;3215 } & Struct;3216 readonly isRefundSurplus: boolean;3217 readonly isSetErrorHandler: boolean;3218 readonly asSetErrorHandler: XcmV2Xcm;3219 readonly isSetAppendix: boolean;3220 readonly asSetAppendix: XcmV2Xcm;3221 readonly isClearError: boolean;3222 readonly isClaimAsset: boolean;3223 readonly asClaimAsset: {3224 readonly assets: XcmV1MultiassetMultiAssets;3225 readonly ticket: XcmV1MultiLocation;3226 } & Struct;3227 readonly isTrap: boolean;3228 readonly asTrap: Compact<u64>;3229 readonly isSubscribeVersion: boolean;3230 readonly asSubscribeVersion: {3231 readonly queryId: Compact<u64>;3232 readonly maxResponseWeight: Compact<u64>;3233 } & Struct;3234 readonly isUnsubscribeVersion: boolean;3235 readonly type: 'WithdrawAsset' | 'ReserveAssetDeposited' | 'ReceiveTeleportedAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'ClearOrigin' | 'DescendOrigin' | 'ReportError' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution' | 'RefundSurplus' | 'SetErrorHandler' | 'SetAppendix' | 'ClearError' | 'ClaimAsset' | 'Trap' | 'SubscribeVersion' | 'UnsubscribeVersion';3236}32373238/** @name XcmV2Response */3239export interface XcmV2Response extends Enum {3240 readonly isNull: boolean;3241 readonly isAssets: boolean;3242 readonly asAssets: XcmV1MultiassetMultiAssets;3243 readonly isExecutionResult: boolean;3244 readonly asExecutionResult: Option<ITuple<[u32, XcmV2TraitsError]>>;3245 readonly isVersion: boolean;3246 readonly asVersion: u32;3247 readonly type: 'Null' | 'Assets' | 'ExecutionResult' | 'Version';3248}32493250/** @name XcmV2TraitsError */3251export interface XcmV2TraitsError extends Enum {3252 readonly isOverflow: boolean;3253 readonly isUnimplemented: boolean;3254 readonly isUntrustedReserveLocation: boolean;3255 readonly isUntrustedTeleportLocation: boolean;3256 readonly isMultiLocationFull: boolean;3257 readonly isMultiLocationNotInvertible: boolean;3258 readonly isBadOrigin: boolean;3259 readonly isInvalidLocation: boolean;3260 readonly isAssetNotFound: boolean;3261 readonly isFailedToTransactAsset: boolean;3262 readonly isNotWithdrawable: boolean;3263 readonly isLocationCannotHold: boolean;3264 readonly isExceedsMaxMessageSize: boolean;3265 readonly isDestinationUnsupported: boolean;3266 readonly isTransport: boolean;3267 readonly isUnroutable: boolean;3268 readonly isUnknownClaim: boolean;3269 readonly isFailedToDecode: boolean;3270 readonly isMaxWeightInvalid: boolean;3271 readonly isNotHoldingFees: boolean;3272 readonly isTooExpensive: boolean;3273 readonly isTrap: boolean;3274 readonly asTrap: u64;3275 readonly isUnhandledXcmVersion: boolean;3276 readonly isWeightLimitReached: boolean;3277 readonly asWeightLimitReached: u64;3278 readonly isBarrier: boolean;3279 readonly isWeightNotComputable: boolean;3280 readonly type: 'Overflow' | 'Unimplemented' | 'UntrustedReserveLocation' | 'UntrustedTeleportLocation' | 'MultiLocationFull' | 'MultiLocationNotInvertible' | 'BadOrigin' | 'InvalidLocation' | 'AssetNotFound' | 'FailedToTransactAsset' | 'NotWithdrawable' | 'LocationCannotHold' | 'ExceedsMaxMessageSize' | 'DestinationUnsupported' | 'Transport' | 'Unroutable' | 'UnknownClaim' | 'FailedToDecode' | 'MaxWeightInvalid' | 'NotHoldingFees' | 'TooExpensive' | 'Trap' | 'UnhandledXcmVersion' | 'WeightLimitReached' | 'Barrier' | 'WeightNotComputable';3281}32823283/** @name XcmV2TraitsOutcome */3284export interface XcmV2TraitsOutcome extends Enum {3285 readonly isComplete: boolean;3286 readonly asComplete: u64;3287 readonly isIncomplete: boolean;3288 readonly asIncomplete: ITuple<[u64, XcmV2TraitsError]>;3289 readonly isError: boolean;3290 readonly asError: XcmV2TraitsError;3291 readonly type: 'Complete' | 'Incomplete' | 'Error';3292}32933294/** @name XcmV2WeightLimit */3295export interface XcmV2WeightLimit extends Enum {3296 readonly isUnlimited: boolean;3297 readonly isLimited: boolean;3298 readonly asLimited: Compact<u64>;3299 readonly type: 'Unlimited' | 'Limited';3300}33013302/** @name XcmV2Xcm */3303export interface XcmV2Xcm extends Vec<XcmV2Instruction> {}33043305/** @name XcmVersionedMultiAssets */3306export interface XcmVersionedMultiAssets extends Enum {3307 readonly isV0: boolean;3308 readonly asV0: Vec<XcmV0MultiAsset>;3309 readonly isV1: boolean;3310 readonly asV1: XcmV1MultiassetMultiAssets;3311 readonly type: 'V0' | 'V1';3312}33133314/** @name XcmVersionedMultiLocation */3315export interface XcmVersionedMultiLocation extends Enum {3316 readonly isV0: boolean;3317 readonly asV0: XcmV0MultiLocation;3318 readonly isV1: boolean;3319 readonly asV1: XcmV1MultiLocation;3320 readonly type: 'V0' | 'V1';3321}33223323/** @name XcmVersionedXcm */3324export interface XcmVersionedXcm extends Enum {3325 readonly isV0: boolean;3326 readonly asV0: XcmV0Xcm;3327 readonly isV1: boolean;3328 readonly asV1: XcmV1Xcm;3329 readonly isV2: boolean;3330 readonly asV2: XcmV2Xcm;3331 readonly type: 'V0' | 'V1' | 'V2';3332}33333334export type PHANTOM_DEFAULT = 'default';1// Auto-generated via `yarn polkadot-types-from-defs`, do not edit2/* eslint-disable */34import type { BTreeMap, BTreeSet, Bytes, Compact, Enum, Null, Option, Result, Struct, Text, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec';5import type { ITuple } from '@polkadot/types-codec/types';6import type { AccountId32, Call, H160, H256, MultiAddress, Perbill, Permill } from '@polkadot/types/interfaces/runtime';7import type { Event } from '@polkadot/types/interfaces/system';89/** @name CumulusPalletDmpQueueCall */10export interface CumulusPalletDmpQueueCall extends Enum {11 readonly isServiceOverweight: boolean;12 readonly asServiceOverweight: {13 readonly index: u64;14 readonly weightLimit: u64;15 } & Struct;16 readonly type: 'ServiceOverweight';17}1819/** @name CumulusPalletDmpQueueConfigData */20export interface CumulusPalletDmpQueueConfigData extends Struct {21 readonly maxIndividual: u64;22}2324/** @name CumulusPalletDmpQueueError */25export interface CumulusPalletDmpQueueError extends Enum {26 readonly isUnknown: boolean;27 readonly isOverLimit: boolean;28 readonly type: 'Unknown' | 'OverLimit';29}3031/** @name CumulusPalletDmpQueueEvent */32export interface CumulusPalletDmpQueueEvent extends Enum {33 readonly isInvalidFormat: boolean;34 readonly asInvalidFormat: {35 readonly messageId: U8aFixed;36 } & Struct;37 readonly isUnsupportedVersion: boolean;38 readonly asUnsupportedVersion: {39 readonly messageId: U8aFixed;40 } & Struct;41 readonly isExecutedDownward: boolean;42 readonly asExecutedDownward: {43 readonly messageId: U8aFixed;44 readonly outcome: XcmV2TraitsOutcome;45 } & Struct;46 readonly isWeightExhausted: boolean;47 readonly asWeightExhausted: {48 readonly messageId: U8aFixed;49 readonly remainingWeight: u64;50 readonly requiredWeight: u64;51 } & Struct;52 readonly isOverweightEnqueued: boolean;53 readonly asOverweightEnqueued: {54 readonly messageId: U8aFixed;55 readonly overweightIndex: u64;56 readonly requiredWeight: u64;57 } & Struct;58 readonly isOverweightServiced: boolean;59 readonly asOverweightServiced: {60 readonly overweightIndex: u64;61 readonly weightUsed: u64;62 } & Struct;63 readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward' | 'WeightExhausted' | 'OverweightEnqueued' | 'OverweightServiced';64}6566/** @name CumulusPalletDmpQueuePageIndexData */67export interface CumulusPalletDmpQueuePageIndexData extends Struct {68 readonly beginUsed: u32;69 readonly endUsed: u32;70 readonly overweightCount: u64;71}7273/** @name CumulusPalletParachainSystemCall */74export interface CumulusPalletParachainSystemCall extends Enum {75 readonly isSetValidationData: boolean;76 readonly asSetValidationData: {77 readonly data: CumulusPrimitivesParachainInherentParachainInherentData;78 } & Struct;79 readonly isSudoSendUpwardMessage: boolean;80 readonly asSudoSendUpwardMessage: {81 readonly message: Bytes;82 } & Struct;83 readonly isAuthorizeUpgrade: boolean;84 readonly asAuthorizeUpgrade: {85 readonly codeHash: H256;86 } & Struct;87 readonly isEnactAuthorizedUpgrade: boolean;88 readonly asEnactAuthorizedUpgrade: {89 readonly code: Bytes;90 } & Struct;91 readonly type: 'SetValidationData' | 'SudoSendUpwardMessage' | 'AuthorizeUpgrade' | 'EnactAuthorizedUpgrade';92}9394/** @name CumulusPalletParachainSystemError */95export interface CumulusPalletParachainSystemError extends Enum {96 readonly isOverlappingUpgrades: boolean;97 readonly isProhibitedByPolkadot: boolean;98 readonly isTooBig: boolean;99 readonly isValidationDataNotAvailable: boolean;100 readonly isHostConfigurationNotAvailable: boolean;101 readonly isNotScheduled: boolean;102 readonly isNothingAuthorized: boolean;103 readonly isUnauthorized: boolean;104 readonly type: 'OverlappingUpgrades' | 'ProhibitedByPolkadot' | 'TooBig' | 'ValidationDataNotAvailable' | 'HostConfigurationNotAvailable' | 'NotScheduled' | 'NothingAuthorized' | 'Unauthorized';105}106107/** @name CumulusPalletParachainSystemEvent */108export interface CumulusPalletParachainSystemEvent extends Enum {109 readonly isValidationFunctionStored: boolean;110 readonly isValidationFunctionApplied: boolean;111 readonly asValidationFunctionApplied: {112 readonly relayChainBlockNum: u32;113 } & Struct;114 readonly isValidationFunctionDiscarded: boolean;115 readonly isUpgradeAuthorized: boolean;116 readonly asUpgradeAuthorized: {117 readonly codeHash: H256;118 } & Struct;119 readonly isDownwardMessagesReceived: boolean;120 readonly asDownwardMessagesReceived: {121 readonly count: u32;122 } & Struct;123 readonly isDownwardMessagesProcessed: boolean;124 readonly asDownwardMessagesProcessed: {125 readonly weightUsed: u64;126 readonly dmqHead: H256;127 } & Struct;128 readonly type: 'ValidationFunctionStored' | 'ValidationFunctionApplied' | 'ValidationFunctionDiscarded' | 'UpgradeAuthorized' | 'DownwardMessagesReceived' | 'DownwardMessagesProcessed';129}130131/** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot */132export interface CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot extends Struct {133 readonly dmqMqcHead: H256;134 readonly relayDispatchQueueSize: ITuple<[u32, u32]>;135 readonly ingressChannels: Vec<ITuple<[u32, PolkadotPrimitivesV2AbridgedHrmpChannel]>>;136 readonly egressChannels: Vec<ITuple<[u32, PolkadotPrimitivesV2AbridgedHrmpChannel]>>;137}138139/** @name CumulusPalletXcmCall */140export interface CumulusPalletXcmCall extends Null {}141142/** @name CumulusPalletXcmError */143export interface CumulusPalletXcmError extends Null {}144145/** @name CumulusPalletXcmEvent */146export interface CumulusPalletXcmEvent extends Enum {147 readonly isInvalidFormat: boolean;148 readonly asInvalidFormat: U8aFixed;149 readonly isUnsupportedVersion: boolean;150 readonly asUnsupportedVersion: U8aFixed;151 readonly isExecutedDownward: boolean;152 readonly asExecutedDownward: ITuple<[U8aFixed, XcmV2TraitsOutcome]>;153 readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward';154}155156/** @name CumulusPalletXcmOrigin */157export interface CumulusPalletXcmOrigin extends Enum {158 readonly isRelay: boolean;159 readonly isSiblingParachain: boolean;160 readonly asSiblingParachain: u32;161 readonly type: 'Relay' | 'SiblingParachain';162}163164/** @name CumulusPalletXcmpQueueCall */165export interface CumulusPalletXcmpQueueCall extends Enum {166 readonly isServiceOverweight: boolean;167 readonly asServiceOverweight: {168 readonly index: u64;169 readonly weightLimit: u64;170 } & Struct;171 readonly isSuspendXcmExecution: boolean;172 readonly isResumeXcmExecution: boolean;173 readonly isUpdateSuspendThreshold: boolean;174 readonly asUpdateSuspendThreshold: {175 readonly new_: u32;176 } & Struct;177 readonly isUpdateDropThreshold: boolean;178 readonly asUpdateDropThreshold: {179 readonly new_: u32;180 } & Struct;181 readonly isUpdateResumeThreshold: boolean;182 readonly asUpdateResumeThreshold: {183 readonly new_: u32;184 } & Struct;185 readonly isUpdateThresholdWeight: boolean;186 readonly asUpdateThresholdWeight: {187 readonly new_: u64;188 } & Struct;189 readonly isUpdateWeightRestrictDecay: boolean;190 readonly asUpdateWeightRestrictDecay: {191 readonly new_: u64;192 } & Struct;193 readonly isUpdateXcmpMaxIndividualWeight: boolean;194 readonly asUpdateXcmpMaxIndividualWeight: {195 readonly new_: u64;196 } & Struct;197 readonly type: 'ServiceOverweight' | 'SuspendXcmExecution' | 'ResumeXcmExecution' | 'UpdateSuspendThreshold' | 'UpdateDropThreshold' | 'UpdateResumeThreshold' | 'UpdateThresholdWeight' | 'UpdateWeightRestrictDecay' | 'UpdateXcmpMaxIndividualWeight';198}199200/** @name CumulusPalletXcmpQueueError */201export interface CumulusPalletXcmpQueueError extends Enum {202 readonly isFailedToSend: boolean;203 readonly isBadXcmOrigin: boolean;204 readonly isBadXcm: boolean;205 readonly isBadOverweightIndex: boolean;206 readonly isWeightOverLimit: boolean;207 readonly type: 'FailedToSend' | 'BadXcmOrigin' | 'BadXcm' | 'BadOverweightIndex' | 'WeightOverLimit';208}209210/** @name CumulusPalletXcmpQueueEvent */211export interface CumulusPalletXcmpQueueEvent extends Enum {212 readonly isSuccess: boolean;213 readonly asSuccess: Option<H256>;214 readonly isFail: boolean;215 readonly asFail: ITuple<[Option<H256>, XcmV2TraitsError]>;216 readonly isBadVersion: boolean;217 readonly asBadVersion: Option<H256>;218 readonly isBadFormat: boolean;219 readonly asBadFormat: Option<H256>;220 readonly isUpwardMessageSent: boolean;221 readonly asUpwardMessageSent: Option<H256>;222 readonly isXcmpMessageSent: boolean;223 readonly asXcmpMessageSent: Option<H256>;224 readonly isOverweightEnqueued: boolean;225 readonly asOverweightEnqueued: ITuple<[u32, u32, u64, u64]>;226 readonly isOverweightServiced: boolean;227 readonly asOverweightServiced: ITuple<[u64, u64]>;228 readonly type: 'Success' | 'Fail' | 'BadVersion' | 'BadFormat' | 'UpwardMessageSent' | 'XcmpMessageSent' | 'OverweightEnqueued' | 'OverweightServiced';229}230231/** @name CumulusPalletXcmpQueueInboundChannelDetails */232export interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct {233 readonly sender: u32;234 readonly state: CumulusPalletXcmpQueueInboundState;235 readonly messageMetadata: Vec<ITuple<[u32, PolkadotParachainPrimitivesXcmpMessageFormat]>>;236}237238/** @name CumulusPalletXcmpQueueInboundState */239export interface CumulusPalletXcmpQueueInboundState extends Enum {240 readonly isOk: boolean;241 readonly isSuspended: boolean;242 readonly type: 'Ok' | 'Suspended';243}244245/** @name CumulusPalletXcmpQueueOutboundChannelDetails */246export interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct {247 readonly recipient: u32;248 readonly state: CumulusPalletXcmpQueueOutboundState;249 readonly signalsExist: bool;250 readonly firstIndex: u16;251 readonly lastIndex: u16;252}253254/** @name CumulusPalletXcmpQueueOutboundState */255export interface CumulusPalletXcmpQueueOutboundState extends Enum {256 readonly isOk: boolean;257 readonly isSuspended: boolean;258 readonly type: 'Ok' | 'Suspended';259}260261/** @name CumulusPalletXcmpQueueQueueConfigData */262export interface CumulusPalletXcmpQueueQueueConfigData extends Struct {263 readonly suspendThreshold: u32;264 readonly dropThreshold: u32;265 readonly resumeThreshold: u32;266 readonly thresholdWeight: u64;267 readonly weightRestrictDecay: u64;268 readonly xcmpMaxIndividualWeight: u64;269}270271/** @name CumulusPrimitivesParachainInherentParachainInherentData */272export interface CumulusPrimitivesParachainInherentParachainInherentData extends Struct {273 readonly validationData: PolkadotPrimitivesV2PersistedValidationData;274 readonly relayChainState: SpTrieStorageProof;275 readonly downwardMessages: Vec<PolkadotCorePrimitivesInboundDownwardMessage>;276 readonly horizontalMessages: BTreeMap<u32, Vec<PolkadotCorePrimitivesInboundHrmpMessage>>;277}278279/** @name EthbloomBloom */280export interface EthbloomBloom extends U8aFixed {}281282/** @name EthereumBlock */283export interface EthereumBlock extends Struct {284 readonly header: EthereumHeader;285 readonly transactions: Vec<EthereumTransactionTransactionV2>;286 readonly ommers: Vec<EthereumHeader>;287}288289/** @name EthereumHeader */290export interface EthereumHeader extends Struct {291 readonly parentHash: H256;292 readonly ommersHash: H256;293 readonly beneficiary: H160;294 readonly stateRoot: H256;295 readonly transactionsRoot: H256;296 readonly receiptsRoot: H256;297 readonly logsBloom: EthbloomBloom;298 readonly difficulty: U256;299 readonly number: U256;300 readonly gasLimit: U256;301 readonly gasUsed: U256;302 readonly timestamp: u64;303 readonly extraData: Bytes;304 readonly mixHash: H256;305 readonly nonce: EthereumTypesHashH64;306}307308/** @name EthereumLog */309export interface EthereumLog extends Struct {310 readonly address: H160;311 readonly topics: Vec<H256>;312 readonly data: Bytes;313}314315/** @name EthereumReceiptEip658ReceiptData */316export interface EthereumReceiptEip658ReceiptData extends Struct {317 readonly statusCode: u8;318 readonly usedGas: U256;319 readonly logsBloom: EthbloomBloom;320 readonly logs: Vec<EthereumLog>;321}322323/** @name EthereumReceiptReceiptV3 */324export interface EthereumReceiptReceiptV3 extends Enum {325 readonly isLegacy: boolean;326 readonly asLegacy: EthereumReceiptEip658ReceiptData;327 readonly isEip2930: boolean;328 readonly asEip2930: EthereumReceiptEip658ReceiptData;329 readonly isEip1559: boolean;330 readonly asEip1559: EthereumReceiptEip658ReceiptData;331 readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';332}333334/** @name EthereumTransactionAccessListItem */335export interface EthereumTransactionAccessListItem extends Struct {336 readonly address: H160;337 readonly storageKeys: Vec<H256>;338}339340/** @name EthereumTransactionEip1559Transaction */341export interface EthereumTransactionEip1559Transaction extends Struct {342 readonly chainId: u64;343 readonly nonce: U256;344 readonly maxPriorityFeePerGas: U256;345 readonly maxFeePerGas: U256;346 readonly gasLimit: U256;347 readonly action: EthereumTransactionTransactionAction;348 readonly value: U256;349 readonly input: Bytes;350 readonly accessList: Vec<EthereumTransactionAccessListItem>;351 readonly oddYParity: bool;352 readonly r: H256;353 readonly s: H256;354}355356/** @name EthereumTransactionEip2930Transaction */357export interface EthereumTransactionEip2930Transaction extends Struct {358 readonly chainId: u64;359 readonly nonce: U256;360 readonly gasPrice: U256;361 readonly gasLimit: U256;362 readonly action: EthereumTransactionTransactionAction;363 readonly value: U256;364 readonly input: Bytes;365 readonly accessList: Vec<EthereumTransactionAccessListItem>;366 readonly oddYParity: bool;367 readonly r: H256;368 readonly s: H256;369}370371/** @name EthereumTransactionLegacyTransaction */372export interface EthereumTransactionLegacyTransaction extends Struct {373 readonly nonce: U256;374 readonly gasPrice: U256;375 readonly gasLimit: U256;376 readonly action: EthereumTransactionTransactionAction;377 readonly value: U256;378 readonly input: Bytes;379 readonly signature: EthereumTransactionTransactionSignature;380}381382/** @name EthereumTransactionTransactionAction */383export interface EthereumTransactionTransactionAction extends Enum {384 readonly isCall: boolean;385 readonly asCall: H160;386 readonly isCreate: boolean;387 readonly type: 'Call' | 'Create';388}389390/** @name EthereumTransactionTransactionSignature */391export interface EthereumTransactionTransactionSignature extends Struct {392 readonly v: u64;393 readonly r: H256;394 readonly s: H256;395}396397/** @name EthereumTransactionTransactionV2 */398export interface EthereumTransactionTransactionV2 extends Enum {399 readonly isLegacy: boolean;400 readonly asLegacy: EthereumTransactionLegacyTransaction;401 readonly isEip2930: boolean;402 readonly asEip2930: EthereumTransactionEip2930Transaction;403 readonly isEip1559: boolean;404 readonly asEip1559: EthereumTransactionEip1559Transaction;405 readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';406}407408/** @name EthereumTypesHashH64 */409export interface EthereumTypesHashH64 extends U8aFixed {}410411/** @name EvmCoreErrorExitError */412export interface EvmCoreErrorExitError extends Enum {413 readonly isStackUnderflow: boolean;414 readonly isStackOverflow: boolean;415 readonly isInvalidJump: boolean;416 readonly isInvalidRange: boolean;417 readonly isDesignatedInvalid: boolean;418 readonly isCallTooDeep: boolean;419 readonly isCreateCollision: boolean;420 readonly isCreateContractLimit: boolean;421 readonly isOutOfOffset: boolean;422 readonly isOutOfGas: boolean;423 readonly isOutOfFund: boolean;424 readonly isPcUnderflow: boolean;425 readonly isCreateEmpty: boolean;426 readonly isOther: boolean;427 readonly asOther: Text;428 readonly isInvalidCode: boolean;429 readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other' | 'InvalidCode';430}431432/** @name EvmCoreErrorExitFatal */433export interface EvmCoreErrorExitFatal extends Enum {434 readonly isNotSupported: boolean;435 readonly isUnhandledInterrupt: boolean;436 readonly isCallErrorAsFatal: boolean;437 readonly asCallErrorAsFatal: EvmCoreErrorExitError;438 readonly isOther: boolean;439 readonly asOther: Text;440 readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';441}442443/** @name EvmCoreErrorExitReason */444export interface EvmCoreErrorExitReason extends Enum {445 readonly isSucceed: boolean;446 readonly asSucceed: EvmCoreErrorExitSucceed;447 readonly isError: boolean;448 readonly asError: EvmCoreErrorExitError;449 readonly isRevert: boolean;450 readonly asRevert: EvmCoreErrorExitRevert;451 readonly isFatal: boolean;452 readonly asFatal: EvmCoreErrorExitFatal;453 readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';454}455456/** @name EvmCoreErrorExitRevert */457export interface EvmCoreErrorExitRevert extends Enum {458 readonly isReverted: boolean;459 readonly type: 'Reverted';460}461462/** @name EvmCoreErrorExitSucceed */463export interface EvmCoreErrorExitSucceed extends Enum {464 readonly isStopped: boolean;465 readonly isReturned: boolean;466 readonly isSuicided: boolean;467 readonly type: 'Stopped' | 'Returned' | 'Suicided';468}469470/** @name FpRpcTransactionStatus */471export interface FpRpcTransactionStatus extends Struct {472 readonly transactionHash: H256;473 readonly transactionIndex: u32;474 readonly from: H160;475 readonly to: Option<H160>;476 readonly contractAddress: Option<H160>;477 readonly logs: Vec<EthereumLog>;478 readonly logsBloom: EthbloomBloom;479}480481/** @name FrameSupportDispatchRawOrigin */482export interface FrameSupportDispatchRawOrigin extends Enum {483 readonly isRoot: boolean;484 readonly isSigned: boolean;485 readonly asSigned: AccountId32;486 readonly isNone: boolean;487 readonly type: 'Root' | 'Signed' | 'None';488}489490/** @name FrameSupportPalletId */491export interface FrameSupportPalletId extends U8aFixed {}492493/** @name FrameSupportScheduleLookupError */494export interface FrameSupportScheduleLookupError extends Enum {495 readonly isUnknown: boolean;496 readonly isBadFormat: boolean;497 readonly type: 'Unknown' | 'BadFormat';498}499500/** @name FrameSupportScheduleMaybeHashed */501export interface FrameSupportScheduleMaybeHashed extends Enum {502 readonly isValue: boolean;503 readonly asValue: Call;504 readonly isHash: boolean;505 readonly asHash: H256;506 readonly type: 'Value' | 'Hash';507}508509/** @name FrameSupportTokensMiscBalanceStatus */510export interface FrameSupportTokensMiscBalanceStatus extends Enum {511 readonly isFree: boolean;512 readonly isReserved: boolean;513 readonly type: 'Free' | 'Reserved';514}515516/** @name FrameSupportWeightsDispatchClass */517export interface FrameSupportWeightsDispatchClass extends Enum {518 readonly isNormal: boolean;519 readonly isOperational: boolean;520 readonly isMandatory: boolean;521 readonly type: 'Normal' | 'Operational' | 'Mandatory';522}523524/** @name FrameSupportWeightsDispatchInfo */525export interface FrameSupportWeightsDispatchInfo extends Struct {526 readonly weight: u64;527 readonly class: FrameSupportWeightsDispatchClass;528 readonly paysFee: FrameSupportWeightsPays;529}530531/** @name FrameSupportWeightsPays */532export interface FrameSupportWeightsPays extends Enum {533 readonly isYes: boolean;534 readonly isNo: boolean;535 readonly type: 'Yes' | 'No';536}537538/** @name FrameSupportWeightsPerDispatchClassU32 */539export interface FrameSupportWeightsPerDispatchClassU32 extends Struct {540 readonly normal: u32;541 readonly operational: u32;542 readonly mandatory: u32;543}544545/** @name FrameSupportWeightsPerDispatchClassU64 */546export interface FrameSupportWeightsPerDispatchClassU64 extends Struct {547 readonly normal: u64;548 readonly operational: u64;549 readonly mandatory: u64;550}551552/** @name FrameSupportWeightsPerDispatchClassWeightsPerClass */553export interface FrameSupportWeightsPerDispatchClassWeightsPerClass extends Struct {554 readonly normal: FrameSystemLimitsWeightsPerClass;555 readonly operational: FrameSystemLimitsWeightsPerClass;556 readonly mandatory: FrameSystemLimitsWeightsPerClass;557}558559/** @name FrameSupportWeightsRuntimeDbWeight */560export interface FrameSupportWeightsRuntimeDbWeight extends Struct {561 readonly read: u64;562 readonly write: u64;563}564565/** @name FrameSystemAccountInfo */566export interface FrameSystemAccountInfo extends Struct {567 readonly nonce: u32;568 readonly consumers: u32;569 readonly providers: u32;570 readonly sufficients: u32;571 readonly data: PalletBalancesAccountData;572}573574/** @name FrameSystemCall */575export interface FrameSystemCall extends Enum {576 readonly isFillBlock: boolean;577 readonly asFillBlock: {578 readonly ratio: Perbill;579 } & Struct;580 readonly isRemark: boolean;581 readonly asRemark: {582 readonly remark: Bytes;583 } & Struct;584 readonly isSetHeapPages: boolean;585 readonly asSetHeapPages: {586 readonly pages: u64;587 } & Struct;588 readonly isSetCode: boolean;589 readonly asSetCode: {590 readonly code: Bytes;591 } & Struct;592 readonly isSetCodeWithoutChecks: boolean;593 readonly asSetCodeWithoutChecks: {594 readonly code: Bytes;595 } & Struct;596 readonly isSetStorage: boolean;597 readonly asSetStorage: {598 readonly items: Vec<ITuple<[Bytes, Bytes]>>;599 } & Struct;600 readonly isKillStorage: boolean;601 readonly asKillStorage: {602 readonly keys_: Vec<Bytes>;603 } & Struct;604 readonly isKillPrefix: boolean;605 readonly asKillPrefix: {606 readonly prefix: Bytes;607 readonly subkeys: u32;608 } & Struct;609 readonly isRemarkWithEvent: boolean;610 readonly asRemarkWithEvent: {611 readonly remark: Bytes;612 } & Struct;613 readonly type: 'FillBlock' | 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent';614}615616/** @name FrameSystemError */617export interface FrameSystemError extends Enum {618 readonly isInvalidSpecName: boolean;619 readonly isSpecVersionNeedsToIncrease: boolean;620 readonly isFailedToExtractRuntimeVersion: boolean;621 readonly isNonDefaultComposite: boolean;622 readonly isNonZeroRefCount: boolean;623 readonly isCallFiltered: boolean;624 readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';625}626627/** @name FrameSystemEvent */628export interface FrameSystemEvent extends Enum {629 readonly isExtrinsicSuccess: boolean;630 readonly asExtrinsicSuccess: {631 readonly dispatchInfo: FrameSupportWeightsDispatchInfo;632 } & Struct;633 readonly isExtrinsicFailed: boolean;634 readonly asExtrinsicFailed: {635 readonly dispatchError: SpRuntimeDispatchError;636 readonly dispatchInfo: FrameSupportWeightsDispatchInfo;637 } & Struct;638 readonly isCodeUpdated: boolean;639 readonly isNewAccount: boolean;640 readonly asNewAccount: {641 readonly account: AccountId32;642 } & Struct;643 readonly isKilledAccount: boolean;644 readonly asKilledAccount: {645 readonly account: AccountId32;646 } & Struct;647 readonly isRemarked: boolean;648 readonly asRemarked: {649 readonly sender: AccountId32;650 readonly hash_: H256;651 } & Struct;652 readonly type: 'ExtrinsicSuccess' | 'ExtrinsicFailed' | 'CodeUpdated' | 'NewAccount' | 'KilledAccount' | 'Remarked';653}654655/** @name FrameSystemEventRecord */656export interface FrameSystemEventRecord extends Struct {657 readonly phase: FrameSystemPhase;658 readonly event: Event;659 readonly topics: Vec<H256>;660}661662/** @name FrameSystemExtensionsCheckGenesis */663export interface FrameSystemExtensionsCheckGenesis extends Null {}664665/** @name FrameSystemExtensionsCheckNonce */666export interface FrameSystemExtensionsCheckNonce extends Compact<u32> {}667668/** @name FrameSystemExtensionsCheckSpecVersion */669export interface FrameSystemExtensionsCheckSpecVersion extends Null {}670671/** @name FrameSystemExtensionsCheckWeight */672export interface FrameSystemExtensionsCheckWeight extends Null {}673674/** @name FrameSystemLastRuntimeUpgradeInfo */675export interface FrameSystemLastRuntimeUpgradeInfo extends Struct {676 readonly specVersion: Compact<u32>;677 readonly specName: Text;678}679680/** @name FrameSystemLimitsBlockLength */681export interface FrameSystemLimitsBlockLength extends Struct {682 readonly max: FrameSupportWeightsPerDispatchClassU32;683}684685/** @name FrameSystemLimitsBlockWeights */686export interface FrameSystemLimitsBlockWeights extends Struct {687 readonly baseBlock: u64;688 readonly maxBlock: u64;689 readonly perClass: FrameSupportWeightsPerDispatchClassWeightsPerClass;690}691692/** @name FrameSystemLimitsWeightsPerClass */693export interface FrameSystemLimitsWeightsPerClass extends Struct {694 readonly baseExtrinsic: u64;695 readonly maxExtrinsic: Option<u64>;696 readonly maxTotal: Option<u64>;697 readonly reserved: Option<u64>;698}699700/** @name FrameSystemPhase */701export interface FrameSystemPhase extends Enum {702 readonly isApplyExtrinsic: boolean;703 readonly asApplyExtrinsic: u32;704 readonly isFinalization: boolean;705 readonly isInitialization: boolean;706 readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';707}708709/** @name OpalRuntimeOriginCaller */710export interface OpalRuntimeOriginCaller extends Enum {711 readonly isVoid: boolean;712 readonly asVoid: SpCoreVoid;713 readonly isSystem: boolean;714 readonly asSystem: FrameSupportDispatchRawOrigin;715 readonly isPolkadotXcm: boolean;716 readonly asPolkadotXcm: PalletXcmOrigin;717 readonly isCumulusXcm: boolean;718 readonly asCumulusXcm: CumulusPalletXcmOrigin;719 readonly isEthereum: boolean;720 readonly asEthereum: PalletEthereumRawOrigin;721 readonly type: 'Void' | 'System' | 'PolkadotXcm' | 'CumulusXcm' | 'Ethereum';722}723724/** @name OpalRuntimeRuntime */725export interface OpalRuntimeRuntime extends Null {}726727/** @name OrmlVestingModuleCall */728export interface OrmlVestingModuleCall extends Enum {729 readonly isClaim: boolean;730 readonly isVestedTransfer: boolean;731 readonly asVestedTransfer: {732 readonly dest: MultiAddress;733 readonly schedule: OrmlVestingVestingSchedule;734 } & Struct;735 readonly isUpdateVestingSchedules: boolean;736 readonly asUpdateVestingSchedules: {737 readonly who: MultiAddress;738 readonly vestingSchedules: Vec<OrmlVestingVestingSchedule>;739 } & Struct;740 readonly isClaimFor: boolean;741 readonly asClaimFor: {742 readonly dest: MultiAddress;743 } & Struct;744 readonly type: 'Claim' | 'VestedTransfer' | 'UpdateVestingSchedules' | 'ClaimFor';745}746747/** @name OrmlVestingModuleError */748export interface OrmlVestingModuleError extends Enum {749 readonly isZeroVestingPeriod: boolean;750 readonly isZeroVestingPeriodCount: boolean;751 readonly isInsufficientBalanceToLock: boolean;752 readonly isTooManyVestingSchedules: boolean;753 readonly isAmountLow: boolean;754 readonly isMaxVestingSchedulesExceeded: boolean;755 readonly type: 'ZeroVestingPeriod' | 'ZeroVestingPeriodCount' | 'InsufficientBalanceToLock' | 'TooManyVestingSchedules' | 'AmountLow' | 'MaxVestingSchedulesExceeded';756}757758/** @name OrmlVestingModuleEvent */759export interface OrmlVestingModuleEvent extends Enum {760 readonly isVestingScheduleAdded: boolean;761 readonly asVestingScheduleAdded: {762 readonly from: AccountId32;763 readonly to: AccountId32;764 readonly vestingSchedule: OrmlVestingVestingSchedule;765 } & Struct;766 readonly isClaimed: boolean;767 readonly asClaimed: {768 readonly who: AccountId32;769 readonly amount: u128;770 } & Struct;771 readonly isVestingSchedulesUpdated: boolean;772 readonly asVestingSchedulesUpdated: {773 readonly who: AccountId32;774 } & Struct;775 readonly type: 'VestingScheduleAdded' | 'Claimed' | 'VestingSchedulesUpdated';776}777778/** @name OrmlVestingVestingSchedule */779export interface OrmlVestingVestingSchedule extends Struct {780 readonly start: u32;781 readonly period: u32;782 readonly periodCount: u32;783 readonly perPeriod: Compact<u128>;784}785786/** @name PalletBalancesAccountData */787export interface PalletBalancesAccountData extends Struct {788 readonly free: u128;789 readonly reserved: u128;790 readonly miscFrozen: u128;791 readonly feeFrozen: u128;792}793794/** @name PalletBalancesBalanceLock */795export interface PalletBalancesBalanceLock extends Struct {796 readonly id: U8aFixed;797 readonly amount: u128;798 readonly reasons: PalletBalancesReasons;799}800801/** @name PalletBalancesCall */802export interface PalletBalancesCall extends Enum {803 readonly isTransfer: boolean;804 readonly asTransfer: {805 readonly dest: MultiAddress;806 readonly value: Compact<u128>;807 } & Struct;808 readonly isSetBalance: boolean;809 readonly asSetBalance: {810 readonly who: MultiAddress;811 readonly newFree: Compact<u128>;812 readonly newReserved: Compact<u128>;813 } & Struct;814 readonly isForceTransfer: boolean;815 readonly asForceTransfer: {816 readonly source: MultiAddress;817 readonly dest: MultiAddress;818 readonly value: Compact<u128>;819 } & Struct;820 readonly isTransferKeepAlive: boolean;821 readonly asTransferKeepAlive: {822 readonly dest: MultiAddress;823 readonly value: Compact<u128>;824 } & Struct;825 readonly isTransferAll: boolean;826 readonly asTransferAll: {827 readonly dest: MultiAddress;828 readonly keepAlive: bool;829 } & Struct;830 readonly isForceUnreserve: boolean;831 readonly asForceUnreserve: {832 readonly who: MultiAddress;833 readonly amount: u128;834 } & Struct;835 readonly type: 'Transfer' | 'SetBalance' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve';836}837838/** @name PalletBalancesError */839export interface PalletBalancesError extends Enum {840 readonly isVestingBalance: boolean;841 readonly isLiquidityRestrictions: boolean;842 readonly isInsufficientBalance: boolean;843 readonly isExistentialDeposit: boolean;844 readonly isKeepAlive: boolean;845 readonly isExistingVestingSchedule: boolean;846 readonly isDeadAccount: boolean;847 readonly isTooManyReserves: boolean;848 readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'KeepAlive' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves';849}850851/** @name PalletBalancesEvent */852export interface PalletBalancesEvent extends Enum {853 readonly isEndowed: boolean;854 readonly asEndowed: {855 readonly account: AccountId32;856 readonly freeBalance: u128;857 } & Struct;858 readonly isDustLost: boolean;859 readonly asDustLost: {860 readonly account: AccountId32;861 readonly amount: u128;862 } & Struct;863 readonly isTransfer: boolean;864 readonly asTransfer: {865 readonly from: AccountId32;866 readonly to: AccountId32;867 readonly amount: u128;868 } & Struct;869 readonly isBalanceSet: boolean;870 readonly asBalanceSet: {871 readonly who: AccountId32;872 readonly free: u128;873 readonly reserved: u128;874 } & Struct;875 readonly isReserved: boolean;876 readonly asReserved: {877 readonly who: AccountId32;878 readonly amount: u128;879 } & Struct;880 readonly isUnreserved: boolean;881 readonly asUnreserved: {882 readonly who: AccountId32;883 readonly amount: u128;884 } & Struct;885 readonly isReserveRepatriated: boolean;886 readonly asReserveRepatriated: {887 readonly from: AccountId32;888 readonly to: AccountId32;889 readonly amount: u128;890 readonly destinationStatus: FrameSupportTokensMiscBalanceStatus;891 } & Struct;892 readonly isDeposit: boolean;893 readonly asDeposit: {894 readonly who: AccountId32;895 readonly amount: u128;896 } & Struct;897 readonly isWithdraw: boolean;898 readonly asWithdraw: {899 readonly who: AccountId32;900 readonly amount: u128;901 } & Struct;902 readonly isSlashed: boolean;903 readonly asSlashed: {904 readonly who: AccountId32;905 readonly amount: u128;906 } & Struct;907 readonly type: 'Endowed' | 'DustLost' | 'Transfer' | 'BalanceSet' | 'Reserved' | 'Unreserved' | 'ReserveRepatriated' | 'Deposit' | 'Withdraw' | 'Slashed';908}909910/** @name PalletBalancesReasons */911export interface PalletBalancesReasons extends Enum {912 readonly isFee: boolean;913 readonly isMisc: boolean;914 readonly isAll: boolean;915 readonly type: 'Fee' | 'Misc' | 'All';916}917918/** @name PalletBalancesReleases */919export interface PalletBalancesReleases extends Enum {920 readonly isV100: boolean;921 readonly isV200: boolean;922 readonly type: 'V100' | 'V200';923}924925/** @name PalletBalancesReserveData */926export interface PalletBalancesReserveData extends Struct {927 readonly id: U8aFixed;928 readonly amount: u128;929}930931/** @name PalletCommonError */932export interface PalletCommonError extends Enum {933 readonly isCollectionNotFound: boolean;934 readonly isMustBeTokenOwner: boolean;935 readonly isNoPermission: boolean;936 readonly isCantDestroyNotEmptyCollection: boolean;937 readonly isPublicMintingNotAllowed: boolean;938 readonly isAddressNotInAllowlist: boolean;939 readonly isCollectionNameLimitExceeded: boolean;940 readonly isCollectionDescriptionLimitExceeded: boolean;941 readonly isCollectionTokenPrefixLimitExceeded: boolean;942 readonly isTotalCollectionsLimitExceeded: boolean;943 readonly isCollectionAdminCountExceeded: boolean;944 readonly isCollectionLimitBoundsExceeded: boolean;945 readonly isOwnerPermissionsCantBeReverted: boolean;946 readonly isTransferNotAllowed: boolean;947 readonly isAccountTokenLimitExceeded: boolean;948 readonly isCollectionTokenLimitExceeded: boolean;949 readonly isMetadataFlagFrozen: boolean;950 readonly isTokenNotFound: boolean;951 readonly isTokenValueTooLow: boolean;952 readonly isApprovedValueTooLow: boolean;953 readonly isCantApproveMoreThanOwned: boolean;954 readonly isAddressIsZero: boolean;955 readonly isUnsupportedOperation: boolean;956 readonly isNotSufficientFounds: boolean;957 readonly isUserIsNotAllowedToNest: boolean;958 readonly isSourceCollectionIsNotAllowedToNest: boolean;959 readonly isCollectionFieldSizeExceeded: boolean;960 readonly isNoSpaceForProperty: boolean;961 readonly isPropertyLimitReached: boolean;962 readonly isPropertyKeyIsTooLong: boolean;963 readonly isInvalidCharacterInPropertyKey: boolean;964 readonly isEmptyPropertyKey: boolean;965 readonly isCollectionIsExternal: boolean;966 readonly isCollectionIsInternal: boolean;967 readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'CantDestroyNotEmptyCollection' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'UserIsNotAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey' | 'CollectionIsExternal' | 'CollectionIsInternal';968}969970/** @name PalletCommonEvent */971export interface PalletCommonEvent extends Enum {972 readonly isCollectionCreated: boolean;973 readonly asCollectionCreated: ITuple<[u32, u8, AccountId32]>;974 readonly isCollectionDestroyed: boolean;975 readonly asCollectionDestroyed: u32;976 readonly isItemCreated: boolean;977 readonly asItemCreated: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;978 readonly isItemDestroyed: boolean;979 readonly asItemDestroyed: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;980 readonly isTransfer: boolean;981 readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;982 readonly isApproved: boolean;983 readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;984 readonly isCollectionPropertySet: boolean;985 readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;986 readonly isCollectionPropertyDeleted: boolean;987 readonly asCollectionPropertyDeleted: ITuple<[u32, Bytes]>;988 readonly isTokenPropertySet: boolean;989 readonly asTokenPropertySet: ITuple<[u32, u32, Bytes]>;990 readonly isTokenPropertyDeleted: boolean;991 readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;992 readonly isPropertyPermissionSet: boolean;993 readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;994 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';995}996997/** @name PalletEthereumCall */998export interface PalletEthereumCall extends Enum {999 readonly isTransact: boolean;1000 readonly asTransact: {1001 readonly transaction: EthereumTransactionTransactionV2;1002 } & Struct;1003 readonly type: 'Transact';1004}10051006/** @name PalletEthereumError */1007export interface PalletEthereumError extends Enum {1008 readonly isInvalidSignature: boolean;1009 readonly isPreLogExists: boolean;1010 readonly type: 'InvalidSignature' | 'PreLogExists';1011}10121013/** @name PalletEthereumEvent */1014export interface PalletEthereumEvent extends Enum {1015 readonly isExecuted: boolean;1016 readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;1017 readonly type: 'Executed';1018}10191020/** @name PalletEthereumFakeTransactionFinalizer */1021export interface PalletEthereumFakeTransactionFinalizer extends Null {}10221023/** @name PalletEthereumRawOrigin */1024export interface PalletEthereumRawOrigin extends Enum {1025 readonly isEthereumTransaction: boolean;1026 readonly asEthereumTransaction: H160;1027 readonly type: 'EthereumTransaction';1028}10291030/** @name PalletEvmAccountBasicCrossAccountIdRepr */1031export interface PalletEvmAccountBasicCrossAccountIdRepr extends Enum {1032 readonly isSubstrate: boolean;1033 readonly asSubstrate: AccountId32;1034 readonly isEthereum: boolean;1035 readonly asEthereum: H160;1036 readonly type: 'Substrate' | 'Ethereum';1037}10381039/** @name PalletEvmCall */1040export interface PalletEvmCall extends Enum {1041 readonly isWithdraw: boolean;1042 readonly asWithdraw: {1043 readonly address: H160;1044 readonly value: u128;1045 } & Struct;1046 readonly isCall: boolean;1047 readonly asCall: {1048 readonly source: H160;1049 readonly target: H160;1050 readonly input: Bytes;1051 readonly value: U256;1052 readonly gasLimit: u64;1053 readonly maxFeePerGas: U256;1054 readonly maxPriorityFeePerGas: Option<U256>;1055 readonly nonce: Option<U256>;1056 readonly accessList: Vec<ITuple<[H160, Vec<H256>]>>;1057 } & Struct;1058 readonly isCreate: boolean;1059 readonly asCreate: {1060 readonly source: H160;1061 readonly init: Bytes;1062 readonly value: U256;1063 readonly gasLimit: u64;1064 readonly maxFeePerGas: U256;1065 readonly maxPriorityFeePerGas: Option<U256>;1066 readonly nonce: Option<U256>;1067 readonly accessList: Vec<ITuple<[H160, Vec<H256>]>>;1068 } & Struct;1069 readonly isCreate2: boolean;1070 readonly asCreate2: {1071 readonly source: H160;1072 readonly init: Bytes;1073 readonly salt: H256;1074 readonly value: U256;1075 readonly gasLimit: u64;1076 readonly maxFeePerGas: U256;1077 readonly maxPriorityFeePerGas: Option<U256>;1078 readonly nonce: Option<U256>;1079 readonly accessList: Vec<ITuple<[H160, Vec<H256>]>>;1080 } & Struct;1081 readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2';1082}10831084/** @name PalletEvmCoderSubstrateError */1085export interface PalletEvmCoderSubstrateError extends Enum {1086 readonly isOutOfGas: boolean;1087 readonly isOutOfFund: boolean;1088 readonly type: 'OutOfGas' | 'OutOfFund';1089}10901091/** @name PalletEvmContractHelpersError */1092export interface PalletEvmContractHelpersError extends Enum {1093 readonly isNoPermission: boolean;1094 readonly type: 'NoPermission';1095}10961097/** @name PalletEvmContractHelpersSponsoringModeT */1098export interface PalletEvmContractHelpersSponsoringModeT extends Enum {1099 readonly isDisabled: boolean;1100 readonly isAllowlisted: boolean;1101 readonly isGenerous: boolean;1102 readonly type: 'Disabled' | 'Allowlisted' | 'Generous';1103}11041105/** @name PalletEvmError */1106export interface PalletEvmError extends Enum {1107 readonly isBalanceLow: boolean;1108 readonly isFeeOverflow: boolean;1109 readonly isPaymentOverflow: boolean;1110 readonly isWithdrawFailed: boolean;1111 readonly isGasPriceTooLow: boolean;1112 readonly isInvalidNonce: boolean;1113 readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';1114}11151116/** @name PalletEvmEvent */1117export interface PalletEvmEvent extends Enum {1118 readonly isLog: boolean;1119 readonly asLog: EthereumLog;1120 readonly isCreated: boolean;1121 readonly asCreated: H160;1122 readonly isCreatedFailed: boolean;1123 readonly asCreatedFailed: H160;1124 readonly isExecuted: boolean;1125 readonly asExecuted: H160;1126 readonly isExecutedFailed: boolean;1127 readonly asExecutedFailed: H160;1128 readonly isBalanceDeposit: boolean;1129 readonly asBalanceDeposit: ITuple<[AccountId32, H160, U256]>;1130 readonly isBalanceWithdraw: boolean;1131 readonly asBalanceWithdraw: ITuple<[AccountId32, H160, U256]>;1132 readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';1133}11341135/** @name PalletEvmMigrationCall */1136export interface PalletEvmMigrationCall extends Enum {1137 readonly isBegin: boolean;1138 readonly asBegin: {1139 readonly address: H160;1140 } & Struct;1141 readonly isSetData: boolean;1142 readonly asSetData: {1143 readonly address: H160;1144 readonly data: Vec<ITuple<[H256, H256]>>;1145 } & Struct;1146 readonly isFinish: boolean;1147 readonly asFinish: {1148 readonly address: H160;1149 readonly code: Bytes;1150 } & Struct;1151 readonly type: 'Begin' | 'SetData' | 'Finish';1152}11531154/** @name PalletEvmMigrationError */1155export interface PalletEvmMigrationError extends Enum {1156 readonly isAccountNotEmpty: boolean;1157 readonly isAccountIsNotMigrating: boolean;1158 readonly type: 'AccountNotEmpty' | 'AccountIsNotMigrating';1159}11601161/** @name PalletFungibleError */1162export interface PalletFungibleError extends Enum {1163 readonly isNotFungibleDataUsedToMintFungibleCollectionToken: boolean;1164 readonly isFungibleItemsHaveNoId: boolean;1165 readonly isFungibleItemsDontHaveData: boolean;1166 readonly isFungibleDisallowsNesting: boolean;1167 readonly isSettingPropertiesNotAllowed: boolean;1168 readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';1169}11701171/** @name PalletInflationCall */1172export interface PalletInflationCall extends Enum {1173 readonly isStartInflation: boolean;1174 readonly asStartInflation: {1175 readonly inflationStartRelayBlock: u32;1176 } & Struct;1177 readonly type: 'StartInflation';1178}11791180/** @name PalletNonfungibleError */1181export interface PalletNonfungibleError extends Enum {1182 readonly isNotNonfungibleDataUsedToMintFungibleCollectionToken: boolean;1183 readonly isNonfungibleItemsHaveNoAmount: boolean;1184 readonly isCantBurnNftWithChildren: boolean;1185 readonly type: 'NotNonfungibleDataUsedToMintFungibleCollectionToken' | 'NonfungibleItemsHaveNoAmount' | 'CantBurnNftWithChildren';1186}11871188/** @name PalletNonfungibleItemData */1189export interface PalletNonfungibleItemData extends Struct {1190 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;1191}11921193/** @name PalletRefungibleError */1194export interface PalletRefungibleError extends Enum {1195 readonly isNotRefungibleDataUsedToMintFungibleCollectionToken: boolean;1196 readonly isWrongRefungiblePieces: boolean;1197 readonly isRepartitionWhileNotOwningAllPieces: boolean;1198 readonly isRefungibleDisallowsNesting: boolean;1199 readonly isSettingPropertiesNotAllowed: boolean;1200 readonly type: 'NotRefungibleDataUsedToMintFungibleCollectionToken' | 'WrongRefungiblePieces' | 'RepartitionWhileNotOwningAllPieces' | 'RefungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';1201}12021203/** @name PalletRefungibleItemData */1204export interface PalletRefungibleItemData extends Struct {1205 readonly constData: Bytes;1206}12071208/** @name PalletRmrkCoreCall */1209export interface PalletRmrkCoreCall extends Enum {1210 readonly isCreateCollection: boolean;1211 readonly asCreateCollection: {1212 readonly metadata: Bytes;1213 readonly max: Option<u32>;1214 readonly symbol: Bytes;1215 } & Struct;1216 readonly isDestroyCollection: boolean;1217 readonly asDestroyCollection: {1218 readonly collectionId: u32;1219 } & Struct;1220 readonly isChangeCollectionIssuer: boolean;1221 readonly asChangeCollectionIssuer: {1222 readonly collectionId: u32;1223 readonly newIssuer: MultiAddress;1224 } & Struct;1225 readonly isLockCollection: boolean;1226 readonly asLockCollection: {1227 readonly collectionId: u32;1228 } & Struct;1229 readonly isMintNft: boolean;1230 readonly asMintNft: {1231 readonly owner: Option<AccountId32>;1232 readonly collectionId: u32;1233 readonly recipient: Option<AccountId32>;1234 readonly royaltyAmount: Option<Permill>;1235 readonly metadata: Bytes;1236 readonly transferable: bool;1237 readonly resources: Option<Vec<RmrkTraitsResourceResourceTypes>>;1238 } & Struct;1239 readonly isBurnNft: boolean;1240 readonly asBurnNft: {1241 readonly collectionId: u32;1242 readonly nftId: u32;1243 readonly maxBurns: u32;1244 } & Struct;1245 readonly isSend: boolean;1246 readonly asSend: {1247 readonly rmrkCollectionId: u32;1248 readonly rmrkNftId: u32;1249 readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;1250 } & Struct;1251 readonly isAcceptNft: boolean;1252 readonly asAcceptNft: {1253 readonly rmrkCollectionId: u32;1254 readonly rmrkNftId: u32;1255 readonly newOwner: RmrkTraitsNftAccountIdOrCollectionNftTuple;1256 } & Struct;1257 readonly isRejectNft: boolean;1258 readonly asRejectNft: {1259 readonly rmrkCollectionId: u32;1260 readonly rmrkNftId: u32;1261 } & Struct;1262 readonly isAcceptResource: boolean;1263 readonly asAcceptResource: {1264 readonly rmrkCollectionId: u32;1265 readonly rmrkNftId: u32;1266 readonly resourceId: u32;1267 } & Struct;1268 readonly isAcceptResourceRemoval: boolean;1269 readonly asAcceptResourceRemoval: {1270 readonly rmrkCollectionId: u32;1271 readonly rmrkNftId: u32;1272 readonly resourceId: u32;1273 } & Struct;1274 readonly isSetProperty: boolean;1275 readonly asSetProperty: {1276 readonly rmrkCollectionId: Compact<u32>;1277 readonly maybeNftId: Option<u32>;1278 readonly key: Bytes;1279 readonly value: Bytes;1280 } & Struct;1281 readonly isSetPriority: boolean;1282 readonly asSetPriority: {1283 readonly rmrkCollectionId: u32;1284 readonly rmrkNftId: u32;1285 readonly priorities: Vec<u32>;1286 } & Struct;1287 readonly isAddBasicResource: boolean;1288 readonly asAddBasicResource: {1289 readonly rmrkCollectionId: u32;1290 readonly nftId: u32;1291 readonly resource: RmrkTraitsResourceBasicResource;1292 } & Struct;1293 readonly isAddComposableResource: boolean;1294 readonly asAddComposableResource: {1295 readonly rmrkCollectionId: u32;1296 readonly nftId: u32;1297 readonly resource: RmrkTraitsResourceComposableResource;1298 } & Struct;1299 readonly isAddSlotResource: boolean;1300 readonly asAddSlotResource: {1301 readonly rmrkCollectionId: u32;1302 readonly nftId: u32;1303 readonly resource: RmrkTraitsResourceSlotResource;1304 } & Struct;1305 readonly isRemoveResource: boolean;1306 readonly asRemoveResource: {1307 readonly rmrkCollectionId: u32;1308 readonly nftId: u32;1309 readonly resourceId: u32;1310 } & Struct;1311 readonly type: 'CreateCollection' | 'DestroyCollection' | 'ChangeCollectionIssuer' | 'LockCollection' | 'MintNft' | 'BurnNft' | 'Send' | 'AcceptNft' | 'RejectNft' | 'AcceptResource' | 'AcceptResourceRemoval' | 'SetProperty' | 'SetPriority' | 'AddBasicResource' | 'AddComposableResource' | 'AddSlotResource' | 'RemoveResource';1312}13131314/** @name PalletRmrkCoreError */1315export interface PalletRmrkCoreError extends Enum {1316 readonly isCorruptedCollectionType: boolean;1317 readonly isRmrkPropertyKeyIsTooLong: boolean;1318 readonly isRmrkPropertyValueIsTooLong: boolean;1319 readonly isRmrkPropertyIsNotFound: boolean;1320 readonly isUnableToDecodeRmrkData: boolean;1321 readonly isCollectionNotEmpty: boolean;1322 readonly isNoAvailableCollectionId: boolean;1323 readonly isNoAvailableNftId: boolean;1324 readonly isCollectionUnknown: boolean;1325 readonly isNoPermission: boolean;1326 readonly isNonTransferable: boolean;1327 readonly isCollectionFullOrLocked: boolean;1328 readonly isResourceDoesntExist: boolean;1329 readonly isCannotSendToDescendentOrSelf: boolean;1330 readonly isCannotAcceptNonOwnedNft: boolean;1331 readonly isCannotRejectNonOwnedNft: boolean;1332 readonly isCannotRejectNonPendingNft: boolean;1333 readonly isResourceNotPending: boolean;1334 readonly isNoAvailableResourceId: boolean;1335 readonly type: 'CorruptedCollectionType' | 'RmrkPropertyKeyIsTooLong' | 'RmrkPropertyValueIsTooLong' | 'RmrkPropertyIsNotFound' | 'UnableToDecodeRmrkData' | 'CollectionNotEmpty' | 'NoAvailableCollectionId' | 'NoAvailableNftId' | 'CollectionUnknown' | 'NoPermission' | 'NonTransferable' | 'CollectionFullOrLocked' | 'ResourceDoesntExist' | 'CannotSendToDescendentOrSelf' | 'CannotAcceptNonOwnedNft' | 'CannotRejectNonOwnedNft' | 'CannotRejectNonPendingNft' | 'ResourceNotPending' | 'NoAvailableResourceId';1336}13371338/** @name PalletRmrkCoreEvent */1339export interface PalletRmrkCoreEvent extends Enum {1340 readonly isCollectionCreated: boolean;1341 readonly asCollectionCreated: {1342 readonly issuer: AccountId32;1343 readonly collectionId: u32;1344 } & Struct;1345 readonly isCollectionDestroyed: boolean;1346 readonly asCollectionDestroyed: {1347 readonly issuer: AccountId32;1348 readonly collectionId: u32;1349 } & Struct;1350 readonly isIssuerChanged: boolean;1351 readonly asIssuerChanged: {1352 readonly oldIssuer: AccountId32;1353 readonly newIssuer: AccountId32;1354 readonly collectionId: u32;1355 } & Struct;1356 readonly isCollectionLocked: boolean;1357 readonly asCollectionLocked: {1358 readonly issuer: AccountId32;1359 readonly collectionId: u32;1360 } & Struct;1361 readonly isNftMinted: boolean;1362 readonly asNftMinted: {1363 readonly owner: AccountId32;1364 readonly collectionId: u32;1365 readonly nftId: u32;1366 } & Struct;1367 readonly isNftBurned: boolean;1368 readonly asNftBurned: {1369 readonly owner: AccountId32;1370 readonly nftId: u32;1371 } & Struct;1372 readonly isNftSent: boolean;1373 readonly asNftSent: {1374 readonly sender: AccountId32;1375 readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;1376 readonly collectionId: u32;1377 readonly nftId: u32;1378 readonly approvalRequired: bool;1379 } & Struct;1380 readonly isNftAccepted: boolean;1381 readonly asNftAccepted: {1382 readonly sender: AccountId32;1383 readonly recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple;1384 readonly collectionId: u32;1385 readonly nftId: u32;1386 } & Struct;1387 readonly isNftRejected: boolean;1388 readonly asNftRejected: {1389 readonly sender: AccountId32;1390 readonly collectionId: u32;1391 readonly nftId: u32;1392 } & Struct;1393 readonly isPropertySet: boolean;1394 readonly asPropertySet: {1395 readonly collectionId: u32;1396 readonly maybeNftId: Option<u32>;1397 readonly key: Bytes;1398 readonly value: Bytes;1399 } & Struct;1400 readonly isResourceAdded: boolean;1401 readonly asResourceAdded: {1402 readonly nftId: u32;1403 readonly resourceId: u32;1404 } & Struct;1405 readonly isResourceRemoval: boolean;1406 readonly asResourceRemoval: {1407 readonly nftId: u32;1408 readonly resourceId: u32;1409 } & Struct;1410 readonly isResourceAccepted: boolean;1411 readonly asResourceAccepted: {1412 readonly nftId: u32;1413 readonly resourceId: u32;1414 } & Struct;1415 readonly isResourceRemovalAccepted: boolean;1416 readonly asResourceRemovalAccepted: {1417 readonly nftId: u32;1418 readonly resourceId: u32;1419 } & Struct;1420 readonly isPrioritySet: boolean;1421 readonly asPrioritySet: {1422 readonly collectionId: u32;1423 readonly nftId: u32;1424 } & Struct;1425 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';1426}14271428/** @name PalletRmrkEquipCall */1429export interface PalletRmrkEquipCall extends Enum {1430 readonly isCreateBase: boolean;1431 readonly asCreateBase: {1432 readonly baseType: Bytes;1433 readonly symbol: Bytes;1434 readonly parts: Vec<RmrkTraitsPartPartType>;1435 } & Struct;1436 readonly isThemeAdd: boolean;1437 readonly asThemeAdd: {1438 readonly baseId: u32;1439 readonly theme: RmrkTraitsTheme;1440 } & Struct;1441 readonly isEquippable: boolean;1442 readonly asEquippable: {1443 readonly baseId: u32;1444 readonly slotId: u32;1445 readonly equippables: RmrkTraitsPartEquippableList;1446 } & Struct;1447 readonly type: 'CreateBase' | 'ThemeAdd' | 'Equippable';1448}14491450/** @name PalletRmrkEquipError */1451export interface PalletRmrkEquipError extends Enum {1452 readonly isPermissionError: boolean;1453 readonly isNoAvailableBaseId: boolean;1454 readonly isNoAvailablePartId: boolean;1455 readonly isBaseDoesntExist: boolean;1456 readonly isNeedsDefaultThemeFirst: boolean;1457 readonly isPartDoesntExist: boolean;1458 readonly isNoEquippableOnFixedPart: boolean;1459 readonly type: 'PermissionError' | 'NoAvailableBaseId' | 'NoAvailablePartId' | 'BaseDoesntExist' | 'NeedsDefaultThemeFirst' | 'PartDoesntExist' | 'NoEquippableOnFixedPart';1460}14611462/** @name PalletRmrkEquipEvent */1463export interface PalletRmrkEquipEvent extends Enum {1464 readonly isBaseCreated: boolean;1465 readonly asBaseCreated: {1466 readonly issuer: AccountId32;1467 readonly baseId: u32;1468 } & Struct;1469 readonly isEquippablesUpdated: boolean;1470 readonly asEquippablesUpdated: {1471 readonly baseId: u32;1472 readonly slotId: u32;1473 } & Struct;1474 readonly type: 'BaseCreated' | 'EquippablesUpdated';1475}14761477/** @name PalletStructureCall */1478export interface PalletStructureCall extends Null {}14791480/** @name PalletStructureError */1481export interface PalletStructureError extends Enum {1482 readonly isOuroborosDetected: boolean;1483 readonly isDepthLimit: boolean;1484 readonly isBreadthLimit: boolean;1485 readonly isTokenNotFound: boolean;1486 readonly type: 'OuroborosDetected' | 'DepthLimit' | 'BreadthLimit' | 'TokenNotFound';1487}14881489/** @name PalletStructureEvent */1490export interface PalletStructureEvent extends Enum {1491 readonly isExecuted: boolean;1492 readonly asExecuted: Result<Null, SpRuntimeDispatchError>;1493 readonly type: 'Executed';1494}14951496/** @name PalletSudoCall */1497export interface PalletSudoCall extends Enum {1498 readonly isSudo: boolean;1499 readonly asSudo: {1500 readonly call: Call;1501 } & Struct;1502 readonly isSudoUncheckedWeight: boolean;1503 readonly asSudoUncheckedWeight: {1504 readonly call: Call;1505 readonly weight: u64;1506 } & Struct;1507 readonly isSetKey: boolean;1508 readonly asSetKey: {1509 readonly new_: MultiAddress;1510 } & Struct;1511 readonly isSudoAs: boolean;1512 readonly asSudoAs: {1513 readonly who: MultiAddress;1514 readonly call: Call;1515 } & Struct;1516 readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs';1517}15181519/** @name PalletSudoError */1520export interface PalletSudoError extends Enum {1521 readonly isRequireSudo: boolean;1522 readonly type: 'RequireSudo';1523}15241525/** @name PalletSudoEvent */1526export interface PalletSudoEvent extends Enum {1527 readonly isSudid: boolean;1528 readonly asSudid: {1529 readonly sudoResult: Result<Null, SpRuntimeDispatchError>;1530 } & Struct;1531 readonly isKeyChanged: boolean;1532 readonly asKeyChanged: {1533 readonly oldSudoer: Option<AccountId32>;1534 } & Struct;1535 readonly isSudoAsDone: boolean;1536 readonly asSudoAsDone: {1537 readonly sudoResult: Result<Null, SpRuntimeDispatchError>;1538 } & Struct;1539 readonly type: 'Sudid' | 'KeyChanged' | 'SudoAsDone';1540}15411542/** @name PalletTemplateTransactionPaymentCall */1543export interface PalletTemplateTransactionPaymentCall extends Null {}15441545/** @name PalletTemplateTransactionPaymentChargeTransactionPayment */1546export interface PalletTemplateTransactionPaymentChargeTransactionPayment extends Compact<u128> {}15471548/** @name PalletTimestampCall */1549export interface PalletTimestampCall extends Enum {1550 readonly isSet: boolean;1551 readonly asSet: {1552 readonly now: Compact<u64>;1553 } & Struct;1554 readonly type: 'Set';1555}15561557/** @name PalletTransactionPaymentReleases */1558export interface PalletTransactionPaymentReleases extends Enum {1559 readonly isV1Ancient: boolean;1560 readonly isV2: boolean;1561 readonly type: 'V1Ancient' | 'V2';1562}15631564/** @name PalletTreasuryCall */1565export interface PalletTreasuryCall extends Enum {1566 readonly isProposeSpend: boolean;1567 readonly asProposeSpend: {1568 readonly value: Compact<u128>;1569 readonly beneficiary: MultiAddress;1570 } & Struct;1571 readonly isRejectProposal: boolean;1572 readonly asRejectProposal: {1573 readonly proposalId: Compact<u32>;1574 } & Struct;1575 readonly isApproveProposal: boolean;1576 readonly asApproveProposal: {1577 readonly proposalId: Compact<u32>;1578 } & Struct;1579 readonly isRemoveApproval: boolean;1580 readonly asRemoveApproval: {1581 readonly proposalId: Compact<u32>;1582 } & Struct;1583 readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal' | 'RemoveApproval';1584}15851586/** @name PalletTreasuryError */1587export interface PalletTreasuryError extends Enum {1588 readonly isInsufficientProposersBalance: boolean;1589 readonly isInvalidIndex: boolean;1590 readonly isTooManyApprovals: boolean;1591 readonly isProposalNotApproved: boolean;1592 readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals' | 'ProposalNotApproved';1593}15941595/** @name PalletTreasuryEvent */1596export interface PalletTreasuryEvent extends Enum {1597 readonly isProposed: boolean;1598 readonly asProposed: {1599 readonly proposalIndex: u32;1600 } & Struct;1601 readonly isSpending: boolean;1602 readonly asSpending: {1603 readonly budgetRemaining: u128;1604 } & Struct;1605 readonly isAwarded: boolean;1606 readonly asAwarded: {1607 readonly proposalIndex: u32;1608 readonly award: u128;1609 readonly account: AccountId32;1610 } & Struct;1611 readonly isRejected: boolean;1612 readonly asRejected: {1613 readonly proposalIndex: u32;1614 readonly slashed: u128;1615 } & Struct;1616 readonly isBurnt: boolean;1617 readonly asBurnt: {1618 readonly burntFunds: u128;1619 } & Struct;1620 readonly isRollover: boolean;1621 readonly asRollover: {1622 readonly rolloverBalance: u128;1623 } & Struct;1624 readonly isDeposit: boolean;1625 readonly asDeposit: {1626 readonly value: u128;1627 } & Struct;1628 readonly type: 'Proposed' | 'Spending' | 'Awarded' | 'Rejected' | 'Burnt' | 'Rollover' | 'Deposit';1629}16301631/** @name PalletTreasuryProposal */1632export interface PalletTreasuryProposal extends Struct {1633 readonly proposer: AccountId32;1634 readonly value: u128;1635 readonly beneficiary: AccountId32;1636 readonly bond: u128;1637}16381639/** @name PalletUniqueCall */1640export interface PalletUniqueCall extends Enum {1641 readonly isCreateCollection: boolean;1642 readonly asCreateCollection: {1643 readonly collectionName: Vec<u16>;1644 readonly collectionDescription: Vec<u16>;1645 readonly tokenPrefix: Bytes;1646 readonly mode: UpDataStructsCollectionMode;1647 } & Struct;1648 readonly isCreateCollectionEx: boolean;1649 readonly asCreateCollectionEx: {1650 readonly data: UpDataStructsCreateCollectionData;1651 } & Struct;1652 readonly isDestroyCollection: boolean;1653 readonly asDestroyCollection: {1654 readonly collectionId: u32;1655 } & Struct;1656 readonly isAddToAllowList: boolean;1657 readonly asAddToAllowList: {1658 readonly collectionId: u32;1659 readonly address: PalletEvmAccountBasicCrossAccountIdRepr;1660 } & Struct;1661 readonly isRemoveFromAllowList: boolean;1662 readonly asRemoveFromAllowList: {1663 readonly collectionId: u32;1664 readonly address: PalletEvmAccountBasicCrossAccountIdRepr;1665 } & Struct;1666 readonly isChangeCollectionOwner: boolean;1667 readonly asChangeCollectionOwner: {1668 readonly collectionId: u32;1669 readonly newOwner: AccountId32;1670 } & Struct;1671 readonly isAddCollectionAdmin: boolean;1672 readonly asAddCollectionAdmin: {1673 readonly collectionId: u32;1674 readonly newAdmin: PalletEvmAccountBasicCrossAccountIdRepr;1675 } & Struct;1676 readonly isRemoveCollectionAdmin: boolean;1677 readonly asRemoveCollectionAdmin: {1678 readonly collectionId: u32;1679 readonly accountId: PalletEvmAccountBasicCrossAccountIdRepr;1680 } & Struct;1681 readonly isSetCollectionSponsor: boolean;1682 readonly asSetCollectionSponsor: {1683 readonly collectionId: u32;1684 readonly newSponsor: AccountId32;1685 } & Struct;1686 readonly isConfirmSponsorship: boolean;1687 readonly asConfirmSponsorship: {1688 readonly collectionId: u32;1689 } & Struct;1690 readonly isRemoveCollectionSponsor: boolean;1691 readonly asRemoveCollectionSponsor: {1692 readonly collectionId: u32;1693 } & Struct;1694 readonly isCreateItem: boolean;1695 readonly asCreateItem: {1696 readonly collectionId: u32;1697 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;1698 readonly data: UpDataStructsCreateItemData;1699 } & Struct;1700 readonly isCreateMultipleItems: boolean;1701 readonly asCreateMultipleItems: {1702 readonly collectionId: u32;1703 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;1704 readonly itemsData: Vec<UpDataStructsCreateItemData>;1705 } & Struct;1706 readonly isSetCollectionProperties: boolean;1707 readonly asSetCollectionProperties: {1708 readonly collectionId: u32;1709 readonly properties: Vec<UpDataStructsProperty>;1710 } & Struct;1711 readonly isDeleteCollectionProperties: boolean;1712 readonly asDeleteCollectionProperties: {1713 readonly collectionId: u32;1714 readonly propertyKeys: Vec<Bytes>;1715 } & Struct;1716 readonly isSetTokenProperties: boolean;1717 readonly asSetTokenProperties: {1718 readonly collectionId: u32;1719 readonly tokenId: u32;1720 readonly properties: Vec<UpDataStructsProperty>;1721 } & Struct;1722 readonly isDeleteTokenProperties: boolean;1723 readonly asDeleteTokenProperties: {1724 readonly collectionId: u32;1725 readonly tokenId: u32;1726 readonly propertyKeys: Vec<Bytes>;1727 } & Struct;1728 readonly isSetTokenPropertyPermissions: boolean;1729 readonly asSetTokenPropertyPermissions: {1730 readonly collectionId: u32;1731 readonly propertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;1732 } & Struct;1733 readonly isCreateMultipleItemsEx: boolean;1734 readonly asCreateMultipleItemsEx: {1735 readonly collectionId: u32;1736 readonly data: UpDataStructsCreateItemExData;1737 } & Struct;1738 readonly isSetTransfersEnabledFlag: boolean;1739 readonly asSetTransfersEnabledFlag: {1740 readonly collectionId: u32;1741 readonly value: bool;1742 } & Struct;1743 readonly isBurnItem: boolean;1744 readonly asBurnItem: {1745 readonly collectionId: u32;1746 readonly itemId: u32;1747 readonly value: u128;1748 } & Struct;1749 readonly isBurnFrom: boolean;1750 readonly asBurnFrom: {1751 readonly collectionId: u32;1752 readonly from: PalletEvmAccountBasicCrossAccountIdRepr;1753 readonly itemId: u32;1754 readonly value: u128;1755 } & Struct;1756 readonly isTransfer: boolean;1757 readonly asTransfer: {1758 readonly recipient: PalletEvmAccountBasicCrossAccountIdRepr;1759 readonly collectionId: u32;1760 readonly itemId: u32;1761 readonly value: u128;1762 } & Struct;1763 readonly isApprove: boolean;1764 readonly asApprove: {1765 readonly spender: PalletEvmAccountBasicCrossAccountIdRepr;1766 readonly collectionId: u32;1767 readonly itemId: u32;1768 readonly amount: u128;1769 } & Struct;1770 readonly isTransferFrom: boolean;1771 readonly asTransferFrom: {1772 readonly from: PalletEvmAccountBasicCrossAccountIdRepr;1773 readonly recipient: PalletEvmAccountBasicCrossAccountIdRepr;1774 readonly collectionId: u32;1775 readonly itemId: u32;1776 readonly value: u128;1777 } & Struct;1778 readonly isSetCollectionLimits: boolean;1779 readonly asSetCollectionLimits: {1780 readonly collectionId: u32;1781 readonly newLimit: UpDataStructsCollectionLimits;1782 } & Struct;1783 readonly isSetCollectionPermissions: boolean;1784 readonly asSetCollectionPermissions: {1785 readonly collectionId: u32;1786 readonly newPermission: UpDataStructsCollectionPermissions;1787 } & Struct;1788 readonly isRepartition: boolean;1789 readonly asRepartition: {1790 readonly collectionId: u32;1791 readonly tokenId: u32;1792 readonly amount: u128;1793 } & Struct;1794 readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';1795}17961797/** @name PalletUniqueError */1798export interface PalletUniqueError extends Enum {1799 readonly isCollectionDecimalPointLimitExceeded: boolean;1800 readonly isConfirmUnsetSponsorFail: boolean;1801 readonly isEmptyArgument: boolean;1802 readonly isRepartitionCalledOnNonRefungibleCollection: boolean;1803 readonly type: 'CollectionDecimalPointLimitExceeded' | 'ConfirmUnsetSponsorFail' | 'EmptyArgument' | 'RepartitionCalledOnNonRefungibleCollection';1804}18051806/** @name PalletUniqueRawEvent */1807export interface PalletUniqueRawEvent extends Enum {1808 readonly isCollectionSponsorRemoved: boolean;1809 readonly asCollectionSponsorRemoved: u32;1810 readonly isCollectionAdminAdded: boolean;1811 readonly asCollectionAdminAdded: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1812 readonly isCollectionOwnedChanged: boolean;1813 readonly asCollectionOwnedChanged: ITuple<[u32, AccountId32]>;1814 readonly isCollectionSponsorSet: boolean;1815 readonly asCollectionSponsorSet: ITuple<[u32, AccountId32]>;1816 readonly isSponsorshipConfirmed: boolean;1817 readonly asSponsorshipConfirmed: ITuple<[u32, AccountId32]>;1818 readonly isCollectionAdminRemoved: boolean;1819 readonly asCollectionAdminRemoved: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1820 readonly isAllowListAddressRemoved: boolean;1821 readonly asAllowListAddressRemoved: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1822 readonly isAllowListAddressAdded: boolean;1823 readonly asAllowListAddressAdded: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr]>;1824 readonly isCollectionLimitSet: boolean;1825 readonly asCollectionLimitSet: u32;1826 readonly isCollectionPermissionSet: boolean;1827 readonly asCollectionPermissionSet: u32;1828 readonly type: 'CollectionSponsorRemoved' | 'CollectionAdminAdded' | 'CollectionOwnedChanged' | 'CollectionSponsorSet' | 'SponsorshipConfirmed' | 'CollectionAdminRemoved' | 'AllowListAddressRemoved' | 'AllowListAddressAdded' | 'CollectionLimitSet' | 'CollectionPermissionSet';1829}18301831/** @name PalletUniqueSchedulerCall */1832export interface PalletUniqueSchedulerCall extends Enum {1833 readonly isScheduleNamed: boolean;1834 readonly asScheduleNamed: {1835 readonly id: U8aFixed;1836 readonly when: u32;1837 readonly maybePeriodic: Option<ITuple<[u32, u32]>>;1838 readonly priority: u8;1839 readonly call: FrameSupportScheduleMaybeHashed;1840 } & Struct;1841 readonly isCancelNamed: boolean;1842 readonly asCancelNamed: {1843 readonly id: U8aFixed;1844 } & Struct;1845 readonly isScheduleNamedAfter: boolean;1846 readonly asScheduleNamedAfter: {1847 readonly id: U8aFixed;1848 readonly after: u32;1849 readonly maybePeriodic: Option<ITuple<[u32, u32]>>;1850 readonly priority: u8;1851 readonly call: FrameSupportScheduleMaybeHashed;1852 } & Struct;1853 readonly type: 'ScheduleNamed' | 'CancelNamed' | 'ScheduleNamedAfter';1854}18551856/** @name PalletUniqueSchedulerError */1857export interface PalletUniqueSchedulerError extends Enum {1858 readonly isFailedToSchedule: boolean;1859 readonly isNotFound: boolean;1860 readonly isTargetBlockNumberInPast: boolean;1861 readonly isRescheduleNoChange: boolean;1862 readonly type: 'FailedToSchedule' | 'NotFound' | 'TargetBlockNumberInPast' | 'RescheduleNoChange';1863}18641865/** @name PalletUniqueSchedulerEvent */1866export interface PalletUniqueSchedulerEvent extends Enum {1867 readonly isScheduled: boolean;1868 readonly asScheduled: {1869 readonly when: u32;1870 readonly index: u32;1871 } & Struct;1872 readonly isCanceled: boolean;1873 readonly asCanceled: {1874 readonly when: u32;1875 readonly index: u32;1876 } & Struct;1877 readonly isDispatched: boolean;1878 readonly asDispatched: {1879 readonly task: ITuple<[u32, u32]>;1880 readonly id: Option<U8aFixed>;1881 readonly result: Result<Null, SpRuntimeDispatchError>;1882 } & Struct;1883 readonly isCallLookupFailed: boolean;1884 readonly asCallLookupFailed: {1885 readonly task: ITuple<[u32, u32]>;1886 readonly id: Option<U8aFixed>;1887 readonly error: FrameSupportScheduleLookupError;1888 } & Struct;1889 readonly type: 'Scheduled' | 'Canceled' | 'Dispatched' | 'CallLookupFailed';1890}18911892/** @name PalletUniqueSchedulerScheduledV3 */1893export interface PalletUniqueSchedulerScheduledV3 extends Struct {1894 readonly maybeId: Option<U8aFixed>;1895 readonly priority: u8;1896 readonly call: FrameSupportScheduleMaybeHashed;1897 readonly maybePeriodic: Option<ITuple<[u32, u32]>>;1898 readonly origin: OpalRuntimeOriginCaller;1899}19001901/** @name PalletXcmCall */1902export interface PalletXcmCall extends Enum {1903 readonly isSend: boolean;1904 readonly asSend: {1905 readonly dest: XcmVersionedMultiLocation;1906 readonly message: XcmVersionedXcm;1907 } & Struct;1908 readonly isTeleportAssets: boolean;1909 readonly asTeleportAssets: {1910 readonly dest: XcmVersionedMultiLocation;1911 readonly beneficiary: XcmVersionedMultiLocation;1912 readonly assets: XcmVersionedMultiAssets;1913 readonly feeAssetItem: u32;1914 } & Struct;1915 readonly isReserveTransferAssets: boolean;1916 readonly asReserveTransferAssets: {1917 readonly dest: XcmVersionedMultiLocation;1918 readonly beneficiary: XcmVersionedMultiLocation;1919 readonly assets: XcmVersionedMultiAssets;1920 readonly feeAssetItem: u32;1921 } & Struct;1922 readonly isExecute: boolean;1923 readonly asExecute: {1924 readonly message: XcmVersionedXcm;1925 readonly maxWeight: u64;1926 } & Struct;1927 readonly isForceXcmVersion: boolean;1928 readonly asForceXcmVersion: {1929 readonly location: XcmV1MultiLocation;1930 readonly xcmVersion: u32;1931 } & Struct;1932 readonly isForceDefaultXcmVersion: boolean;1933 readonly asForceDefaultXcmVersion: {1934 readonly maybeXcmVersion: Option<u32>;1935 } & Struct;1936 readonly isForceSubscribeVersionNotify: boolean;1937 readonly asForceSubscribeVersionNotify: {1938 readonly location: XcmVersionedMultiLocation;1939 } & Struct;1940 readonly isForceUnsubscribeVersionNotify: boolean;1941 readonly asForceUnsubscribeVersionNotify: {1942 readonly location: XcmVersionedMultiLocation;1943 } & Struct;1944 readonly isLimitedReserveTransferAssets: boolean;1945 readonly asLimitedReserveTransferAssets: {1946 readonly dest: XcmVersionedMultiLocation;1947 readonly beneficiary: XcmVersionedMultiLocation;1948 readonly assets: XcmVersionedMultiAssets;1949 readonly feeAssetItem: u32;1950 readonly weightLimit: XcmV2WeightLimit;1951 } & Struct;1952 readonly isLimitedTeleportAssets: boolean;1953 readonly asLimitedTeleportAssets: {1954 readonly dest: XcmVersionedMultiLocation;1955 readonly beneficiary: XcmVersionedMultiLocation;1956 readonly assets: XcmVersionedMultiAssets;1957 readonly feeAssetItem: u32;1958 readonly weightLimit: XcmV2WeightLimit;1959 } & Struct;1960 readonly type: 'Send' | 'TeleportAssets' | 'ReserveTransferAssets' | 'Execute' | 'ForceXcmVersion' | 'ForceDefaultXcmVersion' | 'ForceSubscribeVersionNotify' | 'ForceUnsubscribeVersionNotify' | 'LimitedReserveTransferAssets' | 'LimitedTeleportAssets';1961}19621963/** @name PalletXcmError */1964export interface PalletXcmError extends Enum {1965 readonly isUnreachable: boolean;1966 readonly isSendFailure: boolean;1967 readonly isFiltered: boolean;1968 readonly isUnweighableMessage: boolean;1969 readonly isDestinationNotInvertible: boolean;1970 readonly isEmpty: boolean;1971 readonly isCannotReanchor: boolean;1972 readonly isTooManyAssets: boolean;1973 readonly isInvalidOrigin: boolean;1974 readonly isBadVersion: boolean;1975 readonly isBadLocation: boolean;1976 readonly isNoSubscription: boolean;1977 readonly isAlreadySubscribed: boolean;1978 readonly type: 'Unreachable' | 'SendFailure' | 'Filtered' | 'UnweighableMessage' | 'DestinationNotInvertible' | 'Empty' | 'CannotReanchor' | 'TooManyAssets' | 'InvalidOrigin' | 'BadVersion' | 'BadLocation' | 'NoSubscription' | 'AlreadySubscribed';1979}19801981/** @name PalletXcmEvent */1982export interface PalletXcmEvent extends Enum {1983 readonly isAttempted: boolean;1984 readonly asAttempted: XcmV2TraitsOutcome;1985 readonly isSent: boolean;1986 readonly asSent: ITuple<[XcmV1MultiLocation, XcmV1MultiLocation, XcmV2Xcm]>;1987 readonly isUnexpectedResponse: boolean;1988 readonly asUnexpectedResponse: ITuple<[XcmV1MultiLocation, u64]>;1989 readonly isResponseReady: boolean;1990 readonly asResponseReady: ITuple<[u64, XcmV2Response]>;1991 readonly isNotified: boolean;1992 readonly asNotified: ITuple<[u64, u8, u8]>;1993 readonly isNotifyOverweight: boolean;1994 readonly asNotifyOverweight: ITuple<[u64, u8, u8, u64, u64]>;1995 readonly isNotifyDispatchError: boolean;1996 readonly asNotifyDispatchError: ITuple<[u64, u8, u8]>;1997 readonly isNotifyDecodeFailed: boolean;1998 readonly asNotifyDecodeFailed: ITuple<[u64, u8, u8]>;1999 readonly isInvalidResponder: boolean;2000 readonly asInvalidResponder: ITuple<[XcmV1MultiLocation, u64, Option<XcmV1MultiLocation>]>;2001 readonly isInvalidResponderVersion: boolean;2002 readonly asInvalidResponderVersion: ITuple<[XcmV1MultiLocation, u64]>;2003 readonly isResponseTaken: boolean;2004 readonly asResponseTaken: u64;2005 readonly isAssetsTrapped: boolean;2006 readonly asAssetsTrapped: ITuple<[H256, XcmV1MultiLocation, XcmVersionedMultiAssets]>;2007 readonly isVersionChangeNotified: boolean;2008 readonly asVersionChangeNotified: ITuple<[XcmV1MultiLocation, u32]>;2009 readonly isSupportedVersionChanged: boolean;2010 readonly asSupportedVersionChanged: ITuple<[XcmV1MultiLocation, u32]>;2011 readonly isNotifyTargetSendFail: boolean;2012 readonly asNotifyTargetSendFail: ITuple<[XcmV1MultiLocation, u64, XcmV2TraitsError]>;2013 readonly isNotifyTargetMigrationFail: boolean;2014 readonly asNotifyTargetMigrationFail: ITuple<[XcmVersionedMultiLocation, u64]>;2015 readonly type: 'Attempted' | 'Sent' | 'UnexpectedResponse' | 'ResponseReady' | 'Notified' | 'NotifyOverweight' | 'NotifyDispatchError' | 'NotifyDecodeFailed' | 'InvalidResponder' | 'InvalidResponderVersion' | 'ResponseTaken' | 'AssetsTrapped' | 'VersionChangeNotified' | 'SupportedVersionChanged' | 'NotifyTargetSendFail' | 'NotifyTargetMigrationFail';2016}20172018/** @name PalletXcmOrigin */2019export interface PalletXcmOrigin extends Enum {2020 readonly isXcm: boolean;2021 readonly asXcm: XcmV1MultiLocation;2022 readonly isResponse: boolean;2023 readonly asResponse: XcmV1MultiLocation;2024 readonly type: 'Xcm' | 'Response';2025}20262027/** @name PhantomTypeUpDataStructs */2028export interface PhantomTypeUpDataStructs extends Vec<ITuple<[UpDataStructsTokenData, UpDataStructsRpcCollection, RmrkTraitsCollectionCollectionInfo, RmrkTraitsNftNftInfo, RmrkTraitsResourceResourceInfo, RmrkTraitsPropertyPropertyInfo, RmrkTraitsBaseBaseInfo, RmrkTraitsPartPartType, RmrkTraitsTheme, RmrkTraitsNftNftChild]>> {}20292030/** @name PolkadotCorePrimitivesInboundDownwardMessage */2031export interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {2032 readonly sentAt: u32;2033 readonly msg: Bytes;2034}20352036/** @name PolkadotCorePrimitivesInboundHrmpMessage */2037export interface PolkadotCorePrimitivesInboundHrmpMessage extends Struct {2038 readonly sentAt: u32;2039 readonly data: Bytes;2040}20412042/** @name PolkadotCorePrimitivesOutboundHrmpMessage */2043export interface PolkadotCorePrimitivesOutboundHrmpMessage extends Struct {2044 readonly recipient: u32;2045 readonly data: Bytes;2046}20472048/** @name PolkadotParachainPrimitivesXcmpMessageFormat */2049export interface PolkadotParachainPrimitivesXcmpMessageFormat extends Enum {2050 readonly isConcatenatedVersionedXcm: boolean;2051 readonly isConcatenatedEncodedBlob: boolean;2052 readonly isSignals: boolean;2053 readonly type: 'ConcatenatedVersionedXcm' | 'ConcatenatedEncodedBlob' | 'Signals';2054}20552056/** @name PolkadotPrimitivesV2AbridgedHostConfiguration */2057export interface PolkadotPrimitivesV2AbridgedHostConfiguration extends Struct {2058 readonly maxCodeSize: u32;2059 readonly maxHeadDataSize: u32;2060 readonly maxUpwardQueueCount: u32;2061 readonly maxUpwardQueueSize: u32;2062 readonly maxUpwardMessageSize: u32;2063 readonly maxUpwardMessageNumPerCandidate: u32;2064 readonly hrmpMaxMessageNumPerCandidate: u32;2065 readonly validationUpgradeCooldown: u32;2066 readonly validationUpgradeDelay: u32;2067}20682069/** @name PolkadotPrimitivesV2AbridgedHrmpChannel */2070export interface PolkadotPrimitivesV2AbridgedHrmpChannel extends Struct {2071 readonly maxCapacity: u32;2072 readonly maxTotalSize: u32;2073 readonly maxMessageSize: u32;2074 readonly msgCount: u32;2075 readonly totalSize: u32;2076 readonly mqcHead: Option<H256>;2077}20782079/** @name PolkadotPrimitivesV2PersistedValidationData */2080export interface PolkadotPrimitivesV2PersistedValidationData extends Struct {2081 readonly parentHead: Bytes;2082 readonly relayParentNumber: u32;2083 readonly relayParentStorageRoot: H256;2084 readonly maxPovSize: u32;2085}20862087/** @name PolkadotPrimitivesV2UpgradeRestriction */2088export interface PolkadotPrimitivesV2UpgradeRestriction extends Enum {2089 readonly isPresent: boolean;2090 readonly type: 'Present';2091}20922093/** @name RmrkTraitsBaseBaseInfo */2094export interface RmrkTraitsBaseBaseInfo extends Struct {2095 readonly issuer: AccountId32;2096 readonly baseType: Bytes;2097 readonly symbol: Bytes;2098}20992100/** @name RmrkTraitsCollectionCollectionInfo */2101export interface RmrkTraitsCollectionCollectionInfo extends Struct {2102 readonly issuer: AccountId32;2103 readonly metadata: Bytes;2104 readonly max: Option<u32>;2105 readonly symbol: Bytes;2106 readonly nftsCount: u32;2107}21082109/** @name RmrkTraitsNftAccountIdOrCollectionNftTuple */2110export interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {2111 readonly isAccountId: boolean;2112 readonly asAccountId: AccountId32;2113 readonly isCollectionAndNftTuple: boolean;2114 readonly asCollectionAndNftTuple: ITuple<[u32, u32]>;2115 readonly type: 'AccountId' | 'CollectionAndNftTuple';2116}21172118/** @name RmrkTraitsNftNftChild */2119export interface RmrkTraitsNftNftChild extends Struct {2120 readonly collectionId: u32;2121 readonly nftId: u32;2122}21232124/** @name RmrkTraitsNftNftInfo */2125export interface RmrkTraitsNftNftInfo extends Struct {2126 readonly owner: RmrkTraitsNftAccountIdOrCollectionNftTuple;2127 readonly royalty: Option<RmrkTraitsNftRoyaltyInfo>;2128 readonly metadata: Bytes;2129 readonly equipped: bool;2130 readonly pending: bool;2131}21322133/** @name RmrkTraitsNftRoyaltyInfo */2134export interface RmrkTraitsNftRoyaltyInfo extends Struct {2135 readonly recipient: AccountId32;2136 readonly amount: Permill;2137}21382139/** @name RmrkTraitsPartEquippableList */2140export interface RmrkTraitsPartEquippableList extends Enum {2141 readonly isAll: boolean;2142 readonly isEmpty: boolean;2143 readonly isCustom: boolean;2144 readonly asCustom: Vec<u32>;2145 readonly type: 'All' | 'Empty' | 'Custom';2146}21472148/** @name RmrkTraitsPartFixedPart */2149export interface RmrkTraitsPartFixedPart extends Struct {2150 readonly id: u32;2151 readonly z: u32;2152 readonly src: Bytes;2153}21542155/** @name RmrkTraitsPartPartType */2156export interface RmrkTraitsPartPartType extends Enum {2157 readonly isFixedPart: boolean;2158 readonly asFixedPart: RmrkTraitsPartFixedPart;2159 readonly isSlotPart: boolean;2160 readonly asSlotPart: RmrkTraitsPartSlotPart;2161 readonly type: 'FixedPart' | 'SlotPart';2162}21632164/** @name RmrkTraitsPartSlotPart */2165export interface RmrkTraitsPartSlotPart extends Struct {2166 readonly id: u32;2167 readonly equippable: RmrkTraitsPartEquippableList;2168 readonly src: Bytes;2169 readonly z: u32;2170}21712172/** @name RmrkTraitsPropertyPropertyInfo */2173export interface RmrkTraitsPropertyPropertyInfo extends Struct {2174 readonly key: Bytes;2175 readonly value: Bytes;2176}21772178/** @name RmrkTraitsResourceBasicResource */2179export interface RmrkTraitsResourceBasicResource extends Struct {2180 readonly src: Option<Bytes>;2181 readonly metadata: Option<Bytes>;2182 readonly license: Option<Bytes>;2183 readonly thumb: Option<Bytes>;2184}21852186/** @name RmrkTraitsResourceComposableResource */2187export interface RmrkTraitsResourceComposableResource extends Struct {2188 readonly parts: Vec<u32>;2189 readonly base: u32;2190 readonly src: Option<Bytes>;2191 readonly metadata: Option<Bytes>;2192 readonly license: Option<Bytes>;2193 readonly thumb: Option<Bytes>;2194}21952196/** @name RmrkTraitsResourceResourceInfo */2197export interface RmrkTraitsResourceResourceInfo extends Struct {2198 readonly id: u32;2199 readonly resource: RmrkTraitsResourceResourceTypes;2200 readonly pending: bool;2201 readonly pendingRemoval: bool;2202}22032204/** @name RmrkTraitsResourceResourceTypes */2205export interface RmrkTraitsResourceResourceTypes extends Enum {2206 readonly isBasic: boolean;2207 readonly asBasic: RmrkTraitsResourceBasicResource;2208 readonly isComposable: boolean;2209 readonly asComposable: RmrkTraitsResourceComposableResource;2210 readonly isSlot: boolean;2211 readonly asSlot: RmrkTraitsResourceSlotResource;2212 readonly type: 'Basic' | 'Composable' | 'Slot';2213}22142215/** @name RmrkTraitsResourceSlotResource */2216export interface RmrkTraitsResourceSlotResource extends Struct {2217 readonly base: u32;2218 readonly src: Option<Bytes>;2219 readonly metadata: Option<Bytes>;2220 readonly slot: u32;2221 readonly license: Option<Bytes>;2222 readonly thumb: Option<Bytes>;2223}22242225/** @name RmrkTraitsTheme */2226export interface RmrkTraitsTheme extends Struct {2227 readonly name: Bytes;2228 readonly properties: Vec<RmrkTraitsThemeThemeProperty>;2229 readonly inherit: bool;2230}22312232/** @name RmrkTraitsThemeThemeProperty */2233export interface RmrkTraitsThemeThemeProperty extends Struct {2234 readonly key: Bytes;2235 readonly value: Bytes;2236}22372238/** @name SpCoreEcdsaSignature */2239export interface SpCoreEcdsaSignature extends U8aFixed {}22402241/** @name SpCoreEd25519Signature */2242export interface SpCoreEd25519Signature extends U8aFixed {}22432244/** @name SpCoreSr25519Signature */2245export interface SpCoreSr25519Signature extends U8aFixed {}22462247/** @name SpCoreVoid */2248export interface SpCoreVoid extends Null {}22492250/** @name SpRuntimeArithmeticError */2251export interface SpRuntimeArithmeticError extends Enum {2252 readonly isUnderflow: boolean;2253 readonly isOverflow: boolean;2254 readonly isDivisionByZero: boolean;2255 readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero';2256}22572258/** @name SpRuntimeDigest */2259export interface SpRuntimeDigest extends Struct {2260 readonly logs: Vec<SpRuntimeDigestDigestItem>;2261}22622263/** @name SpRuntimeDigestDigestItem */2264export interface SpRuntimeDigestDigestItem extends Enum {2265 readonly isOther: boolean;2266 readonly asOther: Bytes;2267 readonly isConsensus: boolean;2268 readonly asConsensus: ITuple<[U8aFixed, Bytes]>;2269 readonly isSeal: boolean;2270 readonly asSeal: ITuple<[U8aFixed, Bytes]>;2271 readonly isPreRuntime: boolean;2272 readonly asPreRuntime: ITuple<[U8aFixed, Bytes]>;2273 readonly isRuntimeEnvironmentUpdated: boolean;2274 readonly type: 'Other' | 'Consensus' | 'Seal' | 'PreRuntime' | 'RuntimeEnvironmentUpdated';2275}22762277/** @name SpRuntimeDispatchError */2278export interface SpRuntimeDispatchError extends Enum {2279 readonly isOther: boolean;2280 readonly isCannotLookup: boolean;2281 readonly isBadOrigin: boolean;2282 readonly isModule: boolean;2283 readonly asModule: SpRuntimeModuleError;2284 readonly isConsumerRemaining: boolean;2285 readonly isNoProviders: boolean;2286 readonly isTooManyConsumers: boolean;2287 readonly isToken: boolean;2288 readonly asToken: SpRuntimeTokenError;2289 readonly isArithmetic: boolean;2290 readonly asArithmetic: SpRuntimeArithmeticError;2291 readonly isTransactional: boolean;2292 readonly asTransactional: SpRuntimeTransactionalError;2293 readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic' | 'Transactional';2294}22952296/** @name SpRuntimeModuleError */2297export interface SpRuntimeModuleError extends Struct {2298 readonly index: u8;2299 readonly error: U8aFixed;2300}23012302/** @name SpRuntimeMultiSignature */2303export interface SpRuntimeMultiSignature extends Enum {2304 readonly isEd25519: boolean;2305 readonly asEd25519: SpCoreEd25519Signature;2306 readonly isSr25519: boolean;2307 readonly asSr25519: SpCoreSr25519Signature;2308 readonly isEcdsa: boolean;2309 readonly asEcdsa: SpCoreEcdsaSignature;2310 readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa';2311}23122313/** @name SpRuntimeTokenError */2314export interface SpRuntimeTokenError extends Enum {2315 readonly isNoFunds: boolean;2316 readonly isWouldDie: boolean;2317 readonly isBelowMinimum: boolean;2318 readonly isCannotCreate: boolean;2319 readonly isUnknownAsset: boolean;2320 readonly isFrozen: boolean;2321 readonly isUnsupported: boolean;2322 readonly type: 'NoFunds' | 'WouldDie' | 'BelowMinimum' | 'CannotCreate' | 'UnknownAsset' | 'Frozen' | 'Unsupported';2323}23242325/** @name SpRuntimeTransactionalError */2326export interface SpRuntimeTransactionalError extends Enum {2327 readonly isLimitReached: boolean;2328 readonly isNoLayer: boolean;2329 readonly type: 'LimitReached' | 'NoLayer';2330}23312332/** @name SpTrieStorageProof */2333export interface SpTrieStorageProof extends Struct {2334 readonly trieNodes: BTreeSet<Bytes>;2335}23362337/** @name SpVersionRuntimeVersion */2338export interface SpVersionRuntimeVersion extends Struct {2339 readonly specName: Text;2340 readonly implName: Text;2341 readonly authoringVersion: u32;2342 readonly specVersion: u32;2343 readonly implVersion: u32;2344 readonly apis: Vec<ITuple<[U8aFixed, u32]>>;2345 readonly transactionVersion: u32;2346 readonly stateVersion: u8;2347}23482349/** @name UpDataStructsAccessMode */2350export interface UpDataStructsAccessMode extends Enum {2351 readonly isNormal: boolean;2352 readonly isAllowList: boolean;2353 readonly type: 'Normal' | 'AllowList';2354}23552356/** @name UpDataStructsCollection */2357export interface UpDataStructsCollection extends Struct {2358 readonly owner: AccountId32;2359 readonly mode: UpDataStructsCollectionMode;2360 readonly name: Vec<u16>;2361 readonly description: Vec<u16>;2362 readonly tokenPrefix: Bytes;2363 readonly sponsorship: UpDataStructsSponsorshipState;2364 readonly limits: UpDataStructsCollectionLimits;2365 readonly permissions: UpDataStructsCollectionPermissions;2366 readonly externalCollection: bool;2367}23682369/** @name UpDataStructsCollectionLimits */2370export interface UpDataStructsCollectionLimits extends Struct {2371 readonly accountTokenOwnershipLimit: Option<u32>;2372 readonly sponsoredDataSize: Option<u32>;2373 readonly sponsoredDataRateLimit: Option<UpDataStructsSponsoringRateLimit>;2374 readonly tokenLimit: Option<u32>;2375 readonly sponsorTransferTimeout: Option<u32>;2376 readonly sponsorApproveTimeout: Option<u32>;2377 readonly ownerCanTransfer: Option<bool>;2378 readonly ownerCanDestroy: Option<bool>;2379 readonly transfersEnabled: Option<bool>;2380}23812382/** @name UpDataStructsCollectionMode */2383export interface UpDataStructsCollectionMode extends Enum {2384 readonly isNft: boolean;2385 readonly isFungible: boolean;2386 readonly asFungible: u8;2387 readonly isReFungible: boolean;2388 readonly type: 'Nft' | 'Fungible' | 'ReFungible';2389}23902391/** @name UpDataStructsCollectionPermissions */2392export interface UpDataStructsCollectionPermissions extends Struct {2393 readonly access: Option<UpDataStructsAccessMode>;2394 readonly mintMode: Option<bool>;2395 readonly nesting: Option<UpDataStructsNestingPermissions>;2396}23972398/** @name UpDataStructsCollectionStats */2399export interface UpDataStructsCollectionStats extends Struct {2400 readonly created: u32;2401 readonly destroyed: u32;2402 readonly alive: u32;2403}24042405/** @name UpDataStructsCreateCollectionData */2406export interface UpDataStructsCreateCollectionData extends Struct {2407 readonly mode: UpDataStructsCollectionMode;2408 readonly access: Option<UpDataStructsAccessMode>;2409 readonly name: Vec<u16>;2410 readonly description: Vec<u16>;2411 readonly tokenPrefix: Bytes;2412 readonly pendingSponsor: Option<AccountId32>;2413 readonly limits: Option<UpDataStructsCollectionLimits>;2414 readonly permissions: Option<UpDataStructsCollectionPermissions>;2415 readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;2416 readonly properties: Vec<UpDataStructsProperty>;2417}24182419/** @name UpDataStructsCreateFungibleData */2420export interface UpDataStructsCreateFungibleData extends Struct {2421 readonly value: u128;2422}24232424/** @name UpDataStructsCreateItemData */2425export interface UpDataStructsCreateItemData extends Enum {2426 readonly isNft: boolean;2427 readonly asNft: UpDataStructsCreateNftData;2428 readonly isFungible: boolean;2429 readonly asFungible: UpDataStructsCreateFungibleData;2430 readonly isReFungible: boolean;2431 readonly asReFungible: UpDataStructsCreateReFungibleData;2432 readonly type: 'Nft' | 'Fungible' | 'ReFungible';2433}24342435/** @name UpDataStructsCreateItemExData */2436export interface UpDataStructsCreateItemExData extends Enum {2437 readonly isNft: boolean;2438 readonly asNft: Vec<UpDataStructsCreateNftExData>;2439 readonly isFungible: boolean;2440 readonly asFungible: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr,u128>;2441 readonly isRefungibleMultipleItems: boolean;2442 readonly asRefungibleMultipleItems: Vec<UpDataStructsCreateRefungibleExSingleOwner>;2443 readonly isRefungibleMultipleOwners: boolean;2444 readonly asRefungibleMultipleOwners: UpDataStructsCreateRefungibleExMultipleOwners;2445 readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';2446}24472448/** @name UpDataStructsCreateNftData */2449export interface UpDataStructsCreateNftData extends Struct {2450 readonly properties: Vec<UpDataStructsProperty>;2451}24522453/** @name UpDataStructsCreateNftExData */2454export interface UpDataStructsCreateNftExData extends Struct {2455 readonly properties: Vec<UpDataStructsProperty>;2456 readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;2457}24582459/** @name UpDataStructsCreateReFungibleData */2460export interface UpDataStructsCreateReFungibleData extends Struct {2461 readonly pieces: u128;2462 readonly properties: Vec<UpDataStructsProperty>;2463}24642465/** @name UpDataStructsCreateRefungibleExMultipleOwners */2466export interface UpDataStructsCreateRefungibleExMultipleOwners extends Struct {2467 readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;2468 readonly properties: Vec<UpDataStructsProperty>;2469}24702471/** @name UpDataStructsCreateRefungibleExSingleOwner */2472export interface UpDataStructsCreateRefungibleExSingleOwner extends Struct {2473 readonly user: PalletEvmAccountBasicCrossAccountIdRepr;2474 readonly pieces: u128;2475 readonly properties: Vec<UpDataStructsProperty>;2476}24772478/** @name UpDataStructsNestingPermissions */2479export interface UpDataStructsNestingPermissions extends Struct {2480 readonly tokenOwner: bool;2481 readonly collectionAdmin: bool;2482 readonly restricted: Option<UpDataStructsOwnerRestrictedSet>;2483}24842485/** @name UpDataStructsOwnerRestrictedSet */2486export interface UpDataStructsOwnerRestrictedSet extends BTreeSet<u32> {}24872488/** @name UpDataStructsProperties */2489export interface UpDataStructsProperties extends Struct {2490 readonly map: UpDataStructsPropertiesMapBoundedVec;2491 readonly consumedSpace: u32;2492 readonly spaceLimit: u32;2493}24942495/** @name UpDataStructsPropertiesMapBoundedVec */2496export interface UpDataStructsPropertiesMapBoundedVec extends BTreeMap<Bytes, Bytes> {}24972498/** @name UpDataStructsPropertiesMapPropertyPermission */2499export interface UpDataStructsPropertiesMapPropertyPermission extends BTreeMap<Bytes, UpDataStructsPropertyPermission> {}25002501/** @name UpDataStructsProperty */2502export interface UpDataStructsProperty extends Struct {2503 readonly key: Bytes;2504 readonly value: Bytes;2505}25062507/** @name UpDataStructsPropertyKeyPermission */2508export interface UpDataStructsPropertyKeyPermission extends Struct {2509 readonly key: Bytes;2510 readonly permission: UpDataStructsPropertyPermission;2511}25122513/** @name UpDataStructsPropertyPermission */2514export interface UpDataStructsPropertyPermission extends Struct {2515 readonly mutable: bool;2516 readonly collectionAdmin: bool;2517 readonly tokenOwner: bool;2518}25192520/** @name UpDataStructsPropertyScope */2521export interface UpDataStructsPropertyScope extends Enum {2522 readonly isNone: boolean;2523 readonly isRmrk: boolean;2524 readonly isEth: boolean;2525 readonly type: 'None' | 'Rmrk' | 'Eth';2526}25272528/** @name UpDataStructsRpcCollection */2529export interface UpDataStructsRpcCollection extends Struct {2530 readonly owner: AccountId32;2531 readonly mode: UpDataStructsCollectionMode;2532 readonly name: Vec<u16>;2533 readonly description: Vec<u16>;2534 readonly tokenPrefix: Bytes;2535 readonly sponsorship: UpDataStructsSponsorshipState;2536 readonly limits: UpDataStructsCollectionLimits;2537 readonly permissions: UpDataStructsCollectionPermissions;2538 readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;2539 readonly properties: Vec<UpDataStructsProperty>;2540 readonly readOnly: bool;2541}25422543/** @name UpDataStructsSponsoringRateLimit */2544export interface UpDataStructsSponsoringRateLimit extends Enum {2545 readonly isSponsoringDisabled: boolean;2546 readonly isBlocks: boolean;2547 readonly asBlocks: u32;2548 readonly type: 'SponsoringDisabled' | 'Blocks';2549}25502551/** @name UpDataStructsSponsorshipState */2552export interface UpDataStructsSponsorshipState extends Enum {2553 readonly isDisabled: boolean;2554 readonly isUnconfirmed: boolean;2555 readonly asUnconfirmed: AccountId32;2556 readonly isConfirmed: boolean;2557 readonly asConfirmed: AccountId32;2558 readonly type: 'Disabled' | 'Unconfirmed' | 'Confirmed';2559}25602561/** @name UpDataStructsTokenChild */2562export interface UpDataStructsTokenChild extends Struct {2563 readonly token: u32;2564 readonly collection: u32;2565}25662567/** @name UpDataStructsTokenData */2568export interface UpDataStructsTokenData extends Struct {2569 readonly properties: Vec<UpDataStructsProperty>;2570 readonly owner: Option<PalletEvmAccountBasicCrossAccountIdRepr>;2571 readonly pieces: u128;2572}25732574/** @name XcmDoubleEncoded */2575export interface XcmDoubleEncoded extends Struct {2576 readonly encoded: Bytes;2577}25782579/** @name XcmV0Junction */2580export interface XcmV0Junction extends Enum {2581 readonly isParent: boolean;2582 readonly isParachain: boolean;2583 readonly asParachain: Compact<u32>;2584 readonly isAccountId32: boolean;2585 readonly asAccountId32: {2586 readonly network: XcmV0JunctionNetworkId;2587 readonly id: U8aFixed;2588 } & Struct;2589 readonly isAccountIndex64: boolean;2590 readonly asAccountIndex64: {2591 readonly network: XcmV0JunctionNetworkId;2592 readonly index: Compact<u64>;2593 } & Struct;2594 readonly isAccountKey20: boolean;2595 readonly asAccountKey20: {2596 readonly network: XcmV0JunctionNetworkId;2597 readonly key: U8aFixed;2598 } & Struct;2599 readonly isPalletInstance: boolean;2600 readonly asPalletInstance: u8;2601 readonly isGeneralIndex: boolean;2602 readonly asGeneralIndex: Compact<u128>;2603 readonly isGeneralKey: boolean;2604 readonly asGeneralKey: Bytes;2605 readonly isOnlyChild: boolean;2606 readonly isPlurality: boolean;2607 readonly asPlurality: {2608 readonly id: XcmV0JunctionBodyId;2609 readonly part: XcmV0JunctionBodyPart;2610 } & Struct;2611 readonly type: 'Parent' | 'Parachain' | 'AccountId32' | 'AccountIndex64' | 'AccountKey20' | 'PalletInstance' | 'GeneralIndex' | 'GeneralKey' | 'OnlyChild' | 'Plurality';2612}26132614/** @name XcmV0JunctionBodyId */2615export interface XcmV0JunctionBodyId extends Enum {2616 readonly isUnit: boolean;2617 readonly isNamed: boolean;2618 readonly asNamed: Bytes;2619 readonly isIndex: boolean;2620 readonly asIndex: Compact<u32>;2621 readonly isExecutive: boolean;2622 readonly isTechnical: boolean;2623 readonly isLegislative: boolean;2624 readonly isJudicial: boolean;2625 readonly type: 'Unit' | 'Named' | 'Index' | 'Executive' | 'Technical' | 'Legislative' | 'Judicial';2626}26272628/** @name XcmV0JunctionBodyPart */2629export interface XcmV0JunctionBodyPart extends Enum {2630 readonly isVoice: boolean;2631 readonly isMembers: boolean;2632 readonly asMembers: {2633 readonly count: Compact<u32>;2634 } & Struct;2635 readonly isFraction: boolean;2636 readonly asFraction: {2637 readonly nom: Compact<u32>;2638 readonly denom: Compact<u32>;2639 } & Struct;2640 readonly isAtLeastProportion: boolean;2641 readonly asAtLeastProportion: {2642 readonly nom: Compact<u32>;2643 readonly denom: Compact<u32>;2644 } & Struct;2645 readonly isMoreThanProportion: boolean;2646 readonly asMoreThanProportion: {2647 readonly nom: Compact<u32>;2648 readonly denom: Compact<u32>;2649 } & Struct;2650 readonly type: 'Voice' | 'Members' | 'Fraction' | 'AtLeastProportion' | 'MoreThanProportion';2651}26522653/** @name XcmV0JunctionNetworkId */2654export interface XcmV0JunctionNetworkId extends Enum {2655 readonly isAny: boolean;2656 readonly isNamed: boolean;2657 readonly asNamed: Bytes;2658 readonly isPolkadot: boolean;2659 readonly isKusama: boolean;2660 readonly type: 'Any' | 'Named' | 'Polkadot' | 'Kusama';2661}26622663/** @name XcmV0MultiAsset */2664export interface XcmV0MultiAsset extends Enum {2665 readonly isNone: boolean;2666 readonly isAll: boolean;2667 readonly isAllFungible: boolean;2668 readonly isAllNonFungible: boolean;2669 readonly isAllAbstractFungible: boolean;2670 readonly asAllAbstractFungible: {2671 readonly id: Bytes;2672 } & Struct;2673 readonly isAllAbstractNonFungible: boolean;2674 readonly asAllAbstractNonFungible: {2675 readonly class: Bytes;2676 } & Struct;2677 readonly isAllConcreteFungible: boolean;2678 readonly asAllConcreteFungible: {2679 readonly id: XcmV0MultiLocation;2680 } & Struct;2681 readonly isAllConcreteNonFungible: boolean;2682 readonly asAllConcreteNonFungible: {2683 readonly class: XcmV0MultiLocation;2684 } & Struct;2685 readonly isAbstractFungible: boolean;2686 readonly asAbstractFungible: {2687 readonly id: Bytes;2688 readonly amount: Compact<u128>;2689 } & Struct;2690 readonly isAbstractNonFungible: boolean;2691 readonly asAbstractNonFungible: {2692 readonly class: Bytes;2693 readonly instance: XcmV1MultiassetAssetInstance;2694 } & Struct;2695 readonly isConcreteFungible: boolean;2696 readonly asConcreteFungible: {2697 readonly id: XcmV0MultiLocation;2698 readonly amount: Compact<u128>;2699 } & Struct;2700 readonly isConcreteNonFungible: boolean;2701 readonly asConcreteNonFungible: {2702 readonly class: XcmV0MultiLocation;2703 readonly instance: XcmV1MultiassetAssetInstance;2704 } & Struct;2705 readonly type: 'None' | 'All' | 'AllFungible' | 'AllNonFungible' | 'AllAbstractFungible' | 'AllAbstractNonFungible' | 'AllConcreteFungible' | 'AllConcreteNonFungible' | 'AbstractFungible' | 'AbstractNonFungible' | 'ConcreteFungible' | 'ConcreteNonFungible';2706}27072708/** @name XcmV0MultiLocation */2709export interface XcmV0MultiLocation extends Enum {2710 readonly isNull: boolean;2711 readonly isX1: boolean;2712 readonly asX1: XcmV0Junction;2713 readonly isX2: boolean;2714 readonly asX2: ITuple<[XcmV0Junction, XcmV0Junction]>;2715 readonly isX3: boolean;2716 readonly asX3: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2717 readonly isX4: boolean;2718 readonly asX4: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2719 readonly isX5: boolean;2720 readonly asX5: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2721 readonly isX6: boolean;2722 readonly asX6: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2723 readonly isX7: boolean;2724 readonly asX7: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2725 readonly isX8: boolean;2726 readonly asX8: ITuple<[XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction, XcmV0Junction]>;2727 readonly type: 'Null' | 'X1' | 'X2' | 'X3' | 'X4' | 'X5' | 'X6' | 'X7' | 'X8';2728}27292730/** @name XcmV0Order */2731export interface XcmV0Order extends Enum {2732 readonly isNull: boolean;2733 readonly isDepositAsset: boolean;2734 readonly asDepositAsset: {2735 readonly assets: Vec<XcmV0MultiAsset>;2736 readonly dest: XcmV0MultiLocation;2737 } & Struct;2738 readonly isDepositReserveAsset: boolean;2739 readonly asDepositReserveAsset: {2740 readonly assets: Vec<XcmV0MultiAsset>;2741 readonly dest: XcmV0MultiLocation;2742 readonly effects: Vec<XcmV0Order>;2743 } & Struct;2744 readonly isExchangeAsset: boolean;2745 readonly asExchangeAsset: {2746 readonly give: Vec<XcmV0MultiAsset>;2747 readonly receive: Vec<XcmV0MultiAsset>;2748 } & Struct;2749 readonly isInitiateReserveWithdraw: boolean;2750 readonly asInitiateReserveWithdraw: {2751 readonly assets: Vec<XcmV0MultiAsset>;2752 readonly reserve: XcmV0MultiLocation;2753 readonly effects: Vec<XcmV0Order>;2754 } & Struct;2755 readonly isInitiateTeleport: boolean;2756 readonly asInitiateTeleport: {2757 readonly assets: Vec<XcmV0MultiAsset>;2758 readonly dest: XcmV0MultiLocation;2759 readonly effects: Vec<XcmV0Order>;2760 } & Struct;2761 readonly isQueryHolding: boolean;2762 readonly asQueryHolding: {2763 readonly queryId: Compact<u64>;2764 readonly dest: XcmV0MultiLocation;2765 readonly assets: Vec<XcmV0MultiAsset>;2766 } & Struct;2767 readonly isBuyExecution: boolean;2768 readonly asBuyExecution: {2769 readonly fees: XcmV0MultiAsset;2770 readonly weight: u64;2771 readonly debt: u64;2772 readonly haltOnError: bool;2773 readonly xcm: Vec<XcmV0Xcm>;2774 } & Struct;2775 readonly type: 'Null' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';2776}27772778/** @name XcmV0OriginKind */2779export interface XcmV0OriginKind extends Enum {2780 readonly isNative: boolean;2781 readonly isSovereignAccount: boolean;2782 readonly isSuperuser: boolean;2783 readonly isXcm: boolean;2784 readonly type: 'Native' | 'SovereignAccount' | 'Superuser' | 'Xcm';2785}27862787/** @name XcmV0Response */2788export interface XcmV0Response extends Enum {2789 readonly isAssets: boolean;2790 readonly asAssets: Vec<XcmV0MultiAsset>;2791 readonly type: 'Assets';2792}27932794/** @name XcmV0Xcm */2795export interface XcmV0Xcm extends Enum {2796 readonly isWithdrawAsset: boolean;2797 readonly asWithdrawAsset: {2798 readonly assets: Vec<XcmV0MultiAsset>;2799 readonly effects: Vec<XcmV0Order>;2800 } & Struct;2801 readonly isReserveAssetDeposit: boolean;2802 readonly asReserveAssetDeposit: {2803 readonly assets: Vec<XcmV0MultiAsset>;2804 readonly effects: Vec<XcmV0Order>;2805 } & Struct;2806 readonly isTeleportAsset: boolean;2807 readonly asTeleportAsset: {2808 readonly assets: Vec<XcmV0MultiAsset>;2809 readonly effects: Vec<XcmV0Order>;2810 } & Struct;2811 readonly isQueryResponse: boolean;2812 readonly asQueryResponse: {2813 readonly queryId: Compact<u64>;2814 readonly response: XcmV0Response;2815 } & Struct;2816 readonly isTransferAsset: boolean;2817 readonly asTransferAsset: {2818 readonly assets: Vec<XcmV0MultiAsset>;2819 readonly dest: XcmV0MultiLocation;2820 } & Struct;2821 readonly isTransferReserveAsset: boolean;2822 readonly asTransferReserveAsset: {2823 readonly assets: Vec<XcmV0MultiAsset>;2824 readonly dest: XcmV0MultiLocation;2825 readonly effects: Vec<XcmV0Order>;2826 } & Struct;2827 readonly isTransact: boolean;2828 readonly asTransact: {2829 readonly originType: XcmV0OriginKind;2830 readonly requireWeightAtMost: u64;2831 readonly call: XcmDoubleEncoded;2832 } & Struct;2833 readonly isHrmpNewChannelOpenRequest: boolean;2834 readonly asHrmpNewChannelOpenRequest: {2835 readonly sender: Compact<u32>;2836 readonly maxMessageSize: Compact<u32>;2837 readonly maxCapacity: Compact<u32>;2838 } & Struct;2839 readonly isHrmpChannelAccepted: boolean;2840 readonly asHrmpChannelAccepted: {2841 readonly recipient: Compact<u32>;2842 } & Struct;2843 readonly isHrmpChannelClosing: boolean;2844 readonly asHrmpChannelClosing: {2845 readonly initiator: Compact<u32>;2846 readonly sender: Compact<u32>;2847 readonly recipient: Compact<u32>;2848 } & Struct;2849 readonly isRelayedFrom: boolean;2850 readonly asRelayedFrom: {2851 readonly who: XcmV0MultiLocation;2852 readonly message: XcmV0Xcm;2853 } & Struct;2854 readonly type: 'WithdrawAsset' | 'ReserveAssetDeposit' | 'TeleportAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom';2855}28562857/** @name XcmV1Junction */2858export interface XcmV1Junction extends Enum {2859 readonly isParachain: boolean;2860 readonly asParachain: Compact<u32>;2861 readonly isAccountId32: boolean;2862 readonly asAccountId32: {2863 readonly network: XcmV0JunctionNetworkId;2864 readonly id: U8aFixed;2865 } & Struct;2866 readonly isAccountIndex64: boolean;2867 readonly asAccountIndex64: {2868 readonly network: XcmV0JunctionNetworkId;2869 readonly index: Compact<u64>;2870 } & Struct;2871 readonly isAccountKey20: boolean;2872 readonly asAccountKey20: {2873 readonly network: XcmV0JunctionNetworkId;2874 readonly key: U8aFixed;2875 } & Struct;2876 readonly isPalletInstance: boolean;2877 readonly asPalletInstance: u8;2878 readonly isGeneralIndex: boolean;2879 readonly asGeneralIndex: Compact<u128>;2880 readonly isGeneralKey: boolean;2881 readonly asGeneralKey: Bytes;2882 readonly isOnlyChild: boolean;2883 readonly isPlurality: boolean;2884 readonly asPlurality: {2885 readonly id: XcmV0JunctionBodyId;2886 readonly part: XcmV0JunctionBodyPart;2887 } & Struct;2888 readonly type: 'Parachain' | 'AccountId32' | 'AccountIndex64' | 'AccountKey20' | 'PalletInstance' | 'GeneralIndex' | 'GeneralKey' | 'OnlyChild' | 'Plurality';2889}28902891/** @name XcmV1MultiAsset */2892export interface XcmV1MultiAsset extends Struct {2893 readonly id: XcmV1MultiassetAssetId;2894 readonly fun: XcmV1MultiassetFungibility;2895}28962897/** @name XcmV1MultiassetAssetId */2898export interface XcmV1MultiassetAssetId extends Enum {2899 readonly isConcrete: boolean;2900 readonly asConcrete: XcmV1MultiLocation;2901 readonly isAbstract: boolean;2902 readonly asAbstract: Bytes;2903 readonly type: 'Concrete' | 'Abstract';2904}29052906/** @name XcmV1MultiassetAssetInstance */2907export interface XcmV1MultiassetAssetInstance extends Enum {2908 readonly isUndefined: boolean;2909 readonly isIndex: boolean;2910 readonly asIndex: Compact<u128>;2911 readonly isArray4: boolean;2912 readonly asArray4: U8aFixed;2913 readonly isArray8: boolean;2914 readonly asArray8: U8aFixed;2915 readonly isArray16: boolean;2916 readonly asArray16: U8aFixed;2917 readonly isArray32: boolean;2918 readonly asArray32: U8aFixed;2919 readonly isBlob: boolean;2920 readonly asBlob: Bytes;2921 readonly type: 'Undefined' | 'Index' | 'Array4' | 'Array8' | 'Array16' | 'Array32' | 'Blob';2922}29232924/** @name XcmV1MultiassetFungibility */2925export interface XcmV1MultiassetFungibility extends Enum {2926 readonly isFungible: boolean;2927 readonly asFungible: Compact<u128>;2928 readonly isNonFungible: boolean;2929 readonly asNonFungible: XcmV1MultiassetAssetInstance;2930 readonly type: 'Fungible' | 'NonFungible';2931}29322933/** @name XcmV1MultiassetMultiAssetFilter */2934export interface XcmV1MultiassetMultiAssetFilter extends Enum {2935 readonly isDefinite: boolean;2936 readonly asDefinite: XcmV1MultiassetMultiAssets;2937 readonly isWild: boolean;2938 readonly asWild: XcmV1MultiassetWildMultiAsset;2939 readonly type: 'Definite' | 'Wild';2940}29412942/** @name XcmV1MultiassetMultiAssets */2943export interface XcmV1MultiassetMultiAssets extends Vec<XcmV1MultiAsset> {}29442945/** @name XcmV1MultiassetWildFungibility */2946export interface XcmV1MultiassetWildFungibility extends Enum {2947 readonly isFungible: boolean;2948 readonly isNonFungible: boolean;2949 readonly type: 'Fungible' | 'NonFungible';2950}29512952/** @name XcmV1MultiassetWildMultiAsset */2953export interface XcmV1MultiassetWildMultiAsset extends Enum {2954 readonly isAll: boolean;2955 readonly isAllOf: boolean;2956 readonly asAllOf: {2957 readonly id: XcmV1MultiassetAssetId;2958 readonly fun: XcmV1MultiassetWildFungibility;2959 } & Struct;2960 readonly type: 'All' | 'AllOf';2961}29622963/** @name XcmV1MultiLocation */2964export interface XcmV1MultiLocation extends Struct {2965 readonly parents: u8;2966 readonly interior: XcmV1MultilocationJunctions;2967}29682969/** @name XcmV1MultilocationJunctions */2970export interface XcmV1MultilocationJunctions extends Enum {2971 readonly isHere: boolean;2972 readonly isX1: boolean;2973 readonly asX1: XcmV1Junction;2974 readonly isX2: boolean;2975 readonly asX2: ITuple<[XcmV1Junction, XcmV1Junction]>;2976 readonly isX3: boolean;2977 readonly asX3: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2978 readonly isX4: boolean;2979 readonly asX4: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2980 readonly isX5: boolean;2981 readonly asX5: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2982 readonly isX6: boolean;2983 readonly asX6: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2984 readonly isX7: boolean;2985 readonly asX7: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2986 readonly isX8: boolean;2987 readonly asX8: ITuple<[XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction, XcmV1Junction]>;2988 readonly type: 'Here' | 'X1' | 'X2' | 'X3' | 'X4' | 'X5' | 'X6' | 'X7' | 'X8';2989}29902991/** @name XcmV1Order */2992export interface XcmV1Order extends Enum {2993 readonly isNoop: boolean;2994 readonly isDepositAsset: boolean;2995 readonly asDepositAsset: {2996 readonly assets: XcmV1MultiassetMultiAssetFilter;2997 readonly maxAssets: u32;2998 readonly beneficiary: XcmV1MultiLocation;2999 } & Struct;3000 readonly isDepositReserveAsset: boolean;3001 readonly asDepositReserveAsset: {3002 readonly assets: XcmV1MultiassetMultiAssetFilter;3003 readonly maxAssets: u32;3004 readonly dest: XcmV1MultiLocation;3005 readonly effects: Vec<XcmV1Order>;3006 } & Struct;3007 readonly isExchangeAsset: boolean;3008 readonly asExchangeAsset: {3009 readonly give: XcmV1MultiassetMultiAssetFilter;3010 readonly receive: XcmV1MultiassetMultiAssets;3011 } & Struct;3012 readonly isInitiateReserveWithdraw: boolean;3013 readonly asInitiateReserveWithdraw: {3014 readonly assets: XcmV1MultiassetMultiAssetFilter;3015 readonly reserve: XcmV1MultiLocation;3016 readonly effects: Vec<XcmV1Order>;3017 } & Struct;3018 readonly isInitiateTeleport: boolean;3019 readonly asInitiateTeleport: {3020 readonly assets: XcmV1MultiassetMultiAssetFilter;3021 readonly dest: XcmV1MultiLocation;3022 readonly effects: Vec<XcmV1Order>;3023 } & Struct;3024 readonly isQueryHolding: boolean;3025 readonly asQueryHolding: {3026 readonly queryId: Compact<u64>;3027 readonly dest: XcmV1MultiLocation;3028 readonly assets: XcmV1MultiassetMultiAssetFilter;3029 } & Struct;3030 readonly isBuyExecution: boolean;3031 readonly asBuyExecution: {3032 readonly fees: XcmV1MultiAsset;3033 readonly weight: u64;3034 readonly debt: u64;3035 readonly haltOnError: bool;3036 readonly instructions: Vec<XcmV1Xcm>;3037 } & Struct;3038 readonly type: 'Noop' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';3039}30403041/** @name XcmV1Response */3042export interface XcmV1Response extends Enum {3043 readonly isAssets: boolean;3044 readonly asAssets: XcmV1MultiassetMultiAssets;3045 readonly isVersion: boolean;3046 readonly asVersion: u32;3047 readonly type: 'Assets' | 'Version';3048}30493050/** @name XcmV1Xcm */3051export interface XcmV1Xcm extends Enum {3052 readonly isWithdrawAsset: boolean;3053 readonly asWithdrawAsset: {3054 readonly assets: XcmV1MultiassetMultiAssets;3055 readonly effects: Vec<XcmV1Order>;3056 } & Struct;3057 readonly isReserveAssetDeposited: boolean;3058 readonly asReserveAssetDeposited: {3059 readonly assets: XcmV1MultiassetMultiAssets;3060 readonly effects: Vec<XcmV1Order>;3061 } & Struct;3062 readonly isReceiveTeleportedAsset: boolean;3063 readonly asReceiveTeleportedAsset: {3064 readonly assets: XcmV1MultiassetMultiAssets;3065 readonly effects: Vec<XcmV1Order>;3066 } & Struct;3067 readonly isQueryResponse: boolean;3068 readonly asQueryResponse: {3069 readonly queryId: Compact<u64>;3070 readonly response: XcmV1Response;3071 } & Struct;3072 readonly isTransferAsset: boolean;3073 readonly asTransferAsset: {3074 readonly assets: XcmV1MultiassetMultiAssets;3075 readonly beneficiary: XcmV1MultiLocation;3076 } & Struct;3077 readonly isTransferReserveAsset: boolean;3078 readonly asTransferReserveAsset: {3079 readonly assets: XcmV1MultiassetMultiAssets;3080 readonly dest: XcmV1MultiLocation;3081 readonly effects: Vec<XcmV1Order>;3082 } & Struct;3083 readonly isTransact: boolean;3084 readonly asTransact: {3085 readonly originType: XcmV0OriginKind;3086 readonly requireWeightAtMost: u64;3087 readonly call: XcmDoubleEncoded;3088 } & Struct;3089 readonly isHrmpNewChannelOpenRequest: boolean;3090 readonly asHrmpNewChannelOpenRequest: {3091 readonly sender: Compact<u32>;3092 readonly maxMessageSize: Compact<u32>;3093 readonly maxCapacity: Compact<u32>;3094 } & Struct;3095 readonly isHrmpChannelAccepted: boolean;3096 readonly asHrmpChannelAccepted: {3097 readonly recipient: Compact<u32>;3098 } & Struct;3099 readonly isHrmpChannelClosing: boolean;3100 readonly asHrmpChannelClosing: {3101 readonly initiator: Compact<u32>;3102 readonly sender: Compact<u32>;3103 readonly recipient: Compact<u32>;3104 } & Struct;3105 readonly isRelayedFrom: boolean;3106 readonly asRelayedFrom: {3107 readonly who: XcmV1MultilocationJunctions;3108 readonly message: XcmV1Xcm;3109 } & Struct;3110 readonly isSubscribeVersion: boolean;3111 readonly asSubscribeVersion: {3112 readonly queryId: Compact<u64>;3113 readonly maxResponseWeight: Compact<u64>;3114 } & Struct;3115 readonly isUnsubscribeVersion: boolean;3116 readonly type: 'WithdrawAsset' | 'ReserveAssetDeposited' | 'ReceiveTeleportedAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom' | 'SubscribeVersion' | 'UnsubscribeVersion';3117}31183119/** @name XcmV2Instruction */3120export interface XcmV2Instruction extends Enum {3121 readonly isWithdrawAsset: boolean;3122 readonly asWithdrawAsset: XcmV1MultiassetMultiAssets;3123 readonly isReserveAssetDeposited: boolean;3124 readonly asReserveAssetDeposited: XcmV1MultiassetMultiAssets;3125 readonly isReceiveTeleportedAsset: boolean;3126 readonly asReceiveTeleportedAsset: XcmV1MultiassetMultiAssets;3127 readonly isQueryResponse: boolean;3128 readonly asQueryResponse: {3129 readonly queryId: Compact<u64>;3130 readonly response: XcmV2Response;3131 readonly maxWeight: Compact<u64>;3132 } & Struct;3133 readonly isTransferAsset: boolean;3134 readonly asTransferAsset: {3135 readonly assets: XcmV1MultiassetMultiAssets;3136 readonly beneficiary: XcmV1MultiLocation;3137 } & Struct;3138 readonly isTransferReserveAsset: boolean;3139 readonly asTransferReserveAsset: {3140 readonly assets: XcmV1MultiassetMultiAssets;3141 readonly dest: XcmV1MultiLocation;3142 readonly xcm: XcmV2Xcm;3143 } & Struct;3144 readonly isTransact: boolean;3145 readonly asTransact: {3146 readonly originType: XcmV0OriginKind;3147 readonly requireWeightAtMost: Compact<u64>;3148 readonly call: XcmDoubleEncoded;3149 } & Struct;3150 readonly isHrmpNewChannelOpenRequest: boolean;3151 readonly asHrmpNewChannelOpenRequest: {3152 readonly sender: Compact<u32>;3153 readonly maxMessageSize: Compact<u32>;3154 readonly maxCapacity: Compact<u32>;3155 } & Struct;3156 readonly isHrmpChannelAccepted: boolean;3157 readonly asHrmpChannelAccepted: {3158 readonly recipient: Compact<u32>;3159 } & Struct;3160 readonly isHrmpChannelClosing: boolean;3161 readonly asHrmpChannelClosing: {3162 readonly initiator: Compact<u32>;3163 readonly sender: Compact<u32>;3164 readonly recipient: Compact<u32>;3165 } & Struct;3166 readonly isClearOrigin: boolean;3167 readonly isDescendOrigin: boolean;3168 readonly asDescendOrigin: XcmV1MultilocationJunctions;3169 readonly isReportError: boolean;3170 readonly asReportError: {3171 readonly queryId: Compact<u64>;3172 readonly dest: XcmV1MultiLocation;3173 readonly maxResponseWeight: Compact<u64>;3174 } & Struct;3175 readonly isDepositAsset: boolean;3176 readonly asDepositAsset: {3177 readonly assets: XcmV1MultiassetMultiAssetFilter;3178 readonly maxAssets: Compact<u32>;3179 readonly beneficiary: XcmV1MultiLocation;3180 } & Struct;3181 readonly isDepositReserveAsset: boolean;3182 readonly asDepositReserveAsset: {3183 readonly assets: XcmV1MultiassetMultiAssetFilter;3184 readonly maxAssets: Compact<u32>;3185 readonly dest: XcmV1MultiLocation;3186 readonly xcm: XcmV2Xcm;3187 } & Struct;3188 readonly isExchangeAsset: boolean;3189 readonly asExchangeAsset: {3190 readonly give: XcmV1MultiassetMultiAssetFilter;3191 readonly receive: XcmV1MultiassetMultiAssets;3192 } & Struct;3193 readonly isInitiateReserveWithdraw: boolean;3194 readonly asInitiateReserveWithdraw: {3195 readonly assets: XcmV1MultiassetMultiAssetFilter;3196 readonly reserve: XcmV1MultiLocation;3197 readonly xcm: XcmV2Xcm;3198 } & Struct;3199 readonly isInitiateTeleport: boolean;3200 readonly asInitiateTeleport: {3201 readonly assets: XcmV1MultiassetMultiAssetFilter;3202 readonly dest: XcmV1MultiLocation;3203 readonly xcm: XcmV2Xcm;3204 } & Struct;3205 readonly isQueryHolding: boolean;3206 readonly asQueryHolding: {3207 readonly queryId: Compact<u64>;3208 readonly dest: XcmV1MultiLocation;3209 readonly assets: XcmV1MultiassetMultiAssetFilter;3210 readonly maxResponseWeight: Compact<u64>;3211 } & Struct;3212 readonly isBuyExecution: boolean;3213 readonly asBuyExecution: {3214 readonly fees: XcmV1MultiAsset;3215 readonly weightLimit: XcmV2WeightLimit;3216 } & Struct;3217 readonly isRefundSurplus: boolean;3218 readonly isSetErrorHandler: boolean;3219 readonly asSetErrorHandler: XcmV2Xcm;3220 readonly isSetAppendix: boolean;3221 readonly asSetAppendix: XcmV2Xcm;3222 readonly isClearError: boolean;3223 readonly isClaimAsset: boolean;3224 readonly asClaimAsset: {3225 readonly assets: XcmV1MultiassetMultiAssets;3226 readonly ticket: XcmV1MultiLocation;3227 } & Struct;3228 readonly isTrap: boolean;3229 readonly asTrap: Compact<u64>;3230 readonly isSubscribeVersion: boolean;3231 readonly asSubscribeVersion: {3232 readonly queryId: Compact<u64>;3233 readonly maxResponseWeight: Compact<u64>;3234 } & Struct;3235 readonly isUnsubscribeVersion: boolean;3236 readonly type: 'WithdrawAsset' | 'ReserveAssetDeposited' | 'ReceiveTeleportedAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'ClearOrigin' | 'DescendOrigin' | 'ReportError' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution' | 'RefundSurplus' | 'SetErrorHandler' | 'SetAppendix' | 'ClearError' | 'ClaimAsset' | 'Trap' | 'SubscribeVersion' | 'UnsubscribeVersion';3237}32383239/** @name XcmV2Response */3240export interface XcmV2Response extends Enum {3241 readonly isNull: boolean;3242 readonly isAssets: boolean;3243 readonly asAssets: XcmV1MultiassetMultiAssets;3244 readonly isExecutionResult: boolean;3245 readonly asExecutionResult: Option<ITuple<[u32, XcmV2TraitsError]>>;3246 readonly isVersion: boolean;3247 readonly asVersion: u32;3248 readonly type: 'Null' | 'Assets' | 'ExecutionResult' | 'Version';3249}32503251/** @name XcmV2TraitsError */3252export interface XcmV2TraitsError extends Enum {3253 readonly isOverflow: boolean;3254 readonly isUnimplemented: boolean;3255 readonly isUntrustedReserveLocation: boolean;3256 readonly isUntrustedTeleportLocation: boolean;3257 readonly isMultiLocationFull: boolean;3258 readonly isMultiLocationNotInvertible: boolean;3259 readonly isBadOrigin: boolean;3260 readonly isInvalidLocation: boolean;3261 readonly isAssetNotFound: boolean;3262 readonly isFailedToTransactAsset: boolean;3263 readonly isNotWithdrawable: boolean;3264 readonly isLocationCannotHold: boolean;3265 readonly isExceedsMaxMessageSize: boolean;3266 readonly isDestinationUnsupported: boolean;3267 readonly isTransport: boolean;3268 readonly isUnroutable: boolean;3269 readonly isUnknownClaim: boolean;3270 readonly isFailedToDecode: boolean;3271 readonly isMaxWeightInvalid: boolean;3272 readonly isNotHoldingFees: boolean;3273 readonly isTooExpensive: boolean;3274 readonly isTrap: boolean;3275 readonly asTrap: u64;3276 readonly isUnhandledXcmVersion: boolean;3277 readonly isWeightLimitReached: boolean;3278 readonly asWeightLimitReached: u64;3279 readonly isBarrier: boolean;3280 readonly isWeightNotComputable: boolean;3281 readonly type: 'Overflow' | 'Unimplemented' | 'UntrustedReserveLocation' | 'UntrustedTeleportLocation' | 'MultiLocationFull' | 'MultiLocationNotInvertible' | 'BadOrigin' | 'InvalidLocation' | 'AssetNotFound' | 'FailedToTransactAsset' | 'NotWithdrawable' | 'LocationCannotHold' | 'ExceedsMaxMessageSize' | 'DestinationUnsupported' | 'Transport' | 'Unroutable' | 'UnknownClaim' | 'FailedToDecode' | 'MaxWeightInvalid' | 'NotHoldingFees' | 'TooExpensive' | 'Trap' | 'UnhandledXcmVersion' | 'WeightLimitReached' | 'Barrier' | 'WeightNotComputable';3282}32833284/** @name XcmV2TraitsOutcome */3285export interface XcmV2TraitsOutcome extends Enum {3286 readonly isComplete: boolean;3287 readonly asComplete: u64;3288 readonly isIncomplete: boolean;3289 readonly asIncomplete: ITuple<[u64, XcmV2TraitsError]>;3290 readonly isError: boolean;3291 readonly asError: XcmV2TraitsError;3292 readonly type: 'Complete' | 'Incomplete' | 'Error';3293}32943295/** @name XcmV2WeightLimit */3296export interface XcmV2WeightLimit extends Enum {3297 readonly isUnlimited: boolean;3298 readonly isLimited: boolean;3299 readonly asLimited: Compact<u64>;3300 readonly type: 'Unlimited' | 'Limited';3301}33023303/** @name XcmV2Xcm */3304export interface XcmV2Xcm extends Vec<XcmV2Instruction> {}33053306/** @name XcmVersionedMultiAssets */3307export interface XcmVersionedMultiAssets extends Enum {3308 readonly isV0: boolean;3309 readonly asV0: Vec<XcmV0MultiAsset>;3310 readonly isV1: boolean;3311 readonly asV1: XcmV1MultiassetMultiAssets;3312 readonly type: 'V0' | 'V1';3313}33143315/** @name XcmVersionedMultiLocation */3316export interface XcmVersionedMultiLocation extends Enum {3317 readonly isV0: boolean;3318 readonly asV0: XcmV0MultiLocation;3319 readonly isV1: boolean;3320 readonly asV1: XcmV1MultiLocation;3321 readonly type: 'V0' | 'V1';3322}33233324/** @name XcmVersionedXcm */3325export interface XcmVersionedXcm extends Enum {3326 readonly isV0: boolean;3327 readonly asV0: XcmV0Xcm;3328 readonly isV1: boolean;3329 readonly asV1: XcmV1Xcm;3330 readonly isV2: boolean;3331 readonly asV2: XcmV2Xcm;3332 readonly type: 'V0' | 'V1' | 'V2';3333}33343335export type PHANTOM_DEFAULT = 'default';tests/src/interfaces/lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -2978,7 +2978,7 @@
* Lookup397: up_data_structs::PropertyScope
**/
UpDataStructsPropertyScope: {
- _enum: ['None', 'Rmrk']
+ _enum: ['None', 'Rmrk', 'Eth']
},
/**
* Lookup399: pallet_nonfungible::pallet::Error<T>
tests/src/interfaces/types-lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -3126,7 +3126,8 @@
export interface UpDataStructsPropertyScope extends Enum {
readonly isNone: boolean;
readonly isRmrk: boolean;
- readonly type: 'None' | 'Rmrk';
+ readonly isEth: boolean;
+ readonly type: 'None' | 'Rmrk' | 'Eth';
}
/** @name PalletNonfungibleError (399) */
tests/src/limits.test.tsdiffbeforeafterboth--- a/tests/src/limits.test.ts
+++ b/tests/src/limits.test.ts
@@ -27,6 +27,8 @@
transferExpectSuccess,
getFreeBalance,
waitNewBlocks, burnItemExpectSuccess,
+ requirePallets,
+ Pallets,
} from './util/helpers';
import {expect} from 'chai';
@@ -67,7 +69,9 @@
describe('Number of tokens per address (ReFungible)', () => {
let alice: IKeyringPair;
- before(async () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api, privateKeyWrapper) => {
alice = privateKeyWrapper('//Alice');
});
@@ -367,7 +371,9 @@
let bob: IKeyringPair;
let charlie: IKeyringPair;
- before(async () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api, privateKeyWrapper) => {
alice = privateKeyWrapper('//Alice');
bob = privateKeyWrapper('//Bob');
tests/src/nesting/nest.test.tsdiffbeforeafterboth--- a/tests/src/nesting/nest.test.ts
+++ b/tests/src/nesting/nest.test.ts
@@ -17,6 +17,8 @@
transferExpectSuccess,
transferFromExpectSuccess,
setCollectionLimitsExpectSuccess,
+ requirePallets,
+ Pallets,
} from '../util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
@@ -311,7 +313,9 @@
// ---------- Re-Fungible ----------
- it('ReFungible: allows an Owner to nest/unnest their token', async () => {
+ it('ReFungible: allows an Owner to nest/unnest their token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {tokenOwner: true}});
@@ -333,7 +337,9 @@
});
});
- it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async () => {
+ it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT', {Substrate: alice.address});
@@ -715,7 +721,9 @@
// ---------- Re-Fungible ----------
- it('ReFungible: disallows to nest token if nesting is disabled', async () => {
+ it('ReFungible: disallows to nest token if nesting is disabled', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {}});
@@ -745,7 +753,9 @@
});
});
- it('ReFungible: disallows a non-Owner to nest someone else\'s token', async () => {
+ it('ReFungible: disallows a non-Owner to nest someone else\'s token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {tokenOwner: true}});
@@ -773,7 +783,9 @@
});
});
- it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {
+ it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);
@@ -800,7 +812,9 @@
});
});
- it('ReFungible: disallows to nest token to an unlisted collection', async () => {
+ it('ReFungible: disallows to nest token to an unlisted collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {tokenOwner: true, restricted:[]}});
tests/src/nesting/properties.test.tsdiffbeforeafterboth--- a/tests/src/nesting/properties.test.ts
+++ b/tests/src/nesting/properties.test.ts
@@ -8,6 +8,8 @@
createItemExpectSuccess,
getCreateCollectionResult,
transferExpectSuccess,
+ requirePallets,
+ Pallets,
} from '../util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
import {tokenIdToAddress} from '../eth/util/helpers';
@@ -64,7 +66,9 @@
await testMakeSureSuppliesRequired({type: 'NFT'});
});
- it('Makes sure collectionById supplies required fields for ReFungible', async () => {
+ it('Makes sure collectionById supplies required fields for ReFungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testMakeSureSuppliesRequired({type: 'ReFungible'});
});
});
@@ -120,7 +124,9 @@
it('Sets properties for a NFT collection', async () => {
await testSetsPropertiesForCollection('NFT');
});
- it('Sets properties for a ReFungible collection', async () => {
+ it('Sets properties for a ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testSetsPropertiesForCollection('ReFungible');
});
@@ -178,7 +184,9 @@
it('Check valid names for NFT collection properties keys', async () => {
await testCheckValidNames('NFT');
});
- it('Check valid names for ReFungible collection properties keys', async () => {
+ it('Check valid names for ReFungible collection properties keys', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testCheckValidNames('ReFungible');
});
@@ -209,7 +217,9 @@
it('Changes properties of a NFT collection', async () => {
await testChangesProperties({type: 'NFT'});
});
- it('Changes properties of a ReFungible collection', async () => {
+ it('Changes properties of a ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testChangesProperties({type: 'ReFungible'});
});
@@ -238,7 +248,9 @@
it('Deletes properties of a NFT collection', async () => {
await testDeleteProperties({type: 'NFT'});
});
- it('Deletes properties of a ReFungible collection', async () => {
+ it('Deletes properties of a ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testDeleteProperties({type: 'ReFungible'});
});
});
@@ -269,7 +281,9 @@
it('Fails to set properties in a NFT collection if not its onwer/administrator', async () => {
await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'NFT'});
});
- it('Fails to set properties in a ReFungible collection if not its onwer/administrator', async () => {
+ it('Fails to set properties in a ReFungible collection if not its onwer/administrator', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'ReFungible'});
});
@@ -307,7 +321,9 @@
it('Fails to set properties that exceed the limits (NFT)', async () => {
await testFailsSetPropertiesThatExeedLimits({type: 'NFT'});
});
- it('Fails to set properties that exceed the limits (ReFungible)', async () => {
+ it('Fails to set properties that exceed the limits (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testFailsSetPropertiesThatExeedLimits({type: 'ReFungible'});
});
@@ -337,7 +353,9 @@
it('Fails to set more properties than it is allowed (NFT)', async () => {
await testFailsSetMorePropertiesThanAllowed({type: 'NFT'});
});
- it('Fails to set more properties than it is allowed (ReFungible)', async () => {
+ it('Fails to set more properties than it is allowed (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testFailsSetMorePropertiesThanAllowed({type: 'ReFungible'});
});
@@ -392,7 +410,9 @@
it('Fails to set properties with invalid names (NFT)', async () => {
await testFailsSetPropertiesWithInvalidNames({type: 'NFT'});
});
- it('Fails to set properties with invalid names (ReFungible)', async () => {
+ it('Fails to set properties with invalid names (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testFailsSetPropertiesWithInvalidNames({type: 'ReFungible'});
});
});
@@ -443,7 +463,9 @@
it('Sets access rights to properties of a collection (NFT)', async () => {
await testSetsAccessRightsToProperties({type: 'NFT'});
});
- it('Sets access rights to properties of a collection (ReFungible)', async () => {
+ it('Sets access rights to properties of a collection (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testSetsAccessRightsToProperties({type: 'ReFungible'});
});
@@ -472,7 +494,9 @@
it('Changes access rights to properties of a NFT collection', async () => {
await testChangesAccessRightsToProperty({type: 'NFT'});
});
- it('Changes access rights to properties of a ReFungible collection', async () => {
+ it('Changes access rights to properties of a ReFungible collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testChangesAccessRightsToProperty({type: 'ReFungible'});
});
});
@@ -502,7 +526,9 @@
it('Prevents from setting access rights to properties of a NFT collection if not an onwer/admin', async () => {
await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'NFT'});
});
- it('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', async () => {
+ it('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'ReFungible'});
});
@@ -531,7 +557,9 @@
it('Prevents from adding too many possible properties (NFT)', async () => {
await testPreventFromAddingTooManyPossibleProperties({type: 'NFT'});
});
- it('Prevents from adding too many possible properties (ReFungible)', async () => {
+ it('Prevents from adding too many possible properties (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testPreventFromAddingTooManyPossibleProperties({type: 'ReFungible'});
});
@@ -560,7 +588,9 @@
it('Prevents access rights to be modified if constant (NFT)', async () => {
await testPreventAccessRightsModifiedIfConstant({type: 'NFT'});
});
- it('Prevents access rights to be modified if constant (ReFungible)', async () => {
+ it('Prevents access rights to be modified if constant (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testPreventAccessRightsModifiedIfConstant({type: 'ReFungible'});
});
@@ -608,7 +638,9 @@
it('Prevents adding properties with invalid names (NFT)', async () => {
await testPreventsAddingPropertiesWithInvalidNames({type: 'NFT'});
});
- it('Prevents adding properties with invalid names (ReFungible)', async () => {
+ it('Prevents adding properties with invalid names (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testPreventsAddingPropertiesWithInvalidNames({type: 'ReFungible'});
});
});
@@ -651,7 +683,9 @@
it('Reads yet empty properties of a token (NFT)', async () => {
await testReadsYetEmptyProperties({type: 'NFT'});
});
- it('Reads yet empty properties of a token (ReFungible)', async () => {
+ it('Reads yet empty properties of a token (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testReadsYetEmptyProperties({type: 'ReFungible'});
});
@@ -696,7 +730,9 @@
it('Assigns properties to a token according to permissions (NFT)', async () => {
await testAssignPropertiesAccordingToPermissions({type: 'NFT'}, 1);
});
- it('Assigns properties to a token according to permissions (ReFungible)', async () => {
+ it('Assigns properties to a token according to permissions (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testAssignPropertiesAccordingToPermissions({type: 'ReFungible'}, 100);
});
@@ -749,7 +785,9 @@
it('Changes properties of a token according to permissions (NFT)', async () => {
await testChangesPropertiesAccordingPermission({type: 'NFT'}, 1);
});
- it('Changes properties of a token according to permissions (ReFungible)', async () => {
+ it('Changes properties of a token according to permissions (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testChangesPropertiesAccordingPermission({type: 'ReFungible'}, 100);
});
@@ -802,7 +840,9 @@
it('Deletes properties of a token according to permissions (NFT)', async () => {
await testDeletePropertiesAccordingPermission({type: 'NFT'}, 1);
});
- it('Deletes properties of a token according to permissions (ReFungible)', async () => {
+ it('Deletes properties of a token according to permissions (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testDeletePropertiesAccordingPermission({type: 'ReFungible'}, 100);
});
@@ -1029,7 +1069,9 @@
it('Forbids changing/deleting properties of a token if the user is outside of permissions (NFT)', async () => {
await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'NFT'}, 1);
});
- it('Forbids changing/deleting properties of a token if the user is outside of permissions (ReFungible)', async () => {
+ it('Forbids changing/deleting properties of a token if the user is outside of permissions (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'ReFungible'}, 100);
});
@@ -1062,7 +1104,9 @@
it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (NFT)', async () => {
await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'NFT'}, 1);
});
- it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (ReFungible)', async () => {
+ it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'ReFungible'}, 100);
});
@@ -1096,7 +1140,9 @@
it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (NFT)', async () => {
await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'NFT'}, 1);
});
- it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (ReFungible)', async () => {
+ it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'ReFungible'}, 100);
});
@@ -1140,7 +1186,9 @@
it('Forbids adding too many properties to a token (NFT)', async () => {
await testForbidsAddingTooManyProperties({type: 'NFT'}, 1);
});
- it('Forbids adding too many properties to a token (ReFungible)', async () => {
+ it('Forbids adding too many properties to a token (ReFungible)', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await testForbidsAddingTooManyProperties({type: 'ReFungible'}, 100);
});
});
@@ -1149,7 +1197,9 @@
let collection: number;
let token: number;
- before(async () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api, privateKeyWrapper) => {
alice = privateKeyWrapper('//Alice');
bob = privateKeyWrapper('//Bob');
tests/src/nesting/rules-smoke.test.tsdiffbeforeafterboth--- a/tests/src/nesting/rules-smoke.test.ts
+++ b/tests/src/nesting/rules-smoke.test.ts
@@ -1,7 +1,7 @@
import {expect} from 'chai';
import {tokenIdToAddress} from '../eth/util/helpers';
import usingApi, {executeTransaction} from '../substrate/substrate-api';
-import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, CrossAccountId, getCreateCollectionResult} from '../util/helpers';
+import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, CrossAccountId, getCreateCollectionResult, requirePallets, Pallets} from '../util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
describe('nesting check', () => {
@@ -47,7 +47,9 @@
});
});
- it('called for refungible', async () => {
+ it('called for refungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await expect(executeTransaction(api, alice, api.tx.unique.createItem(collection, nestTarget, {ReFungible: {}})))
tests/src/nesting/unnest.test.tsdiffbeforeafterboth--- a/tests/src/nesting/unnest.test.ts
+++ b/tests/src/nesting/unnest.test.ts
@@ -10,6 +10,8 @@
setCollectionPermissionsExpectSuccess,
transferExpectSuccess,
transferFromExpectSuccess,
+ requirePallets,
+ Pallets,
} from '../util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
@@ -80,7 +82,9 @@
});
});
- it('ReFungible: allows the owner to successfully unnest a token', async () => {
+ it('ReFungible: allows the owner to successfully unnest a token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async api => {
const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: {tokenOwner: true}});
tests/src/nextSponsoring.test.tsdiffbeforeafterboth--- a/tests/src/nextSponsoring.test.ts
+++ b/tests/src/nextSponsoring.test.ts
@@ -27,6 +27,8 @@
transferExpectSuccess,
normalizeAccountId,
getNextSponsored,
+ requirePallets,
+ Pallets,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -89,7 +91,9 @@
});
});
- it('ReFungible', async () => {
+ it('ReFungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api: ApiPromise) => {
const createMode = 'ReFungible';
tests/src/pallet-presence.test.tsdiffbeforeafterboth--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -49,8 +49,6 @@
'inflation',
'unique',
'nonfungible',
- 'refungible',
- 'scheduler',
'charging',
];
@@ -66,8 +64,16 @@
await usingApi(async api => {
const chain = await api.rpc.system.chain();
- if (!chain.eq('UNIQUE')) {
- requiredPallets.push(...['rmrkcore', 'rmrkequip']);
+ const refungible = 'refungible';
+ const scheduler = 'scheduler';
+ const rmrkPallets = ['rmrkcore', 'rmrkequip'];
+
+ if (chain.eq('OPAL by UNIQUE')) {
+ requiredPallets.push(refungible, scheduler, ...rmrkPallets);
+ } else if (chain.eq('QUARTZ by UNIQUE')) {
+ // Insert Quartz additional pallets here
+ } else if (chain.eq('UNIQUE')) {
+ // Insert Unique additional pallets here
}
});
});
tests/src/refungible.test.tsdiffbeforeafterboth--- a/tests/src/refungible.test.ts
+++ b/tests/src/refungible.test.ts
@@ -14,28 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
import {IKeyringPair} from '@polkadot/types/types';
+
+import { usingPlaygrounds } from './util/playgrounds';
import {
- createCollectionExpectSuccess,
- getBalance,
- createMultipleItemsExpectSuccess,
- isTokenExists,
- getLastTokenId,
- getAllowance,
- approve,
- transferFrom,
- createCollection,
- createRefungibleToken,
- transfer,
- burnItem,
- repartitionRFT,
- createCollectionWithPropsExpectSuccess,
- getDetailedCollectionInfo,
- normalizeAccountId,
- CrossAccountId,
- getCreateItemsResult,
- getDestroyItemsResult,
+ getModuleNames,
+ Pallets,
+ requirePallets,
} from './util/helpers';
import chai from 'chai';
@@ -46,249 +31,241 @@
let alice: IKeyringPair;
let bob: IKeyringPair;
-describe('integration test: Refungible functionality:', () => {
- before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
+describe('integration test: Refungible functionality:', async () => {
+ before(async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ await usingPlaygrounds(async (helper, privateKey) => {
+ alice = privateKey('//Alice');
+ bob = privateKey('//Bob');
+ if (!getModuleNames(helper.api!).includes(Pallets.ReFungible)) this.skip();
});
});
-
+
it('Create refungible collection and token', async () => {
- await usingApi(async api => {
- const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
- expect(createCollectionResult.success).to.be.true;
- const collectionId = createCollectionResult.collectionId;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+
+ const itemCountBefore = await collection.getLastTokenId();
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
- const itemCountBefore = await getLastTokenId(api, collectionId);
- const result = await createRefungibleToken(api, alice, collectionId, 100n);
+ const itemCountAfter = await collection.getLastTokenId();
- const itemCountAfter = await getLastTokenId(api, collectionId);
-
// What to expect
- // tslint:disable-next-line:no-unused-expression
- expect(result.success).to.be.true;
+ expect(token?.tokenId).to.be.gte(itemCountBefore);
expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
- expect(collectionId).to.be.equal(result.collectionId);
- expect(itemCountAfter.toString()).to.be.equal(result.itemId.toString());
+ expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
});
});
it('RPC method tokenOnewrs for refungible collection and token', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
+ await usingPlaygrounds(async (helper, privateKey) => {
const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
- const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));
-
- const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
- const collectionId = createCollectionResult.collectionId;
-
- const result = await createRefungibleToken(api, alice, collectionId, 10_000n);
- const aliceTokenId = result.itemId;
-
-
- await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
- await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
+ const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
+
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 10_000n);
+
+ await token.transfer(alice, {Substrate: bob.address}, 1000n);
+ await token.transfer(alice, ethAcc, 900n);
for (let i = 0; i < 7; i++) {
- await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 50*(i+1));
+ await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
}
-
- const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
- const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
-
- const aliceID = normalizeAccountId(alice);
- const bobId = normalizeAccountId(bob);
-
+
+ const owners = await token.getTop10Owners();
+
// What to expect
- // tslint:disable-next-line:no-unused-expression
- expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
+ expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
expect(owners.length).to.be.equal(10);
- const eleven = privateKeyWrapper('11');
- expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;
- expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);
+ const eleven = privateKey('//ALice+11');
+ expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+ expect((await token.getTop10Owners()).length).to.be.equal(10);
});
});
it('Transfer token pieces', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
- expect(await transfer(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;
-
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(40n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(60n);
- await expect(transfer(api, collectionId, tokenId, alice, bob, 41n)).to.eventually.be.rejected;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+ expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
+ expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
+
+ await expect(token.transfer(alice, {Substrate: bob.address}, 41n)).to.eventually.be.rejected;
});
});
it('Create multiple tokens', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const args = [
- {ReFungible: {pieces: 1}},
- {ReFungible: {pieces: 2}},
- {ReFungible: {pieces: 100}},
- ];
- await createMultipleItemsExpectSuccess(alice, collectionId, args);
-
- await usingApi(async api => {
- const tokenId = await getLastTokenId(api, collectionId);
- expect(tokenId).to.be.equal(3);
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ // TODO: fix mintMultipleTokens
+ // await collection.mintMultipleTokens(alice, [
+ // {owner: {Substrate: alice.address}, pieces: 1n},
+ // {owner: {Substrate: alice.address}, pieces: 2n},
+ // {owner: {Substrate: alice.address}, pieces: 100n},
+ // ]);
+ await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
+ {pieces: 1n},
+ {pieces: 2n},
+ {pieces: 100n},
+ ]);
+ const lastTokenId = await collection.getLastTokenId();
+ expect(lastTokenId).to.be.equal(3);
+ expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
});
});
it('Burn some pieces', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
- expect(await burnItem(api, alice, collectionId, tokenId, 99n)).to.be.true;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(1n);
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+ expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+ expect((await token.burn(alice, 99n)).success).to.be.true;
+ expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
});
});
it('Burn all pieces', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
- expect(await burnItem(api, alice, collectionId, tokenId, 100n)).to.be.true;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+
+ expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+
+ expect((await token.burn(alice, 100n)).success).to.be.true;
+ expect(await collection.isTokenExists(token.tokenId)).to.be.false;
});
});
it('Burn some pieces for multiple users', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
- expect(await transfer(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;
+ expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+ expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
-
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(40n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(60n);
- expect(await burnItem(api, alice, collectionId, tokenId, 40n)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
+ expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
+
+ expect((await token.burn(alice, 40n)).success).to.be.true;
+
+ expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
+
+ expect((await token.burn(bob, 59n)).success).to.be.true;
+
+ expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
+ expect(await collection.isTokenExists(token.tokenId)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(0n);
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await burnItem(api, bob, collectionId, tokenId, 59n)).to.be.true;
+ expect((await token.burn(bob, 1n)).success).to.be.true;
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(1n);
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
- expect(await burnItem(api, bob, collectionId, tokenId, 1n)).to.be.true;
-
- expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
+ expect(await collection.isTokenExists(token.tokenId)).to.be.false;
});
});
it('Set allowance for token', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);
+ expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
+ expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
- expect(await approve(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;
- expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(60n);
-
- expect(await transferFrom(api, collectionId, tokenId, bob, alice, bob, 20n)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(80n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(20n);
- expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(40n);
+ expect(await token.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
+ expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
+ expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
});
});
it('Repartition', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
- expect(await repartitionRFT(api, collectionId, alice, tokenId, 200n)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(200n);
-
- expect(await transfer(api, collectionId, tokenId, alice, bob, 110n)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(90n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(110n);
-
- await expect(repartitionRFT(api, collectionId, alice, tokenId, 80n)).to.eventually.be.rejected;
+ expect(await token.repartition(alice, 200n)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
+ expect(await token.getTotalPieces()).to.be.equal(200n);
+
+ expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
+ expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
+
+ await expect(token.repartition(alice, 80n)).to.eventually.be.rejected;
+
+ expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
+ expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
+ expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
- expect(await transfer(api, collectionId, tokenId, alice, bob, 90n)).to.be.true;
- expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(0n);
- expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(200n);
+ expect(await token.repartition(bob, 150n)).to.be.true;
+ await expect(token.transfer(bob, {Substrate: alice.address}, 160n)).to.eventually.be.rejected;
- expect(await repartitionRFT(api, collectionId, bob, tokenId, 150n)).to.be.true;
- await expect(transfer(api, collectionId, tokenId, bob, alice, 160n)).to.eventually.be.rejected;
});
});
it('Repartition with increased amount', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
-
- const tx = api.tx.unique.repartition(collectionId, tokenId, 200n);
- const events = await submitTransactionAsync(alice, tx);
- const substrateEvents = getCreateItemsResult(events);
- expect(substrateEvents).to.include.deep.members([
- {
- success: true,
- collectionId,
- itemId: tokenId,
- recipient: {Substrate: alice.address},
- amount: 100,
- },
- ]);
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+ await token.repartition(alice, 200n);
+ const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
+ expect(chainEvents).to.include.deep.members([{
+ method: 'ItemCreated',
+ section: 'common',
+ index: '0x4202',
+ data: [
+ collection.collectionId.toString(),
+ token.tokenId.toString(),
+ {Substrate: alice.address},
+ '100',
+ ],
+ }]);
});
});
it('Repartition with decreased amount', async () => {
- await usingApi(async api => {
- const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;
- const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;
-
- const tx = api.tx.unique.repartition(collectionId, tokenId, 50n);
- const events = await submitTransactionAsync(alice, tx);
- const substrateEvents = getDestroyItemsResult(events);
- expect(substrateEvents).to.include.deep.members([
- {
- success: true,
- collectionId,
- itemId: tokenId,
- owner: {Substrate: alice.address},
- amount: 50,
- },
- ]);
- });
- });
-});
-
-describe('Test Refungible properties:', () => {
- before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
+ await usingPlaygrounds(async helper => {
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+ await token.repartition(alice, 50n);
+ const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
+ expect(chainEvents).to.include.deep.members([{
+ method: 'ItemDestroyed',
+ section: 'common',
+ index: '0x4203',
+ data: [
+ collection.collectionId.toString(),
+ token.tokenId.toString(),
+ {Substrate: alice.address},
+ '50',
+ ],
+ }]);
});
});
- it('Сreate new collection with properties', async () => {
- await usingApi(async api => {
+ it('Create new collection with properties', async () => {
+ await usingPlaygrounds(async helper => {
const properties = [{key: 'key1', value: 'val1'}];
- const propertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
- const collectionId = await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'ReFungible'},
- properties: properties,
- propPerm: propertyPermissions,
- });
- const collection = (await getDetailedCollectionInfo(api, collectionId))!;
- expect(collection.properties.toHuman()).to.be.deep.equal(properties);
- expect(collection.tokenPropertyPermissions.toHuman()).to.be.deep.equal(propertyPermissions);
+ const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
+ const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
+ const info = await collection.getData();
+ expect(info?.raw.properties).to.be.deep.equal(properties);
+ expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
});
});
});
+
tests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -16,123 +16,112 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {createCollectionExpectSuccess, destroyCollectionExpectSuccess, getAdminList, normalizeAccountId, queryCollectionExpectSuccess} from './util/helpers';
+import {usingPlaygrounds} from './util/playgrounds';
chai.use(chaiAsPromised);
const expect = chai.expect;
describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
it('Remove collection admin.', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- const collectionId = await createCollectionExpectSuccess();
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
- const collection = await queryCollectionExpectSuccess(api, collectionId);
- expect(collection.owner.toString()).to.be.deep.eq(alice.address);
+ await usingPlaygrounds(async (helper, privateKey) => {
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+ const collectionInfo = await collection.getData();
+ expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
// first - add collection admin Bob
- const addAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await submitTransactionAsync(alice, addAdminTx);
+ await collection.addAdmin(alice, {Substrate: bob.address});
- const adminListAfterAddAdmin = await getAdminList(api, collectionId);
- expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
+ const adminListAfterAddAdmin = await collection.getAdmins();
+ expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
// then remove bob from admins of collection
- const removeAdminTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await submitTransactionAsync(alice, removeAdminTx);
+ await collection.removeAdmin(alice, {Substrate: bob.address});
- const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);
- expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(bob.address));
+ const adminListAfterRemoveAdmin = await collection.getAdmins();
+ expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
});
});
it('Remove admin from collection that has no admins', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- const alice = privateKeyWrapper('//Alice');
- const collectionId = await createCollectionExpectSuccess();
+ await usingPlaygrounds(async (helper, privateKey) => {
+ const alice = privateKey('//Alice');
+ const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
- const adminListBeforeAddAdmin = await getAdminList(api, collectionId);
+ const adminListBeforeAddAdmin = await collection.getAdmins();
expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
- const tx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(alice.address));
- await submitTransactionAsync(alice, tx);
+ // await expect(collection.removeAdmin(alice, {Substrate: alice.address})).to.be.rejectedWith('Unable to remove collection admin');
+ await collection.removeAdmin(alice, {Substrate: alice.address});
});
});
});
describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
it('Can\'t remove collection admin from not existing collection', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
+ await usingPlaygrounds(async (helper, privateKey) => {
// tslint:disable-next-line: no-bitwise
const collectionId = (1 << 32) - 1;
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
- const changeOwnerTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;
+ await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address})).to.be.rejected;
// Verifying that nothing bad happened (network is live, new collections can be created, etc.)
- await createCollectionExpectSuccess();
+ await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
});
});
it('Can\'t remove collection admin from deleted collection', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- // tslint:disable-next-line: no-bitwise
- const collectionId = await createCollectionExpectSuccess();
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
+ await usingPlaygrounds(async (helper, privateKey) => {
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
- await destroyCollectionExpectSuccess(collectionId);
+ expect(await collection.burn(alice)).to.be.true;
- const changeOwnerTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;
+ await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address})).to.be.rejected;
// Verifying that nothing bad happened (network is live, new collections can be created, etc.)
- await createCollectionExpectSuccess();
+ await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
});
});
it('Regular user can\'t remove collection admin', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- const collectionId = await createCollectionExpectSuccess();
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
- const charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper, privateKey) => {
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const charlie = privateKey('//Charlie');
+ const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
- const addAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await submitTransactionAsync(alice, addAdminTx);
+ await collection.addAdmin(alice, {Substrate: bob.address});
- const changeOwnerTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await expect(submitTransactionExpectFailAsync(charlie, changeOwnerTx)).to.be.rejected;
+ await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
// Verifying that nothing bad happened (network is live, new collections can be created, etc.)
- await createCollectionExpectSuccess();
+ await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
});
});
it('Admin can\'t remove collection admin.', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- const collectionId = await createCollectionExpectSuccess();
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
- const charlie = privateKeyWrapper('//Charlie');
-
- const addBobAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await submitTransactionAsync(alice, addBobAdminTx);
- const addCharlieAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));
- await submitTransactionAsync(alice, addCharlieAdminTx);
+ await usingPlaygrounds(async (helper, privateKey) => {
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const charlie = privateKey('//Charlie');
+ const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+
+ await collection.addAdmin(alice, {Substrate: bob.address});
+ await collection.addAdmin(alice, {Substrate: charlie.address});
- const adminListAfterAddAdmin = await getAdminList(api, collectionId);
- expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
- expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));
+ const adminListAfterAddAdmin = await collection.getAdmins();
+ expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
+ expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
- const removeAdminTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
- await expect(submitTransactionExpectFailAsync(charlie, removeAdminTx)).to.be.rejected;
+ await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
- const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);
- expect(adminListAfterRemoveAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
- expect(adminListAfterRemoveAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));
+ const adminListAfterRemoveAdmin = await collection.getAdmins();
+ expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
+ expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
});
});
});
tests/src/rmrk/acceptNft.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/acceptNft.test.ts
+++ b/tests/src/rmrk/acceptNft.test.ts
@@ -8,14 +8,19 @@
} from './util/tx';
import {NftIdTuple} from './util/fetch';
import {isNftChildOfAnother, expectTxFailure} from './util/helpers';
+import {requirePallets, Pallets} from '../util/helpers';
describe('integration test: accept NFT', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
-
+ 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,
tests/src/rmrk/addResource.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/addResource.test.ts
+++ b/tests/src/rmrk/addResource.test.ts
@@ -12,6 +12,7 @@
addNftComposableResource,
} from './util/tx';
import {RmrkTraitsResourceResourceInfo as ResourceInfo} from '@polkadot/types/lookup';
+import {requirePallets, Pallets} from '../util/helpers';
describe('integration test: add NFT resource', () => {
const Alice = '//Alice';
@@ -24,8 +25,9 @@
const nonexistentId = 99999;
let api: any;
- before(async () => {
+ before(async function() {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
});
it('add resource', async () => {
tests/src/rmrk/addTheme.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/addTheme.test.ts
+++ b/tests/src/rmrk/addTheme.test.ts
@@ -3,10 +3,14 @@
import {createBase, addTheme} from './util/tx';
import {expectTxFailure} from './util/helpers';
import {getThemeNames} from './util/fetch';
+import {requirePallets, Pallets} from '../util/helpers';
describe('integration test: add Theme to Base', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+ before(async function() {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkEquip]);
+ });
const alice = '//Alice';
const bob = '//Bob';
tests/src/rmrk/burnNft.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/burnNft.test.ts
+++ b/tests/src/rmrk/burnNft.test.ts
@@ -5,6 +5,7 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
+import {requirePallets, Pallets} from '../util/helpers';
chai.use(chaiAsPromised);
const expect = chai.expect;
@@ -14,10 +15,12 @@
const Bob = '//Bob';
let api: any;
- before(async () => {
+ before(async function() {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
});
+
it('burn nft', async () => {
await createCollection(
api,
tests/src/rmrk/changeCollectionIssuer.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/changeCollectionIssuer.test.ts
+++ b/tests/src/rmrk/changeCollectionIssuer.test.ts
@@ -1,4 +1,5 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {expectTxFailure} from './util/helpers';
import {
changeIssuer,
@@ -10,10 +11,13 @@
const Bob = '//Bob';
let api: any;
- before(async () => {
+ before(async function() {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
});
+
+
it('change collection issuer', async () => {
await createCollection(
api,
tests/src/rmrk/createBase.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/createBase.test.ts
+++ b/tests/src/rmrk/createBase.test.ts
@@ -1,9 +1,13 @@
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 () => { api = await getApiConnection(); });
+ before(async function() {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
+ });
const alice = '//Alice';
tests/src/rmrk/createCollection.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/createCollection.test.ts
+++ b/tests/src/rmrk/createCollection.test.ts
@@ -1,9 +1,15 @@
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 () => { api = await getApiConnection(); });
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
+
+
const alice = '//Alice';
tests/src/rmrk/deleteCollection.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/deleteCollection.test.ts
+++ b/tests/src/rmrk/deleteCollection.test.ts
@@ -1,11 +1,13 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {expectTxFailure} from './util/helpers';
import {createCollection, deleteCollection} from './util/tx';
describe('integration test: delete collection', () => {
let api: any;
- before(async () => {
+ before(async function () {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
});
const Alice = '//Alice';
tests/src/rmrk/equipNft.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/equipNft.test.ts
+++ b/tests/src/rmrk/equipNft.test.ts
@@ -1,6 +1,7 @@
import {ApiPromise} from '@polkadot/api';
import {expect} from 'chai';
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {getNft, getParts, NftIdTuple} from './util/fetch';
import {expectTxFailure} from './util/helpers';
import {
@@ -122,8 +123,10 @@
describe.skip('integration test: Equip NFT', () => {
let api: any;
- before(async () => {
+
+ before(async function () {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
});
it('equip nft', async () => {
tests/src/rmrk/getOwnedNfts.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/getOwnedNfts.test.ts
+++ b/tests/src/rmrk/getOwnedNfts.test.ts
@@ -1,11 +1,17 @@
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 () => { api = await getApiConnection(); });
+
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
+
const alice = '//Alice';
tests/src/rmrk/lockCollection.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/lockCollection.test.ts
+++ b/tests/src/rmrk/lockCollection.test.ts
@@ -1,4 +1,5 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {expectTxFailure} from './util/helpers';
import {createCollection, lockCollection, mintNft} from './util/tx';
@@ -8,8 +9,9 @@
const Max = 5;
let api: any;
- before(async () => {
+ before(async function () {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
});
it('lock collection', async () => {
tests/src/rmrk/mintNft.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/mintNft.test.ts
+++ b/tests/src/rmrk/mintNft.test.ts
@@ -1,12 +1,18 @@
import {expect} from 'chai';
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {getNft} from './util/fetch';
import {expectTxFailure} from './util/helpers';
import {createCollection, mintNft} from './util/tx';
describe('integration test: mint new NFT', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
+
const alice = '//Alice';
const bob = '//Bob';
tests/src/rmrk/rejectNft.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/rejectNft.test.ts
+++ b/tests/src/rmrk/rejectNft.test.ts
@@ -8,10 +8,16 @@
} from './util/tx';
import {getChildren, NftIdTuple} from './util/fetch';
import {isNftChildOfAnother, expectTxFailure} from './util/helpers';
+import {requirePallets, Pallets} from '../util/helpers';
describe('integration test: reject NFT', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
+
+
const alice = '//Alice';
const bob = '//Bob';
tests/src/rmrk/removeResource.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/removeResource.test.ts
+++ b/tests/src/rmrk/removeResource.test.ts
@@ -1,6 +1,7 @@
import {expect} from 'chai';
import privateKey from '../substrate/privateKey';
import {executeTransaction, getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {getNft, NftIdTuple} from './util/fetch';
import {expectTxFailure} from './util/helpers';
import {
@@ -16,9 +17,10 @@
describe('Integration test: remove nft resource', () => {
let api: any;
let ss58Format: string;
- before(async () => {
+ before(async function() {
api = await getApiConnection();
ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
+ await requirePallets(this, [Pallets.RmrkCore]);
});
const Alice = '//Alice';
tests/src/rmrk/rmrkIsolation.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/rmrkIsolation.test.ts
+++ b/tests/src/rmrk/rmrkIsolation.test.ts
@@ -6,7 +6,9 @@
getCreateCollectionResult,
getDetailedCollectionInfo,
getGenericResult,
+ requirePallets,
normalizeAccountId,
+ Pallets,
} from '../util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
import {ApiPromise} from '@polkadot/api';
@@ -59,11 +61,10 @@
describe('RMRK External Integration Test', async () => {
const it_rmrk = (await isUnique() ? it : it.skip);
- before(async () => {
+ before(async function() {
await usingApi(async (api, privateKeyWrapper) => {
alice = privateKeyWrapper('//Alice');
-
-
+ await requirePallets(this, [Pallets.RmrkCore]);
});
});
tests/src/rmrk/sendNft.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/sendNft.test.ts
+++ b/tests/src/rmrk/sendNft.test.ts
@@ -3,10 +3,14 @@
import {createCollection, mintNft, sendNft} from './util/tx';
import {NftIdTuple} from './util/fetch';
import {isNftChildOfAnother, expectTxFailure} from './util/helpers';
+import {requirePallets, Pallets} from '../util/helpers';
describe('integration test: send NFT', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
const maxNftId = 0xFFFFFFFF;
tests/src/rmrk/setCollectionProperty.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/setCollectionProperty.test.ts
+++ b/tests/src/rmrk/setCollectionProperty.test.ts
@@ -1,4 +1,5 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {expectTxFailure} from './util/helpers';
import {createCollection, setPropertyCollection} from './util/tx';
@@ -7,8 +8,9 @@
const Bob = '//Bob';
let api: any;
- before(async () => {
+ before(async function () {
api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
});
it('set collection property', async () => {
tests/src/rmrk/setEquippableList.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/setEquippableList.test.ts
+++ b/tests/src/rmrk/setEquippableList.test.ts
@@ -1,10 +1,14 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {expectTxFailure} from './util/helpers';
import {createCollection, createBase, setEquippableList} from './util/tx';
describe("integration test: set slot's Equippable List", () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
const alice = '//Alice';
const bob = '//Bob';
tests/src/rmrk/setNftProperty.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/setNftProperty.test.ts
+++ b/tests/src/rmrk/setNftProperty.test.ts
@@ -1,11 +1,15 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {NftIdTuple} from './util/fetch';
import {expectTxFailure} from './util/helpers';
import {createCollection, mintNft, sendNft, setNftProperty} from './util/tx';
describe('integration test: set NFT property', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
const alice = '//Alice';
const bob = '//Bob';
tests/src/rmrk/setResourcePriorities.test.tsdiffbeforeafterboth--- a/tests/src/rmrk/setResourcePriorities.test.ts
+++ b/tests/src/rmrk/setResourcePriorities.test.ts
@@ -1,10 +1,14 @@
import {getApiConnection} from '../substrate/substrate-api';
+import {requirePallets, Pallets} from '../util/helpers';
import {expectTxFailure} from './util/helpers';
import {mintNft, createCollection, setResourcePriorities} from './util/tx';
describe('integration test: set NFT resource priorities', () => {
let api: any;
- before(async () => { api = await getApiConnection(); });
+ before(async function () {
+ api = await getApiConnection();
+ await requirePallets(this, [Pallets.RmrkCore]);
+ });
const alice = '//Alice';
const bob = '//Bob';
tests/src/setCollectionSponsor.test.tsdiffbeforeafterboth--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -23,6 +23,8 @@
setCollectionSponsorExpectFailure,
addCollectionAdminExpectSuccess,
getCreatedCollectionCount,
+ requirePallets,
+ Pallets,
} from './util/helpers';
import {IKeyringPair} from '@polkadot/types/types';
@@ -50,7 +52,9 @@
const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
- it('Set ReFungible collection sponsor', async () => {
+ it('Set ReFungible collection sponsor', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
tests/src/transfer.test.tsdiffbeforeafterboth--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -35,11 +35,14 @@
getBalance as getTokenBalance,
transferFromExpectSuccess,
transferFromExpectFail,
+ requirePallets,
+ Pallets,
} from './util/helpers';
import {
subToEth,
itWeb3,
} from './eth/util/helpers';
+import {request} from 'https';
let alice: IKeyringPair;
let bob: IKeyringPair;
@@ -89,56 +92,61 @@
});
});
- it('User can transfer owned token', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- // nft
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
- // fungible
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
- // reFungible
- const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await transferExpectSuccess(
- reFungibleCollectionId,
- newReFungibleTokenId,
- alice,
- bob,
- 100,
- 'ReFungible',
- );
- });
+ it('[nft] User can transfer owned token', async () => {
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+ await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
+ });
+
+ it('[fungible] User can transfer owned token', async () => {
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+ await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
+ });
+
+ it('[refungible] User can transfer owned token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+ await transferExpectSuccess(
+ reFungibleCollectionId,
+ newReFungibleTokenId,
+ alice,
+ bob,
+ 100,
+ 'ReFungible',
+ );
+ });
+
+ it('[nft] Collection admin can transfer owned token', async () => {
+ const nftCollectionId = await createCollectionExpectSuccess();
+ await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
+ const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
+ await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
+ });
+
+ it('[fungible] Collection admin can transfer owned token', async () => {
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
+ const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
+ await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
});
- it('Collection admin can transfer owned token', async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- // nft
- const nftCollectionId = await createCollectionExpectSuccess();
- await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
- const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
- await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
- // fungible
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
- await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
- // reFungible
- const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
- const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
- await transferExpectSuccess(
- reFungibleCollectionId,
- newReFungibleTokenId,
- bob,
- alice,
- 100,
- 'ReFungible',
- );
- });
+ it('[refungible] Collection admin can transfer owned token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
+ const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
+ await transferExpectSuccess(
+ reFungibleCollectionId,
+ newReFungibleTokenId,
+ bob,
+ alice,
+ 100,
+ 'ReFungible',
+ );
});
});
@@ -150,33 +158,49 @@
charlie = privateKeyWrapper('//Charlie');
});
});
- it('Transfer with not existed collection_id', async () => {
+
+ it('[nft] Transfer with not existed collection_id', async () => {
await usingApi(async (api) => {
- // nft
const nftCollectionCount = await getCreatedCollectionCount(api);
await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);
- // fungible
+ });
+ });
+
+ it('[fungible] Transfer with not existed collection_id', async () => {
+ await usingApi(async (api) => {
const fungibleCollectionCount = await getCreatedCollectionCount(api);
await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
- // reFungible
+ });
+ });
+
+ it('[refungible] Transfer with not existed collection_id', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ await usingApi(async (api) => {
const reFungibleCollectionCount = await getCreatedCollectionCount(api);
await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
});
});
- it('Transfer with deleted collection_id', async () => {
- // nft
+
+ it('[nft] Transfer with deleted collection_id', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);
await destroyCollectionExpectSuccess(nftCollectionId);
await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
- // fungible
+ });
+
+ it('[fungible] Transfer with deleted collection_id', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
await destroyCollectionExpectSuccess(fungibleCollectionId);
await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
- // reFungible
+ });
+
+ it('[refungible] Transfer with deleted collection_id', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId = await
createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -190,16 +214,21 @@
1,
);
});
- it('Transfer with not existed item_id', async () => {
- // nft
+
+ it('[nft] Transfer with not existed item_id', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
- // fungible
+ });
+
+ it('[fungible] Transfer with not existed item_id', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);
- // reFungible
- const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ });
+
+ it('[refungible] Transfer with not existed item_id', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await transferExpectFailure(
reFungibleCollectionId,
2,
@@ -208,18 +237,24 @@
1,
);
});
- it('Transfer with deleted item_id', async () => {
- // nft
+
+ it('[nft] Transfer with deleted item_id', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
- // fungible
+ });
+
+ it('[fungible] Transfer with deleted item_id', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
- // reFungible
+ });
+
+ it('[refungible] Transfer with deleted item_id', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
const reFungibleCollectionId = await
createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -232,18 +267,23 @@
1,
);
});
- it('Transfer with recipient that is not owner', async () => {
- // nft
+
+ it('[nft] Transfer with recipient that is not owner', async () => {
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
- // fungible
+ });
+
+ it('[fungible] Transfer with recipient that is not owner', async () => {
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
- // reFungible
- const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ });
+
+ it('[refungible] Transfer with recipient that is not owner', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
await transferExpectFailure(
reFungibleCollectionId,
@@ -276,7 +316,9 @@
});
});
- it('RFT', async () => {
+ it('RFT', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async (api: ApiPromise) => {
const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
tests/src/transferFrom.test.tsdiffbeforeafterboth--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -31,6 +31,8 @@
burnItemExpectSuccess,
setCollectionLimitsExpectSuccess,
getCreatedCollectionCount,
+ requirePallets,
+ Pallets,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -49,36 +51,36 @@
});
});
- it('Execute the extrinsic and check nftItemList - owner of token', async () => {
- await usingApi(async () => {
- // nft
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+ it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
- await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
+ await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
+ });
- // fungible
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
- await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
+ it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
+ await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
+ });
- // reFungible
- const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
- await transferFromExpectSuccess(
- reFungibleCollectionId,
- newReFungibleTokenId,
- bob,
- alice,
- charlie,
- 100,
- 'ReFungible',
- );
- });
+ it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
+ await transferFromExpectSuccess(
+ reFungibleCollectionId,
+ newReFungibleTokenId,
+ bob,
+ alice,
+ charlie,
+ 100,
+ 'ReFungible',
+ );
});
it('Should reduce allowance if value is big', async () => {
@@ -119,20 +121,28 @@
});
});
- it('transferFrom for a collection that does not exist', async () => {
+ it('[nft] transferFrom for a collection that does not exist', async () => {
await usingApi(async (api: ApiPromise) => {
- // nft
const nftCollectionCount = await getCreatedCollectionCount(api);
await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);
+ });
+ });
- // fungible
+ it('[fungible] transferFrom for a collection that does not exist', async () => {
+ await usingApi(async (api: ApiPromise) => {
const fungibleCollectionCount = await getCreatedCollectionCount(api);
await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
- // reFungible
+ });
+ });
+
+ it('[refungible] transferFrom for a collection that does not exist', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ await usingApi(async (api: ApiPromise) => {
const reFungibleCollectionCount = await getCreatedCollectionCount(api);
await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
@@ -158,67 +168,70 @@
});
}); */
- it('transferFrom for not approved address', async () => {
- await usingApi(async () => {
- // nft
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+ it('[nft] transferFrom for not approved address', async () => {
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
+ await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
+ });
- // fungible
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
- // reFungible
- const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await transferFromExpectFail(
- reFungibleCollectionId,
- newReFungibleTokenId,
- bob,
- alice,
- charlie,
- 1,
- );
- });
+ it('[fungible] transferFrom for not approved address', async () => {
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+ await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
+ });
+
+ it('[refungible] transferFrom for not approved address', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+ await transferFromExpectFail(
+ reFungibleCollectionId,
+ newReFungibleTokenId,
+ bob,
+ alice,
+ charlie,
+ 1,
+ );
+ });
+
+ it('[nft] transferFrom incorrect token count', async () => {
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+
+ await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
});
- it('transferFrom incorrect token count', async () => {
- await usingApi(async () => {
- // nft
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+ it('[fungible] transferFrom incorrect token count', async () => {
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
+ await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
+ });
- await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
+ it('[refungible] transferFrom incorrect token count', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
- // fungible
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
- await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
- // reFungible
- const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
- await transferFromExpectFail(
- reFungibleCollectionId,
- newReFungibleTokenId,
- bob,
- alice,
- charlie,
- 2,
- );
- });
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+ const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
+ await transferFromExpectFail(
+ reFungibleCollectionId,
+ newReFungibleTokenId,
+ bob,
+ alice,
+ charlie,
+ 2,
+ );
});
- it('execute transferFrom from account that is not owner of collection', async () => {
+ it('[nft] execute transferFrom from account that is not owner of collection', async () => {
await usingApi(async (api, privateKeyWrapper) => {
const dave = privateKeyWrapper('//Dave');
- // nft
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
try {
@@ -230,8 +243,13 @@
}
// await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
+ });
+ });
- // fungible
+ it('[fungible] execute transferFrom from account that is not owner of collection', async () => {
+ await usingApi(async (api, privateKeyWrapper) => {
+ const dave = privateKeyWrapper('//Dave');
+
const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
try {
@@ -241,7 +259,14 @@
// tslint:disable-next-line:no-unused-expression
expect(e).to.be.exist;
}
- // reFungible
+ });
+ });
+
+ it('[refungible] execute transferFrom from account that is not owner of collection', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
+ await usingApi(async (api, privateKeyWrapper) => {
+ const dave = privateKeyWrapper('//Dave');
const reFungibleCollectionId = await
createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -276,7 +301,9 @@
});
});
- it('transferFrom burnt token before approve ReFungible', async () => {
+ it('transferFrom burnt token before approve ReFungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async () => {
const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await setCollectionLimitsExpectSuccess(alice, reFungibleCollectionId, {ownerCanTransfer: true});
@@ -308,7 +335,9 @@
});
});
- it('transferFrom burnt token after approve ReFungible', async () => {
+ it('transferFrom burnt token after approve ReFungible', async function() {
+ await requirePallets(this, [Pallets.ReFungible]);
+
await usingApi(async () => {
const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -28,6 +28,7 @@
import {hexToStr, strToUTF16, utf16ToStr} from './util';
import {UpDataStructsRpcCollection, UpDataStructsCreateItemData, UpDataStructsProperty} from '@polkadot/types/lookup';
import {UpDataStructsTokenChild} from '../interfaces';
+import {Context} from 'mocha';
chai.use(chaiAsPromised);
const expect = chai.expect;
@@ -38,6 +39,66 @@
Ethereum: string,
};
+
+export enum Pallets {
+ Inflation = 'inflation',
+ RmrkCore = 'rmrkcore',
+ RmrkEquip = 'rmrkequip',
+ ReFungible = 'refungible',
+ Fungible = 'fungible',
+ NFT = 'nonfungible',
+ Scheduler = 'scheduler',
+}
+
+export async function isUnique(): Promise<boolean> {
+ return usingApi(async api => {
+ const chain = await api.rpc.system.chain();
+
+ return chain.eq('UNIQUE');
+ });
+}
+
+export async function isQuartz(): Promise<boolean> {
+ return usingApi(async api => {
+ const chain = await api.rpc.system.chain();
+
+ return chain.eq('QUARTZ');
+ });
+}
+
+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[]> {
+ return await usingApi(async api => {
+ const pallets = getModuleNames(api);
+
+ return requiredPallets.filter(p => !pallets.includes(p));
+ });
+}
+
+export async function checkPalletsPresence(requiredPallets: string[]): Promise<boolean> {
+ return (await missingRequiredPallets(requiredPallets)).length == 0;
+}
+
+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 normalizeAccountId(input: string | AccountId | CrossAccountId | IKeyringPair): CrossAccountId {
if (typeof input === 'string') {
if (input.length >= 47) {
tests/src/util/playgrounds/index.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/util/playgrounds/index.ts
@@ -0,0 +1,93 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+import {IKeyringPair} from '@polkadot/types/types';
+import {UniqueHelper} from './unique';
+import config from '../../config';
+import '../../interfaces/augment-api-events';
+import * as defs from '../../interfaces/definitions';
+import {ApiPromise, WsProvider} from '@polkadot/api';
+
+
+class SilentLogger {
+ log(msg: any, level: any): void {}
+ level = {
+ ERROR: 'ERROR' as const,
+ WARNING: 'WARNING' as const,
+ INFO: 'INFO' as const,
+ };
+}
+
+
+class DevUniqueHelper extends UniqueHelper {
+ async connect(wsEndpoint: string, listeners?: any): Promise<void> {
+ const wsProvider = new WsProvider(wsEndpoint);
+ this.api = new ApiPromise({
+ provider: wsProvider,
+ signedExtensions: {
+ ContractHelpers: {
+ extrinsic: {},
+ payload: {},
+ },
+ FakeTransactionFinalizer: {
+ extrinsic: {},
+ payload: {},
+ },
+ },
+ rpc: {
+ unique: defs.unique.rpc,
+ rmrk: defs.rmrk.rpc,
+ eth: {
+ feeHistory: {
+ description: 'Dummy',
+ params: [],
+ type: 'u8',
+ },
+ maxPriorityFeePerGas: {
+ description: 'Dummy',
+ params: [],
+ type: 'u8',
+ },
+ },
+ },
+ });
+ await this.api.isReadyOrError;
+ this.network = await UniqueHelper.detectNetwork(this.api);
+ }
+}
+
+export const usingPlaygrounds = async (code: (helper: UniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>) => {
+ // TODO: Remove, this is temporary: Filter unneeded API output
+ // (Jaco promised it will be removed in the next version)
+ const consoleErr = console.error;
+ const consoleLog = console.log;
+ const consoleWarn = console.warn;
+
+ const outFn = (printer: any) => (...args: any[]) => {
+ for (const arg of args) {
+ if (typeof arg !== 'string')
+ continue;
+ if (arg.includes('1000:: Normal connection closure' || arg === 'Normal connection closure'))
+ return;
+ }
+ printer(...args);
+ };
+
+ console.error = outFn(consoleErr.bind(console));
+ console.log = outFn(consoleLog.bind(console));
+ console.warn = outFn(consoleWarn.bind(console));
+ const helper = new DevUniqueHelper(new SilentLogger());
+
+ try {
+ await helper.connect(config.substrateUrl);
+ const ss58Format = helper.chain.getChainProperties().ss58Format;
+ const privateKey = (seed: string) => helper.util.fromSeed(seed, ss58Format);
+ await code(helper, privateKey);
+ }
+ finally {
+ await helper.disconnect();
+ console.error = consoleErr;
+ console.log = consoleLog;
+ console.warn = consoleWarn;
+ }
+};
\ No newline at end of file
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/util/playgrounds/unique.ts
@@ -0,0 +1,2490 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+/* eslint-disable @typescript-eslint/no-var-requires */
+/* eslint-disable function-call-argument-newline */
+/* eslint-disable no-prototype-builtins */
+
+import {ApiPromise, WsProvider, Keyring} from '@polkadot/api';
+import {ApiInterfaceEvents} from '@polkadot/api/types';
+import {IKeyringPair} from '@polkadot/types/types';
+import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';
+
+
+const crossAccountIdFromLower = (lowerAddress: ICrossAccountIdLower): ICrossAccountId => {
+ const address = {} as ICrossAccountId;
+ if(lowerAddress.substrate) address.Substrate = lowerAddress.substrate;
+ if(lowerAddress.ethereum) address.Ethereum = lowerAddress.ethereum;
+ return address;
+};
+
+
+const nesting = {
+ toChecksumAddress(address: string): string {
+ if (typeof address === 'undefined') return '';
+
+ if(!/^(0x)?[0-9a-f]{40}$/i.test(address)) throw new Error(`Given address "${address}" is not a valid Ethereum address.`);
+
+ address = address.toLowerCase().replace(/^0x/i,'');
+ const addressHash = keccakAsHex(address).replace(/^0x/i,'');
+ const checksumAddress = ['0x'];
+
+ for (let i = 0; i < address.length; i++) {
+ // If ith character is 8 to f then make it uppercase
+ if (parseInt(addressHash[i], 16) > 7) {
+ checksumAddress.push(address[i].toUpperCase());
+ } else {
+ checksumAddress.push(address[i]);
+ }
+ }
+ return checksumAddress.join('');
+ },
+ tokenIdToAddress(collectionId: number, tokenId: number) {
+ return this.toChecksumAddress(`0xf8238ccfff8ed887463fd5e0${collectionId.toString(16).padStart(8, '0')}${tokenId.toString(16).padStart(8, '0')}`);
+ },
+};
+
+
+interface IChainEvent {
+ data: any;
+ method: string;
+ section: string;
+}
+
+interface ITransactionResult {
+ status: 'Fail' | 'Success';
+ result: {
+ events: {
+ event: IChainEvent
+ }[];
+ },
+ moduleError?: string;
+}
+
+interface ILogger {
+ log: (msg: any, level?: string) => void;
+ level: {
+ ERROR: 'ERROR';
+ WARNING: 'WARNING';
+ INFO: 'INFO';
+ [key: string]: string;
+ }
+}
+
+interface IUniqueHelperLog {
+ executedAt: number;
+ executionTime: number;
+ type: 'extrinsic' | 'rpc';
+ status: 'Fail' | 'Success';
+ call: string;
+ params: any[];
+ moduleError?: string;
+ events?: any;
+}
+
+interface IApiListeners {
+ connected?: (...args: any[]) => any;
+ disconnected?: (...args: any[]) => any;
+ error?: (...args: any[]) => any;
+ ready?: (...args: any[]) => any;
+ decorated?: (...args: any[]) => any;
+}
+
+interface ICrossAccountId {
+ Substrate?: TSubstrateAccount;
+ Ethereum?: TEthereumAccount;
+}
+
+interface ICrossAccountIdLower {
+ substrate?: TSubstrateAccount;
+ ethereum?: TEthereumAccount;
+}
+
+interface ICollectionLimits {
+ accountTokenOwnershipLimit?: number | null;
+ sponsoredDataSize?: number | null;
+ sponsoredDataRateLimit?: {blocks: number} | {sponsoringDisabled: null} | null;
+ tokenLimit?: number | null;
+ sponsorTransferTimeout?: number | null;
+ sponsorApproveTimeout?: number | null;
+ ownerCanTransfer?: boolean | null;
+ ownerCanDestroy?: boolean | null;
+ transfersEnabled?: boolean | null;
+}
+
+interface INestingPermissions {
+ tokenOwner?: boolean;
+ collectionAdmin?: boolean;
+ restricted?: number[] | null;
+}
+
+interface ICollectionPermissions {
+ access?: 'Normal' | 'AllowList';
+ mintMode?: boolean;
+ nesting?: INestingPermissions;
+}
+
+interface IProperty {
+ key: string;
+ value: string;
+}
+
+interface ITokenPropertyPermission {
+ key: string;
+ permission: {
+ mutable: boolean;
+ tokenOwner: boolean;
+ collectionAdmin: boolean;
+ }
+}
+
+interface IToken {
+ collectionId: number;
+ tokenId: number;
+}
+
+interface ICollectionCreationOptions {
+ name: string | number[];
+ description: string | number[];
+ tokenPrefix: string | number[];
+ mode?: {
+ nft?: null;
+ refungible?: null;
+ fungible?: number;
+ }
+ permissions?: ICollectionPermissions;
+ properties?: IProperty[];
+ tokenPropertyPermissions?: ITokenPropertyPermission[];
+ limits?: ICollectionLimits;
+ pendingSponsor?: TSubstrateAccount;
+}
+
+interface IChainProperties {
+ ss58Format: number;
+ tokenDecimals: number[];
+ tokenSymbol: string[]
+}
+
+type TSubstrateAccount = string;
+type TEthereumAccount = string;
+type TApiAllowedListeners = 'connected' | 'disconnected' | 'error' | 'ready' | 'decorated';
+type TUniqueNetworks = 'opal' | 'quartz' | 'unique';
+type TSigner = IKeyringPair; // | 'string'
+
+class UniqueUtil {
+ static transactionStatus = {
+ NOT_READY: 'NotReady',
+ FAIL: 'Fail',
+ SUCCESS: 'Success',
+ };
+
+ static chainLogType = {
+ EXTRINSIC: 'extrinsic',
+ RPC: 'rpc',
+ };
+
+ static getNestingTokenAddress(collectionId: number, tokenId: number) {
+ return nesting.tokenIdToAddress(collectionId, tokenId);
+ }
+
+ static getDefaultLogger(): ILogger {
+ return {
+ log(msg: any, level = 'INFO') {
+ console[level.toLocaleLowerCase() === 'error' ? 'error' : 'log'](...(Array.isArray(msg) ? msg : [msg]));
+ },
+ level: {
+ ERROR: 'ERROR',
+ WARNING: 'WARNING',
+ INFO: 'INFO',
+ },
+ };
+ }
+
+ static vec2str(arr: string[] | number[]) {
+ return arr.map(x => String.fromCharCode(parseInt(x.toString()))).join('');
+ }
+
+ static str2vec(string: string) {
+ if (typeof string !== 'string') return string;
+ return Array.from(string).map(x => x.charCodeAt(0));
+ }
+
+ static fromSeed(seed: string, ss58Format = 42) {
+ const keyring = new Keyring({type: 'sr25519', ss58Format});
+ return keyring.addFromUri(seed);
+ }
+
+ static normalizeSubstrateAddress(address: string, ss58Format = 42) {
+ return encodeAddress(decodeAddress(address), ss58Format);
+ }
+
+ static extractCollectionIdFromCreationResult(creationResult: ITransactionResult, label = 'new collection') {
+ if (creationResult.status !== this.transactionStatus.SUCCESS) {
+ throw Error(`Unable to create collection for ${label}`);
+ }
+
+ let collectionId = null;
+ creationResult.result.events.forEach(({event: {data, method, section}}) => {
+ if ((section === 'common') && (method === 'CollectionCreated')) {
+ collectionId = parseInt(data[0].toString(), 10);
+ }
+ });
+
+ if (collectionId === null) {
+ throw Error(`No CollectionCreated event for ${label}`);
+ }
+
+ return collectionId;
+ }
+
+ static extractTokensFromCreationResult(creationResult: ITransactionResult, label = 'new tokens') {
+ if (creationResult.status !== this.transactionStatus.SUCCESS) {
+ throw Error(`Unable to create tokens for ${label}`);
+ }
+ let success = false;
+ const tokens = [] as any;
+ creationResult.result.events.forEach(({event: {data, method, section}}) => {
+ if (method === 'ExtrinsicSuccess') {
+ success = true;
+ } else if ((section === 'common') && (method === 'ItemCreated')) {
+ tokens.push({
+ collectionId: parseInt(data[0].toString(), 10),
+ tokenId: parseInt(data[1].toString(), 10),
+ owner: data[2].toJSON(),
+ });
+ }
+ });
+ return {success, tokens};
+ }
+
+ static extractTokensFromBurnResult(burnResult: ITransactionResult, label = 'burned tokens') {
+ if (burnResult.status !== this.transactionStatus.SUCCESS) {
+ throw Error(`Unable to burn tokens for ${label}`);
+ }
+ let success = false;
+ const tokens = [] as any;
+ burnResult.result.events.forEach(({event: {data, method, section}}) => {
+ if (method === 'ExtrinsicSuccess') {
+ success = true;
+ } else if ((section === 'common') && (method === 'ItemDestroyed')) {
+ tokens.push({
+ collectionId: parseInt(data[0].toString(), 10),
+ tokenId: parseInt(data[1].toString(), 10),
+ owner: data[2].toJSON(),
+ });
+ }
+ });
+ return {success, tokens};
+ }
+
+ static findCollectionInEvents(events: {event: IChainEvent}[], collectionId: number, expectedSection: string, expectedMethod: string, label?: string) {
+ let eventId = null;
+ events.forEach(({event: {data, method, section}}) => {
+ if ((section === expectedSection) && (method === expectedMethod)) {
+ eventId = parseInt(data[0].toString(), 10);
+ }
+ });
+
+ if (eventId === null) {
+ throw Error(`No ${expectedMethod} event for ${label}`);
+ }
+ return eventId === collectionId;
+ }
+
+ static isTokenTransferSuccess(events: {event: IChainEvent}[], collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n) {
+ const normalizeAddress = (address: string | ICrossAccountId) => {
+ if(typeof address === 'string') return address;
+ const obj = {} as any;
+ Object.keys(address).forEach(k => {
+ obj[k.toLocaleLowerCase()] = address[k as 'Substrate' | 'Ethereum'];
+ });
+ if(obj.substrate) return {Substrate: this.normalizeSubstrateAddress(obj.substrate)};
+ if(obj.ethereum) return {Ethereum: obj.ethereum.toLocaleLowerCase()};
+ return address;
+ };
+ let transfer = {collectionId: null, tokenId: null, from: null, to: null, amount: 1} as any;
+ events.forEach(({event: {data, method, section}}) => {
+ if ((section === 'common') && (method === 'Transfer')) {
+ const hData = (data as any).toJSON();
+ transfer = {
+ collectionId: hData[0],
+ tokenId: hData[1],
+ from: normalizeAddress(hData[2]),
+ to: normalizeAddress(hData[3]),
+ amount: BigInt(hData[4]),
+ };
+ }
+ });
+ let isSuccess = parseInt(collectionId.toString()) === transfer.collectionId && parseInt(tokenId.toString()) === transfer.tokenId;
+ isSuccess = isSuccess && JSON.stringify(normalizeAddress(fromAddressObj)) === JSON.stringify(transfer.from);
+ isSuccess = isSuccess && JSON.stringify(normalizeAddress(toAddressObj)) === JSON.stringify(transfer.to);
+ isSuccess = isSuccess && amount === transfer.amount;
+ return isSuccess;
+ }
+}
+
+
+class ChainHelperBase {
+ transactionStatus = UniqueUtil.transactionStatus;
+ chainLogType = UniqueUtil.chainLogType;
+ util: typeof UniqueUtil;
+ logger: ILogger;
+ api: ApiPromise | null;
+ forcedNetwork: TUniqueNetworks | null;
+ network: TUniqueNetworks | null;
+ chainLog: IUniqueHelperLog[];
+
+ constructor(logger?: ILogger) {
+ this.util = UniqueUtil;
+ if (typeof logger == 'undefined') logger = this.util.getDefaultLogger();
+ this.logger = logger;
+ this.api = null;
+ this.forcedNetwork = null;
+ this.network = null;
+ this.chainLog = [];
+ }
+
+ clearChainLog(): void {
+ this.chainLog = [];
+ }
+
+ forceNetwork(value: TUniqueNetworks): void {
+ this.forcedNetwork = value;
+ }
+
+ async connect(wsEndpoint: string, listeners?: IApiListeners) {
+ if (this.api !== null) throw Error('Already connected');
+ const {api, network} = await ChainHelperBase.createConnection(wsEndpoint, listeners, this.forcedNetwork);
+ this.api = api;
+ this.network = network;
+ }
+
+ async disconnect() {
+ if (this.api === null) return;
+ await this.api.disconnect();
+ this.api = null;
+ this.network = null;
+ }
+
+ static async detectNetwork(api: ApiPromise): Promise<TUniqueNetworks> {
+ const spec = (await api.query.system.lastRuntimeUpgrade()).toJSON() as any;
+ if(['quartz', 'unique'].indexOf(spec.specName) > -1) return spec.specName;
+ return 'opal';
+ }
+
+ static async detectNetworkByWsEndpoint(wsEndpoint: string): Promise<TUniqueNetworks> {
+ const api = new ApiPromise({provider: new WsProvider(wsEndpoint)});
+ await api.isReady;
+
+ const network = await this.detectNetwork(api);
+
+ await api.disconnect();
+
+ return network;
+ }
+
+ static async createConnection(wsEndpoint: string, listeners?: IApiListeners, network?: TUniqueNetworks | null): Promise<{
+ api: ApiPromise;
+ network: TUniqueNetworks;
+ }> {
+ if(typeof network === 'undefined' || network === null) network = 'opal';
+ const supportedRPC = {
+ opal: {
+ unique: require('@unique-nft/opal-testnet-types/definitions').unique.rpc,
+ },
+ quartz: {
+ unique: require('@unique-nft/quartz-mainnet-types/definitions').unique.rpc,
+ },
+ unique: {
+ unique: require('@unique-nft/unique-mainnet-types/definitions').unique.rpc,
+ },
+ };
+ if(!supportedRPC.hasOwnProperty(network)) network = await this.detectNetworkByWsEndpoint(wsEndpoint);
+ const rpc = supportedRPC[network];
+
+ // TODO: investigate how to replace rpc in runtime
+ // api._rpcCore.addUserInterfaces(rpc);
+
+ const api = new ApiPromise({provider: new WsProvider(wsEndpoint), rpc});
+
+ await api.isReadyOrError;
+
+ if (typeof listeners === 'undefined') listeners = {};
+ for (const event of ['connected', 'disconnected', 'error', 'ready', 'decorated']) {
+ if (!listeners.hasOwnProperty(event) || typeof listeners[event as TApiAllowedListeners] === 'undefined') continue;
+ api.on(event as ApiInterfaceEvents, listeners[event as TApiAllowedListeners] as (...args: any[]) => any);
+ }
+
+ return {api, network};
+ }
+
+ getTransactionStatus(data: {events: {event: IChainEvent}[], status: any}) {
+ const {events, status} = data;
+ if (status.isReady) {
+ return this.transactionStatus.NOT_READY;
+ }
+ if (status.isBroadcast) {
+ return this.transactionStatus.NOT_READY;
+ }
+ if (status.isInBlock || status.isFinalized) {
+ const errors = events.filter(e => e.event.data.method === 'ExtrinsicFailed');
+ if (errors.length > 0) {
+ return this.transactionStatus.FAIL;
+ }
+ if (events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) {
+ return this.transactionStatus.SUCCESS;
+ }
+ }
+
+ return this.transactionStatus.FAIL;
+ }
+
+ signTransaction(sender: TSigner, transaction: any, label = 'transaction', options = null) {
+ const sign = (callback: any) => {
+ if(options !== null) return transaction.signAndSend(sender, options, callback);
+ return transaction.signAndSend(sender, callback);
+ };
+ return new Promise(async (resolve, reject) => {
+ try {
+ const unsub = await sign((result: any) => {
+ const status = this.getTransactionStatus(result);
+
+ if (status === this.transactionStatus.SUCCESS) {
+ this.logger.log(`${label} successful`);
+ unsub();
+ resolve({result, status});
+ } else if (status === this.transactionStatus.FAIL) {
+ let moduleError = null;
+
+ if (result.hasOwnProperty('dispatchError')) {
+ const dispatchError = result['dispatchError'];
+
+ if (dispatchError && dispatchError.isModule) {
+ const modErr = dispatchError.asModule;
+ const errorMeta = dispatchError.registry.findMetaError(modErr);
+
+ moduleError = `${errorMeta.section}.${errorMeta.name}`;
+ }
+ else {
+ this.logger.log(result, this.logger.level.ERROR);
+ }
+ }
+
+ this.logger.log(`Something went wrong with ${label}. Status: ${status}`, this.logger.level.ERROR);
+ unsub();
+ reject({status, moduleError, result});
+ }
+ });
+ } catch (e) {
+ this.logger.log(e, this.logger.level.ERROR);
+ reject(e);
+ }
+ });
+ }
+
+ constructApiCall(apiCall: string, params: any[]) {
+ if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);
+ let call = this.api as any;
+ for(const part of apiCall.slice(4).split('.')) {
+ call = call[part];
+ }
+ return call(...params);
+ }
+
+ async executeExtrinsic(sender: TSigner, extrinsic: string, params: any[], expectSuccess=false, failureMessage='expected success') {
+ if(this.api === null) throw Error('API not initialized');
+ if(!extrinsic.startsWith('api.tx.')) throw Error(`${extrinsic} is not transaction`);
+
+ const startTime = (new Date()).getTime();
+ let result: ITransactionResult;
+ let events = [];
+ try {
+ result = await this.signTransaction(sender, this.constructApiCall(extrinsic, params), extrinsic) as ITransactionResult;
+ events = result.result.events.map((x: any) => x.toHuman());
+ }
+ catch(e) {
+ if(!(e as object).hasOwnProperty('status')) throw e;
+ result = e as ITransactionResult;
+ }
+
+ const endTime = (new Date()).getTime();
+
+ const log = {
+ executedAt: endTime,
+ executionTime: endTime - startTime,
+ type: this.chainLogType.EXTRINSIC,
+ status: result.status,
+ call: extrinsic,
+ params,
+ } as IUniqueHelperLog;
+
+ if(result.status !== this.transactionStatus.SUCCESS && result.moduleError) log.moduleError = result.moduleError;
+ if(events.length > 0) log.events = events;
+
+ this.chainLog.push(log);
+
+ if(expectSuccess && result.status !== this.transactionStatus.SUCCESS) throw Error(failureMessage);
+ return result;
+ }
+
+ async callRpc(rpc: string, params?: any[]) {
+ if(typeof params === 'undefined') params = [];
+ if(this.api === null) throw Error('API not initialized');
+ if(!rpc.startsWith('api.rpc.') && !rpc.startsWith('api.query.')) throw Error(`${rpc} is not RPC call`);
+
+ const startTime = (new Date()).getTime();
+ let result;
+ let error = null;
+ const log = {
+ type: this.chainLogType.RPC,
+ call: rpc,
+ params,
+ } as IUniqueHelperLog;
+
+ try {
+ result = await this.constructApiCall(rpc, params);
+ }
+ catch(e) {
+ error = e;
+ }
+
+ const endTime = (new Date()).getTime();
+
+ log.executedAt = endTime;
+ log.status = (error === null ? this.transactionStatus.SUCCESS : this.transactionStatus.FAIL) as 'Fail' | 'Success';
+ log.executionTime = endTime - startTime;
+
+ this.chainLog.push(log);
+
+ if(error !== null) throw error;
+
+ return result;
+ }
+
+ getSignerAddress(signer: IKeyringPair | string): string {
+ if(typeof signer === 'string') return signer;
+ return signer.address;
+ }
+}
+
+
+class HelperGroup {
+ helper: UniqueHelper;
+
+ constructor(uniqueHelper: UniqueHelper) {
+ this.helper = uniqueHelper;
+ }
+}
+
+
+class CollectionGroup extends HelperGroup {
+ /**
+ * Get number of blocks when sponsored transaction is available.
+ *
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param addressObj address for which the sponsorship is checked
+ * @example await getTokenNextSponsored(1, 2, {Substrate: '5DfhbVfww7ThF8q6f3...'});
+ * @returns number of blocks or null if sponsorship hasn't been set
+ */
+ async getTokenNextSponsored(collectionId: number, tokenId: number, addressObj: ICrossAccountId): Promise<number | null> {
+ return (await this.helper.callRpc('api.rpc.unique.nextSponsored', [collectionId, addressObj, tokenId])).toJSON();
+ }
+
+ /**
+ * Get the number of created collections.
+ *
+ * @returns number of created collections
+ */
+ async getTotalCount(): Promise<number> {
+ return (await this.helper.callRpc('api.rpc.unique.collectionStats')).created.toNumber();
+ }
+
+ /**
+ * Get information about the collection with additional data, including the number of tokens it contains, its administrators, the normalized address of the collection's owner, and decoded name and description.
+ *
+ * @param collectionId ID of collection
+ * @example await getData(2)
+ * @returns collection information object
+ */
+ async getData(collectionId: number): Promise<{
+ id: number;
+ name: string;
+ description: string;
+ tokensCount: number;
+ admins: ICrossAccountId[];
+ normalizedOwner: TSubstrateAccount;
+ raw: any
+ } | null> {
+ const collection = await this.helper.callRpc('api.rpc.unique.collectionById', [collectionId]);
+ const humanCollection = collection.toHuman(), collectionData = {
+ id: collectionId, name: null, description: null, tokensCount: 0, admins: [],
+ raw: humanCollection,
+ } as any, jsonCollection = collection.toJSON();
+ if (humanCollection === null) return null;
+ collectionData.raw.limits = jsonCollection.limits;
+ collectionData.raw.permissions = jsonCollection.permissions;
+ collectionData.normalizedOwner = this.helper.address.normalizeSubstrate(collectionData.raw.owner);
+ for (const key of ['name', 'description']) {
+ collectionData[key] = this.helper.util.vec2str(humanCollection[key]);
+ }
+
+ collectionData.tokensCount = (['RFT', 'NFT'].includes(humanCollection.mode)) ? await this.helper[humanCollection.mode.toLocaleLowerCase() as 'nft' | 'rft'].getLastTokenId(collectionId) : 0;
+ collectionData.admins = await this.getAdmins(collectionId);
+
+ return collectionData;
+ }
+
+ /**
+ * Get the normalized addresses of the collection's administrators.
+ *
+ * @param collectionId ID of collection
+ * @example await getAdmins(1)
+ * @returns array of administrators
+ */
+ async getAdmins(collectionId: number): Promise<ICrossAccountId[]> {
+ const normalized = [];
+ for(const admin of (await this.helper.callRpc('api.rpc.unique.adminlist', [collectionId])).toHuman()) {
+ if(admin.Substrate) normalized.push({Substrate: this.helper.address.normalizeSubstrate(admin.Substrate)});
+ else normalized.push(admin);
+ }
+ return normalized;
+ }
+
+ /**
+ * Get the effective limits of the collection instead of null for default values
+ *
+ * @param collectionId ID of collection
+ * @example await getEffectiveLimits(2)
+ * @returns object of collection limits
+ */
+ async getEffectiveLimits(collectionId: number): Promise<ICollectionLimits> {
+ return (await this.helper.callRpc('api.rpc.unique.effectiveCollectionLimits', [collectionId])).toJSON();
+ }
+
+ /**
+ * Burns the collection if the signer has sufficient permissions and collection is empty.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param label extra label for log
+ * @example await helper.collection.burn(aliceKeyring, 3);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async burn(signer: TSigner, collectionId: number, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.destroyCollection', [collectionId],
+ true, `Unable to burn collection for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionDestroyed', label);
+ }
+
+ /**
+ * Sets the sponsor for the collection (Requires the Substrate address).
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param sponsorAddress Sponsor substrate address
+ * @param label extra label for log
+ * @example setSponsor(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...")
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async setSponsor(signer: TSigner, collectionId: number, sponsorAddress: TSubstrateAccount, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setCollectionSponsor', [collectionId, sponsorAddress],
+ true, `Unable to set collection sponsor for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionSponsorSet', label);
+ }
+
+ /**
+ * Confirms consent to sponsor the collection on behalf of the signer.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param label extra label for log
+ * @example confirmSponsorship(aliceKeyring, 10)
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async confirmSponsorship(signer: TSigner, collectionId: number, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.confirmSponsorship', [collectionId],
+ true, `Unable to confirm collection sponsorship for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'SponsorshipConfirmed', label);
+ }
+
+ /**
+ * Sets the limits of the collection. At least one limit must be specified for a correct call.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param limits collection limits object
+ * @param label extra label for log
+ * @example
+ * await setLimits(
+ * aliceKeyring,
+ * 10,
+ * {
+ * sponsorTransferTimeout: 0,
+ * ownerCanDestroy: false
+ * }
+ * )
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async setLimits(signer: TSigner, collectionId: number, limits: ICollectionLimits, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setCollectionLimits', [collectionId, limits],
+ true, `Unable to set collection limits for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionLimitSet', label);
+ }
+
+ /**
+ * Changes the owner of the collection to the new Substrate address.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param ownerAddress substrate address of new owner
+ * @param label extra label for log
+ * @example changeOwner(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...")
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async changeOwner(signer: TSigner, collectionId: number, ownerAddress: TSubstrateAccount, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.changeCollectionOwner', [collectionId, ownerAddress],
+ true, `Unable to change collection owner for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionOwnedChanged', label);
+ }
+
+ /**
+ * Adds a collection administrator.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param adminAddressObj Administrator address (substrate or ethereum)
+ * @param label extra label for log
+ * @example addAdmin(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."})
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async addAdmin(signer: TSigner, collectionId: number, adminAddressObj: ICrossAccountId, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.addCollectionAdmin', [collectionId, adminAddressObj],
+ true, `Unable to add collection admin for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminAdded', label);
+ }
+
+ /**
+ * Removes a collection administrator.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param adminAddressObj Administrator address (substrate or ethereum)
+ * @param label extra label for log
+ * @example removeAdmin(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."})
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async removeAdmin(signer: TSigner, collectionId: number, adminAddressObj: ICrossAccountId, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.removeCollectionAdmin', [collectionId, adminAddressObj],
+ true, `Unable to remove collection admin for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved', label);
+ }
+
+ /**
+ * Sets onchain permissions for selected collection.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param permissions collection permissions object
+ * @param label extra label for log
+ * @example setPermissions(aliceKeyring, 10, {access:'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true}});
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async setPermissions(signer: TSigner, collectionId: number, permissions: ICollectionPermissions, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setCollectionPermissions', [collectionId, permissions],
+ true, `Unable to set collection permissions for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionPermissionSet', label);
+ }
+
+ /**
+ * Enables nesting for selected collection. If `restricted` set, you can nest only tokens from specified collections.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param permissions nesting permissions object
+ * @param label extra label for log
+ * @example enableNesting(aliceKeyring, 10, {collectionAdmin: true, tokenOwner: true});
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async enableNesting(signer: TSigner, collectionId: number, permissions: INestingPermissions, label?: string): Promise<boolean> {
+ return await this.setPermissions(signer, collectionId, {nesting: permissions}, label);
+ }
+
+ /**
+ * Disables nesting for selected collection.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param label extra label for log
+ * @example disableNesting(aliceKeyring, 10);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async disableNesting(signer: TSigner, collectionId: number, label?: string): Promise<boolean> {
+ return await this.setPermissions(signer, collectionId, {nesting: {tokenOwner: false, collectionAdmin: false}}, label);
+ }
+
+ /**
+ * Sets onchain properties to the collection.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param properties array of property objects
+ * @param label extra label for log
+ * @example setProperties(aliceKeyring, 10, [{key: "gender", value: "male"}]);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async setProperties(signer: TSigner, collectionId: number, properties: IProperty[], label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setCollectionProperties', [collectionId, properties],
+ true, `Unable to set collection properties for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertySet', label);
+ }
+
+ /**
+ * Deletes onchain properties from the collection.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param propertyKeys array of property keys to delete
+ * @param label
+ * @example deleteProperties(aliceKeyring, 10, ["gender", "age"]);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async deleteProperties(signer: TSigner, collectionId: number, propertyKeys: string[], label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.deleteCollectionProperties', [collectionId, propertyKeys],
+ true, `Unable to delete collection properties for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertyDeleted', label);
+ }
+
+ /**
+ * Changes the owner of the token.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param addressObj address of a new owner
+ * @param amount amount of tokens to be transfered. For NFT must be set to 1n
+ * @example transferToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})
+ * @returns true if the token success, otherwise false
+ */
+ async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId, amount=1n): Promise<boolean> {
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.transfer', [addressObj, collectionId, tokenId, amount],
+ true, `Unable to transfer token #${tokenId} from collection #${collectionId}`,
+ );
+
+ return this.helper.util.isTokenTransferSuccess(result.result.events, collectionId, tokenId, {Substrate: typeof signer === 'string' ? signer : signer.address}, addressObj, amount);
+ }
+
+ /**
+ *
+ * Change ownership of a token(s) on behalf of the owner.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param fromAddressObj address on behalf of which the token will be sent
+ * @param toAddressObj new token owner
+ * @param amount amount of tokens to be transfered. For NFT must be set to 1n
+ * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg"}, {Ethereum: "0x9F0583DbB85..."})
+ * @returns true if the token success, otherwise false
+ */
+ async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.transferFrom', [fromAddressObj, toAddressObj, collectionId, tokenId, amount],
+ true, `Unable to transfer token #${tokenId} from collection #${collectionId}`,
+ );
+ return this.helper.util.isTokenTransferSuccess(result.result.events, collectionId, tokenId, fromAddressObj, toAddressObj, amount);
+ }
+
+ /**
+ *
+ * Destroys a concrete instance of NFT/RFT or burns a specified amount of fungible tokens.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param label
+ * @param amount amount of tokens to be burned. For NFT must be set to 1n
+ * @example burnToken(aliceKeyring, 10, 5);
+ * @returns ```true``` and burnt token number is extrinsic success. Otherwise ```false``` and ```null```
+ */
+ async burnToken(signer: TSigner, collectionId: number, tokenId: number, label?: string, amount=1n): Promise<{
+ success: boolean,
+ token: number | null
+ }> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const burnResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.burnItem', [collectionId, tokenId, amount],
+ true, `Unable to burn token for ${label}`,
+ );
+ const burnedTokens = this.helper.util.extractTokensFromBurnResult(burnResult, label);
+ if (burnedTokens.tokens.length > 1) throw Error('Burned multiple tokens');
+ return {success: burnedTokens.success, token: burnedTokens.tokens.length > 0 ? burnedTokens.tokens[0] : null};
+ }
+
+ /**
+ * Destroys a concrete instance of NFT on behalf of the owner
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param fromAddressObj address on behalf of which the token will be burnt
+ * @param tokenId ID of token
+ * @param label
+ * @param amount amount of tokens to be burned. For NFT must be set to 1n
+ * @example burnTokenFrom(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."}, 5, {Ethereum: "0x9F0583DbB85..."})
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async burnTokenFrom(signer: TSigner, collectionId: number, fromAddressObj: ICrossAccountId, tokenId: number, label?: string, amount=1n): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const burnResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.burnFrom', [collectionId, fromAddressObj, tokenId, amount],
+ true, `Unable to burn token from for ${label}`,
+ );
+ const burnedTokens = this.helper.util.extractTokensFromBurnResult(burnResult, label);
+ return burnedTokens.success && burnedTokens.tokens.length > 0;
+ }
+
+ /**
+ * Set, change, or remove approved address to transfer the ownership of the NFT.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param toAddressObj
+ * @param label
+ * @param amount amount of token to be approved. For NFT must be set to 1n
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, label?: string, amount=1n) {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const approveResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.approve', [toAddressObj, collectionId, tokenId, amount],
+ true, `Unable to approve token for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(approveResult.result.events, collectionId, 'common', 'Approved', label);
+ }
+
+ /**
+ * Get the amount of token pieces approved to transfer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param toAccountObj
+ * @param fromAccountObj
+ * @example getTokenApprovedPieces(10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Substrate: "5ERZNF88Mm7UGfPP3mdG..."})
+ * @returns number of approved to transfer pieces
+ */
+ async getTokenApprovedPieces(collectionId: number, tokenId: number, toAccountObj: ICrossAccountId, fromAccountObj: ICrossAccountId): Promise<bigint> {
+ return (await this.helper.callRpc('api.rpc.unique.allowance', [collectionId, fromAccountObj, toAccountObj, tokenId])).toBigInt();
+ }
+
+ /**
+ * Get the last created token id
+ * @param collectionId ID of collection
+ * @example getLastTokenId(10);
+ * @returns id of the last created token
+ */
+ async getLastTokenId(collectionId: number): Promise<number> {
+ return (await this.helper.callRpc('api.rpc.unique.lastTokenId', [collectionId])).toNumber();
+ }
+
+ /**
+ * Check if token exists
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @example isTokenExists(10, 20);
+ * @returns true if the token exists, otherwise false
+ */
+ async isTokenExists(collectionId: number, tokenId: number): Promise<boolean> {
+ return (await this.helper.callRpc('api.rpc.unique.tokenExists', [collectionId, tokenId])).toJSON();
+ }
+}
+
+class NFTnRFT extends CollectionGroup {
+ /**
+ * Get tokens owned by account
+ *
+ * @param collectionId ID of collection
+ * @param addressObj tokens owner
+ * @example getTokensByAddress(10, {Substrate: "5DyN4Y92vZCjv38fg..."})
+ * @returns array of token ids owned by account
+ */
+ async getTokensByAddress(collectionId: number, addressObj: ICrossAccountId): Promise<number[]> {
+ return (await this.helper.callRpc('api.rpc.unique.accountTokens', [collectionId, addressObj])).toJSON();
+ }
+
+ /**
+ * Get token data
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param blockHashAt
+ * @param propertyKeys
+ * @example getToken(10, 5);
+ * @returns human readable token data
+ */
+ async getToken(collectionId: number, tokenId: number, blockHashAt?: string, propertyKeys?: string[]): Promise<{
+ properties: IProperty[];
+ owner: ICrossAccountId;
+ normalizedOwner: ICrossAccountId;
+ }| null> {
+ let tokenData;
+ if(typeof blockHashAt === 'undefined') {
+ tokenData = await this.helper.callRpc('api.rpc.unique.tokenData', [collectionId, tokenId]);
+ }
+ else {
+ if(typeof propertyKeys === 'undefined') {
+ const collection = (await this.helper.callRpc('api.rpc.unique.collectionById', [collectionId])).toHuman();
+ if(!collection) return null;
+ propertyKeys = collection.tokenPropertyPermissions.map((x: ITokenPropertyPermission) => x.key);
+ }
+ tokenData = await this.helper.callRpc('api.rpc.unique.tokenData', [collectionId, tokenId, propertyKeys, blockHashAt]);
+ }
+ tokenData = tokenData.toHuman();
+ if (tokenData === null || tokenData.owner === null) return null;
+ const owner = {} as any;
+ for (const key of Object.keys(tokenData.owner)) {
+ owner[key.toLocaleLowerCase()] = key.toLocaleLowerCase() === 'substrate' ? this.helper.address.normalizeSubstrate(tokenData.owner[key]) : tokenData.owner[key];
+ }
+ tokenData.normalizedOwner = crossAccountIdFromLower(owner);
+ return tokenData;
+ }
+
+ /**
+ * Set permissions to change token properties
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param permissions permissions to change a property by the collection owner or admin
+ * @param label
+ * @example setTokenPropertyPermissions(
+ * aliceKeyring, 10, [{key: "gender", permission: {tokenOwner: true, mutable: true, collectionAdmin: true}}]
+ * )
+ * @returns true if extrinsic success otherwise false
+ */
+ async setTokenPropertyPermissions(signer: TSigner, collectionId: number, permissions: ITokenPropertyPermission[], label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setTokenPropertyPermissions', [collectionId, permissions],
+ true, `Unable to set token property permissions for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'PropertyPermissionSet', label);
+ }
+
+ /**
+ * Set token properties
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param properties
+ * @param label
+ * @example setTokenProperties(aliceKeyring, 10, 5, [{key: "gender", value: "female"}, {key: "age", value: "23"}])
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async setTokenProperties(signer: TSigner, collectionId: number, tokenId: number, properties: IProperty[], label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `token #${tokenId} from collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setTokenProperties', [collectionId, tokenId, properties],
+ true, `Unable to set token properties for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertySet', label);
+ }
+
+ /**
+ * Delete the provided properties of a token
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param propertyKeys property keys to be deleted
+ * @param label
+ * @example deleteTokenProperties(aliceKeyring, 10, 5, ["gender", "age"])
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async deleteTokenProperties(signer: TSigner, collectionId: number, tokenId: number, propertyKeys: string[], label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `token #${tokenId} from collection #${collectionId}`;
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.deleteTokenProperties', [collectionId, tokenId, propertyKeys],
+ true, `Unable to delete token properties for ${label}`,
+ );
+
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertyDeleted', label);
+ }
+
+ /**
+ * Mint new collection
+ * @param signer keyring of signer
+ * @param collectionOptions basic collection options and properties
+ * @param mode NFT or RFT type of a collection
+ * @param errorLabel
+ * @example mintCollection(aliceKeyring, {name: 'New', description: "New collection", tokenPrefix: "NEW"}, "NFT")
+ * @returns object of the created collection
+ */
+ async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, mode: 'NFT' | 'RFT', errorLabel = 'Unable to mint collection'): Promise<UniqueCollectionBase> {
+ collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object
+ collectionOptions.mode = (mode === 'NFT') ? {nft: null} : {refungible: null};
+ for (const key of ['name', 'description', 'tokenPrefix']) {
+ if (typeof collectionOptions[key as 'name' | 'description' | 'tokenPrefix'] === 'string') collectionOptions[key as 'name' | 'description' | 'tokenPrefix'] = this.helper.util.str2vec(collectionOptions[key as 'name' | 'description' | 'tokenPrefix'] as string);
+ }
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createCollectionEx', [collectionOptions],
+ true, errorLabel,
+ );
+ return this.getCollectionObject(this.helper.util.extractCollectionIdFromCreationResult(creationResult, errorLabel));
+ }
+
+ getCollectionObject(collectionId: number): any {
+ return null;
+ }
+
+ getTokenObject(collectionId: number, tokenId: number): any {
+ return null;
+ }
+}
+
+
+class NFTGroup extends NFTnRFT {
+ /**
+ * Get collection object
+ * @param collectionId ID of collection
+ * @example getCollectionObject(2);
+ * @returns instance of UniqueNFTCollection
+ */
+ getCollectionObject(collectionId: number): UniqueNFTCollection {
+ return new UniqueNFTCollection(collectionId, this.helper);
+ }
+
+ /**
+ * Get token object
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @example getTokenObject(10, 5);
+ * @returns instance of UniqueNFTToken
+ */
+ getTokenObject(collectionId: number, tokenId: number): UniqueNFTToken {
+ return new UniqueNFTToken(tokenId, this.getCollectionObject(collectionId));
+ }
+
+ /**
+ * Get token's owner
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param blockHashAt
+ * @example getTokenOwner(10, 5);
+ * @returns Address in CrossAccountId format, e.g. {Substrate: "5DnSF6RRjwteE3BrCj..."}
+ */
+ async getTokenOwner(collectionId: number, tokenId: number, blockHashAt?: string): Promise<ICrossAccountId> {
+ let owner;
+ if (typeof blockHashAt === 'undefined') {
+ owner = await this.helper.callRpc('api.rpc.unique.tokenOwner', [collectionId, tokenId]);
+ } else {
+ owner = await this.helper.callRpc('api.rpc.unique.tokenOwner', [collectionId, tokenId, blockHashAt]);
+ }
+ return crossAccountIdFromLower(owner.toJSON());
+ }
+
+ /**
+ * Is token approved to transfer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param toAccountObj address to be approved
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async isTokenApproved(collectionId: number, tokenId: number, toAccountObj: ICrossAccountId): Promise<boolean> {
+ return (await this.getTokenApprovedPieces(collectionId, tokenId, toAccountObj, await this.getTokenOwner(collectionId, tokenId))) === 1n;
+ }
+
+ /**
+ * Changes the owner of the token.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param addressObj address of a new owner
+ * @example transferToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId): Promise<boolean> {
+ return await super.transferToken(signer, collectionId, tokenId, addressObj, 1n);
+ }
+
+ /**
+ *
+ * Change ownership of a NFT on behalf of the owner.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param fromAddressObj address on behalf of which the token will be sent
+ * @param toAddressObj new token owner
+ * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Ethereum: "0x9F0583DbB85..."})
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId): Promise<boolean> {
+ return await super.transferTokenFrom(signer, collectionId, tokenId, fromAddressObj, toAddressObj, 1n);
+ }
+
+ /**
+ * Recursively find the address that owns the token
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param blockHashAt
+ * @example getTokenTopmostOwner(10, 5);
+ * @returns address in CrossAccountId format, e.g. {Substrate: "5DyN4Y92vZCjv38fg..."}
+ */
+ async getTokenTopmostOwner(collectionId: number, tokenId: number, blockHashAt?: string): Promise<ICrossAccountId | null> {
+ let owner;
+ if (typeof blockHashAt === 'undefined') {
+ owner = await this.helper.callRpc('api.rpc.unique.topmostTokenOwner', [collectionId, tokenId]);
+ } else {
+ owner = await this.helper.callRpc('api.rpc.unique.topmostTokenOwner', [collectionId, tokenId, blockHashAt]);
+ }
+
+ if (owner === null) return null;
+
+ owner = owner.toHuman();
+
+ return owner.Substrate ? {Substrate: this.helper.address.normalizeSubstrate(owner.Substrate)} : owner;
+ }
+
+ /**
+ * Get tokens nested in the provided token
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param blockHashAt
+ * @example getTokenChildren(10, 5);
+ * @returns tokens whose depth of nesting is <= 5
+ */
+ async getTokenChildren(collectionId: number, tokenId: number, blockHashAt?: string): Promise<IToken[]> {
+ let children;
+ if(typeof blockHashAt === 'undefined') {
+ children = await this.helper.callRpc('api.rpc.unique.tokenChildren', [collectionId, tokenId]);
+ } else {
+ children = await this.helper.callRpc('api.rpc.unique.tokenChildren', [collectionId, tokenId, blockHashAt]);
+ }
+
+ return children.toJSON().map((x: any) => {
+ return {collectionId: x.collection, tokenId: x.token};
+ });
+ }
+
+ /**
+ * Nest one token into another
+ * @param signer keyring of signer
+ * @param tokenObj token to be nested
+ * @param rootTokenObj token to be parent
+ * @param label
+ * @example nestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4});
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async nestToken(signer: TSigner, tokenObj: IToken, rootTokenObj: IToken, label='nest token'): Promise<boolean> {
+ const rootTokenAddress = {Ethereum: this.helper.util.getNestingTokenAddress(rootTokenObj.collectionId, rootTokenObj.tokenId)};
+ const result = await this.transferToken(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress);
+ if(!result) {
+ throw Error(`Unable to nest token for ${label}`);
+ }
+ return result;
+ }
+
+ /**
+ * Remove token from nested state
+ * @param signer keyring of signer
+ * @param tokenObj token to unnest
+ * @param rootTokenObj parent of a token
+ * @param toAddressObj address of a new token owner
+ * @param label
+ * @example unnestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4}, {Substrate: "5DyN4Y92vZCjv38fg..."});
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async unnestToken(signer: TSigner, tokenObj: IToken, rootTokenObj: IToken, toAddressObj: ICrossAccountId, label='unnest token'): Promise<boolean> {
+ const rootTokenAddress = {Ethereum: this.helper.util.getNestingTokenAddress(rootTokenObj.collectionId, rootTokenObj.tokenId)};
+ const result = await this.transferTokenFrom(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress, toAddressObj);
+ if(!result) {
+ throw Error(`Unable to unnest token for ${label}`);
+ }
+ return result;
+ }
+
+ /**
+ * Mint new collection
+ * @param signer keyring of signer
+ * @param collectionOptions Collection options
+ * @param label
+ * @example
+ * mintCollection(aliceKeyring, {
+ * name: 'New',
+ * description: 'New collection',
+ * tokenPrefix: 'NEW',
+ * })
+ * @returns object of the created collection
+ */
+ async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, label = 'new collection'): Promise<UniqueNFTCollection> {
+ return await super.mintCollection(signer, collectionOptions, 'NFT', `Unable to mint NFT collection for ${label}`) as UniqueNFTCollection;
+ }
+
+ /**
+ * Mint new token
+ * @param signer keyring of signer
+ * @param data token data
+ * @param label
+ * @returns created token object
+ */
+ async mintToken(signer: TSigner, data: { collectionId: number; owner: ICrossAccountId | string; properties?: IProperty[]; }, label?: string): Promise<UniqueNFTToken> {
+ if(typeof label === 'undefined') label = `collection #${data.collectionId}`;
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createItem', [data.collectionId, (typeof data.owner === 'string') ? {Substrate: data.owner} : data.owner, {
+ nft: {
+ properties: data.properties,
+ },
+ }],
+ true, `Unable to mint NFT token for ${label}`,
+ );
+ const createdTokens = this.helper.util.extractTokensFromCreationResult(creationResult, label);
+ if (createdTokens.tokens.length > 1) throw Error('Minted multiple tokens');
+ if (createdTokens.tokens.length < 1) throw Error('No tokens minted');
+ return this.getTokenObject(data.collectionId, createdTokens.tokens[0].tokenId);
+ }
+
+ /**
+ * Mint multiple NFT tokens
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokens array of tokens with owner and properties
+ * @param label
+ * @example
+ * mintMultipleTokens(aliceKeyring, 10, [{
+ * owner: {Substrate: "5DyN4Y92vZCjv38fg..."},
+ * properties: [{key: "gender", value: "male"},{key: "age", value: "45"}],
+ * },{
+ * owner: {Ethereum: "0x9F0583DbB855d..."},
+ * properties: [{key: "gender", value: "female"},{key: "age", value: "22"}],
+ * }]);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[], label?: string): Promise<UniqueNFTToken[]> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createMultipleItemsEx', [collectionId, {NFT: tokens}],
+ true, `Unable to mint NFT tokens for ${label}`,
+ );
+ const collection = this.getCollectionObject(collectionId);
+ return this.helper.util.extractTokensFromCreationResult(creationResult, label).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));
+ }
+
+ /**
+ * Mint multiple NFT tokens with one owner
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param owner tokens owner
+ * @param tokens array of tokens with owner and properties
+ * @param label
+ * @example
+ * mintMultipleTokensWithOneOwner(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...", [{
+ * properties: [{
+ * key: "gender",
+ * value: "female",
+ * },{
+ * key: "age",
+ * value: "33",
+ * }],
+ * }]);
+ * @returns array of newly created tokens
+ */
+ async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {properties?: IProperty[]}[], label?: string): Promise<UniqueNFTToken[]> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const rawTokens = [];
+ for (const token of tokens) {
+ const raw = {NFT: {properties: token.properties}};
+ rawTokens.push(raw);
+ }
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createMultipleItems', [collectionId, owner, rawTokens],
+ true, `Unable to mint NFT tokens for ${label}`,
+ );
+ const collection = this.getCollectionObject(collectionId);
+ return this.helper.util.extractTokensFromCreationResult(creationResult, label).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));
+ }
+
+ /**
+ * Destroys a concrete instance of NFT.
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param label
+ * @example burnToken(aliceKeyring, 10, 5);
+ * @returns ```true``` and burnt token number is extrinsic success. Otherwise ```false``` and ```null```
+ */
+ async burnToken(signer: IKeyringPair, collectionId: number, tokenId: number, label?: string): Promise<{ success: boolean; token: number | null; }> {
+ return await super.burnToken(signer, collectionId, tokenId, label, 1n);
+ }
+
+ /**
+ * Set, change, or remove approved address to transfer the ownership of the NFT.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param toAddressObj address to approve
+ * @param label
+ * @example approveToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, label?: string) {
+ return super.approveToken(signer, collectionId, tokenId, toAddressObj, label, 1n);
+ }
+}
+
+
+class RFTGroup extends NFTnRFT {
+ /**
+ * Get collection object
+ * @param collectionId ID of collection
+ * @example getCollectionObject(2);
+ * @returns instance of UniqueRFTCollection
+ */
+ getCollectionObject(collectionId: number): UniqueRFTCollection {
+ return new UniqueRFTCollection(collectionId, this.helper);
+ }
+
+ /**
+ * Get token object
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @example getTokenObject(10, 5);
+ * @returns instance of UniqueNFTToken
+ */
+ getTokenObject(collectionId: number, tokenId: number): UniqueRFTToken {
+ return new UniqueRFTToken(tokenId, this.getCollectionObject(collectionId));
+ }
+
+ /**
+ * Get top 10 token owners with the largest number of pieces
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @example getTokenTop10Owners(10, 5);
+ * @returns array of top 10 owners
+ */
+ async getTokenTop10Owners(collectionId: number, tokenId: number): Promise<ICrossAccountId[]> {
+ return (await this.helper.callRpc('api.rpc.unique.tokenOwners', [collectionId, tokenId])).toJSON().map(crossAccountIdFromLower);
+ }
+
+ /**
+ * Get number of pieces owned by address
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param addressObj address token owner
+ * @example getTokenBalance(10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."});
+ * @returns number of pieces ownerd by address
+ */
+ async getTokenBalance(collectionId: number, tokenId: number, addressObj: ICrossAccountId): Promise<bigint> {
+ return (await this.helper.callRpc('api.rpc.unique.balance', [collectionId, addressObj, tokenId])).toBigInt();
+ }
+
+ /**
+ * Transfer pieces of token to another address
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param addressObj address of a new owner
+ * @param amount number of pieces to be transfered
+ * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, 2000n)
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId, amount=100n): Promise<boolean> {
+ return await super.transferToken(signer, collectionId, tokenId, addressObj, amount);
+ }
+
+ /**
+ * Change ownership of some pieces of RFT on behalf of the owner.
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param fromAddressObj address on behalf of which the token will be sent
+ * @param toAddressObj new token owner
+ * @param amount number of pieces to be transfered
+ * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Substrate: "5DfhbVfww7ThF8q6f3i..."}, 2000n)
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=100n): Promise<boolean> {
+ return await super.transferTokenFrom(signer, collectionId, tokenId, fromAddressObj, toAddressObj, amount);
+ }
+
+ /**
+ * Mint new collection
+ * @param signer keyring of signer
+ * @param collectionOptions Collection options
+ * @param label
+ * @example
+ * mintCollection(aliceKeyring, {
+ * name: 'New',
+ * description: 'New collection',
+ * tokenPrefix: 'NEW',
+ * })
+ * @returns object of the created collection
+ */
+ async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, label = 'new collection'): Promise<UniqueRFTCollection> {
+ return await super.mintCollection(signer, collectionOptions, 'RFT', `Unable to mint RFT collection for ${label}`) as UniqueRFTCollection;
+ }
+
+ /**
+ * Mint new token
+ * @param signer keyring of signer
+ * @param data token data
+ * @param label
+ * @example mintToken(aliceKeyring, {collectionId: 10, owner: {Substrate: '5GHoZe9c73RYbVzq...'}, pieces: 10000n});
+ * @returns created token object
+ */
+ async mintToken(signer: TSigner, data: { collectionId: number; owner: ICrossAccountId | string; pieces: bigint; properties?: IProperty[]; }, label?: string): Promise<UniqueRFTToken> {
+ if(typeof label === 'undefined') label = `collection #${data.collectionId}`;
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createItem', [data.collectionId, (typeof data.owner === 'string') ? {Substrate: data.owner} : data.owner, {
+ refungible: {
+ pieces: data.pieces,
+ properties: data.properties,
+ },
+ }],
+ true, `Unable to mint RFT token for ${label}`,
+ );
+ const createdTokens = this.helper.util.extractTokensFromCreationResult(creationResult, label);
+ if (createdTokens.tokens.length > 1) throw Error('Minted multiple tokens');
+ if (createdTokens.tokens.length < 1) throw Error('No tokens minted');
+ return this.getTokenObject(data.collectionId, createdTokens.tokens[0].tokenId);
+ }
+
+ async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, pieces: bigint, properties?: IProperty[]}[], label?: string): Promise<UniqueRFTToken[]> {
+ throw Error('Not implemented');
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createMultipleItemsEx', [collectionId, {RefungibleMultipleOwners: tokens}],
+ true, `Unable to mint RFT tokens for ${label}`,
+ );
+ const collection = this.getCollectionObject(collectionId);
+ return this.helper.util.extractTokensFromCreationResult(creationResult, label).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));
+ }
+
+ /**
+ * Mint multiple RFT tokens with one owner
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param owner tokens owner
+ * @param tokens array of tokens with properties and pieces
+ * @param label
+ * @example mintMultipleTokensWithOneOwner(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, [{pieces: 100000n, properties: [{key: "gender", value: "male"}]}]);
+ * @returns array of newly created RFT tokens
+ */
+ async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {pieces: bigint, properties?: IProperty[]}[], label?: string): Promise<UniqueRFTToken[]> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const rawTokens = [];
+ for (const token of tokens) {
+ const raw = {ReFungible: {pieces: token.pieces, properties: token.properties}};
+ rawTokens.push(raw);
+ }
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createMultipleItems', [collectionId, owner, rawTokens],
+ true, `Unable to mint RFT tokens for ${label}`,
+ );
+ const collection = this.getCollectionObject(collectionId);
+ return this.helper.util.extractTokensFromCreationResult(creationResult, label).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));
+ }
+
+ /**
+ * Destroys a concrete instance of RFT.
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param label
+ * @param amount number of pieces to be burnt
+ * @example burnToken(aliceKeyring, 10, 5);
+ * @returns ```true``` and burnt token number is extrinsic success. Otherwise ```false``` and ```null```
+ */
+ async burnToken(signer: IKeyringPair, collectionId: number, tokenId: number, label?: string, amount=100n): Promise<{ success: boolean; token: number | null; }> {
+ return await super.burnToken(signer, collectionId, tokenId, label, amount);
+ }
+
+ /**
+ * Set, change, or remove approved address to transfer the ownership of the RFT.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param toAddressObj address to approve
+ * @param label
+ * @param amount number of pieces to be approved
+ * @example approveToken(aliceKeyring, 10, 5, {Substrate: "5GHoZe9c73RYbVzq..."}, "", 10000n);
+ * @returns true if the token success, otherwise false
+ */
+ async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, label?: string, amount=100n) {
+ return super.approveToken(signer, collectionId, tokenId, toAddressObj, label, amount);
+ }
+
+ /**
+ * Get total number of pieces
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @example getTokenTotalPieces(10, 5);
+ * @returns number of pieces
+ */
+ async getTokenTotalPieces(collectionId: number, tokenId: number): Promise<bigint> {
+ return (await this.helper.callRpc('api.rpc.unique.totalPieces', [collectionId, tokenId])).unwrap().toBigInt();
+ }
+
+ /**
+ * Change number of token pieces. Signer must be the owner of all token pieces.
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param tokenId ID of token
+ * @param amount new number of pieces
+ * @param label
+ * @example repartitionToken(aliceKeyring, 10, 5, 12345n);
+ * @returns true if the repartion was success, otherwise false
+ */
+ async repartitionToken(signer: TSigner, collectionId: number, tokenId: number, amount: bigint, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const currentAmount = await this.getTokenTotalPieces(collectionId, tokenId);
+ const repartitionResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.repartition', [collectionId, tokenId, amount],
+ true, `Unable to repartition RFT token for ${label}`,
+ );
+ if(currentAmount < amount) return this.helper.util.findCollectionInEvents(repartitionResult.result.events, collectionId, 'common', 'ItemCreated', label);
+ return this.helper.util.findCollectionInEvents(repartitionResult.result.events, collectionId, 'common', 'ItemDestroyed', label);
+ }
+}
+
+
+class FTGroup extends CollectionGroup {
+ /**
+ * Get collection object
+ * @param collectionId ID of collection
+ * @example getCollectionObject(2);
+ * @returns instance of UniqueFTCollection
+ */
+ getCollectionObject(collectionId: number): UniqueFTCollection {
+ return new UniqueFTCollection(collectionId, this.helper);
+ }
+
+ /**
+ * Mint new fungible collection
+ * @param signer keyring of signer
+ * @param collectionOptions Collection options
+ * @param decimalPoints number of token decimals
+ * @param errorLabel
+ * @example
+ * mintCollection(aliceKeyring, {
+ * name: 'New',
+ * description: 'New collection',
+ * tokenPrefix: 'NEW',
+ * }, 18)
+ * @returns newly created fungible collection
+ */
+ async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, decimalPoints = 0, errorLabel = 'Unable to mint collection'): Promise<UniqueFTCollection> {
+ collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object
+ if(collectionOptions.tokenPropertyPermissions) throw Error('Fungible collections has no tokenPropertyPermissions');
+ collectionOptions.mode = {fungible: decimalPoints};
+ for (const key of ['name', 'description', 'tokenPrefix']) {
+ if (typeof collectionOptions[key as 'name' | 'description' | 'tokenPrefix'] === 'string') collectionOptions[key as 'name' | 'description' | 'tokenPrefix'] = this.helper.util.str2vec(collectionOptions[key as 'name' | 'description' | 'tokenPrefix'] as string);
+ }
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createCollectionEx', [collectionOptions],
+ true, errorLabel,
+ );
+ return this.getCollectionObject(this.helper.util.extractCollectionIdFromCreationResult(creationResult, errorLabel));
+ }
+
+ /**
+ * Mint tokens
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param owner address owner of new tokens
+ * @param amount amount of tokens to be meanted
+ * @param label
+ * @example mintTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq"}, 1000n);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async mintTokens(signer: TSigner, collectionId: number, owner: ICrossAccountId | string, amount: bigint, label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createItem', [collectionId, (typeof owner === 'string') ? {Substrate: owner} : owner, {
+ fungible: {
+ value: amount,
+ },
+ }],
+ true, `Unable to mint fungible tokens for ${label}`,
+ );
+ return this.helper.util.findCollectionInEvents(creationResult.result.events, collectionId, 'common', 'ItemCreated', label);
+ }
+
+ /**
+ * Mint multiple Fungible tokens with one owner
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param owner tokens owner
+ * @param tokens array of tokens with properties and pieces
+ * @param label
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {value: bigint}[], label?: string): Promise<boolean> {
+ if(typeof label === 'undefined') label = `collection #${collectionId}`;
+ const rawTokens = [];
+ for (const token of tokens) {
+ const raw = {Fungible: {Value: token.value}};
+ rawTokens.push(raw);
+ }
+ const creationResult = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.createMultipleItems', [collectionId, owner, rawTokens],
+ true, `Unable to mint RFT tokens for ${label}`,
+ );
+ return this.helper.util.findCollectionInEvents(creationResult.result.events, collectionId, 'common', 'ItemCreated', label);
+ }
+
+ /**
+ * Get the top 10 owners with the largest balance for the Fungible collection
+ * @param collectionId ID of collection
+ * @example getTop10Owners(10);
+ * @returns array of ```ICrossAccountId```
+ */
+ async getTop10Owners(collectionId: number): Promise<ICrossAccountId[]> {
+ return (await this.helper.callRpc('api.rpc.unique.tokenOwners', [collectionId, 0])).toJSON().map(crossAccountIdFromLower);
+ }
+
+ /**
+ * Get account balance
+ * @param collectionId ID of collection
+ * @param addressObj address of owner
+ * @example getBalance(10, {Substrate: "5GHoZe9c73RYbVzq..."})
+ * @returns amount of fungible tokens owned by address
+ */
+ async getBalance(collectionId: number, addressObj: ICrossAccountId): Promise<bigint> {
+ return (await this.helper.callRpc('api.rpc.unique.balance', [collectionId, addressObj, 0])).toBigInt();
+ }
+
+ /**
+ * Transfer tokens to address
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param toAddressObj address recepient
+ * @param amount amount of tokens to be sent
+ * @example transfer(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transfer(signer: TSigner, collectionId: number, toAddressObj: ICrossAccountId, amount: bigint) {
+ return await super.transferToken(signer, collectionId, 0, toAddressObj, amount);
+ }
+
+ /**
+ * Transfer some tokens on behalf of the owner.
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param fromAddressObj address on behalf of which tokens will be sent
+ * @param toAddressObj address where token to be sent
+ * @param amount number of tokens to be sent
+ * @example transferFrom(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, {Substrate: "5DfhbVfww7ThF8q6f3ij..."}, 10000n);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transferFrom(signer: TSigner, collectionId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount: bigint) {
+ return await super.transferTokenFrom(signer, collectionId, 0, fromAddressObj, toAddressObj, amount);
+ }
+
+ /**
+ * Destroy some amount of tokens
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param amount amount of tokens to be destroyed
+ * @param label
+ * @example burnTokens(aliceKeyring, 10, 1000n);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async burnTokens(signer: IKeyringPair, collectionId: number, amount=100n, label?: string): Promise<boolean> {
+ return (await super.burnToken(signer, collectionId, 0, label, amount)).success;
+ }
+
+ /**
+ * Burn some tokens on behalf of the owner.
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param fromAddressObj address on behalf of which tokens will be burnt
+ * @param amount amount of tokens to be burnt
+ * @param label
+ * @example burnTokensFrom(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async burnTokensFrom(signer: IKeyringPair, collectionId: number, fromAddressObj: ICrossAccountId, amount=100n, label?: string): Promise<boolean> {
+ return await super.burnTokenFrom(signer, collectionId, fromAddressObj, 0, label, amount);
+ }
+
+ /**
+ * Get total collection supply
+ * @param collectionId
+ * @returns
+ */
+ async getTotalPieces(collectionId: number): Promise<bigint> {
+ return (await this.helper.callRpc('api.rpc.unique.totalPieces', [collectionId, 0])).unwrap().toBigInt();
+ }
+
+ /**
+ * Set, change, or remove approved address to transfer tokens.
+ *
+ * @param signer keyring of signer
+ * @param collectionId ID of collection
+ * @param toAddressObj address to be approved
+ * @param amount amount of tokens to be approved
+ * @param label
+ * @example approveTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n)
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async approveTokens(signer: IKeyringPair, collectionId: number, toAddressObj: ICrossAccountId, amount=100n, label?: string) {
+ return super.approveToken(signer, collectionId, 0, toAddressObj, label, amount);
+ }
+
+ /**
+ * Get amount of fungible tokens approved to transfer
+ * @param collectionId ID of collection
+ * @param fromAddressObj owner of tokens
+ * @param toAddressObj the address approved for the transfer of tokens on behalf of the owner
+ * @returns number of tokens approved for the transfer
+ */
+ async getApprovedTokens(collectionId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) {
+ return super.getTokenApprovedPieces(collectionId, 0, toAddressObj, fromAddressObj);
+ }
+}
+
+
+class ChainGroup extends HelperGroup {
+ /**
+ * Get system properties of a chain
+ * @example getChainProperties();
+ * @returns ss58Format, token decimals, and token symbol
+ */
+ getChainProperties(): IChainProperties {
+ const properties = (this.helper.api as any).registry.getChainProperties().toJSON();
+ return {
+ ss58Format: properties.ss58Format.toJSON(),
+ tokenDecimals: properties.tokenDecimals.toJSON(),
+ tokenSymbol: properties.tokenSymbol.toJSON(),
+ };
+ }
+
+ /**
+ * Get chain header
+ * @example getLatestBlockNumber();
+ * @returns the number of the last block
+ */
+ async getLatestBlockNumber(): Promise<number> {
+ return (await this.helper.callRpc('api.rpc.chain.getHeader')).number.toNumber();
+ }
+
+ /**
+ * Get block hash by block number
+ * @param blockNumber number of block
+ * @example getBlockHashByNumber(12345);
+ * @returns hash of a block
+ */
+ async getBlockHashByNumber(blockNumber: number): Promise<string | null> {
+ const blockHash = (await this.helper.callRpc('api.rpc.chain.getBlockHash', [blockNumber])).toJSON();
+ if(blockHash === '0x0000000000000000000000000000000000000000000000000000000000000000') return null;
+ return blockHash;
+ }
+
+ /**
+ * Get account nonce
+ * @param address substrate address
+ * @example getNonce("5GrwvaEF5zXb26Fz...");
+ * @returns number, account's nonce
+ */
+ async getNonce(address: TSubstrateAccount): Promise<number> {
+ return (await (this.helper.api as any).query.system.account(address)).nonce.toNumber();
+ }
+}
+
+
+class BalanceGroup extends HelperGroup {
+ /**
+ * Representation of the native token in the smallest unit
+ * @example getOneTokenNominal()
+ * @returns ```BigInt``` representation of the native token in the smallest unit, e.g. ```1_000_000_000_000_000_000n``` for QTZ.
+ */
+ getOneTokenNominal(): bigint {
+ const chainProperties = this.helper.chain.getChainProperties();
+ return 10n ** BigInt((chainProperties.tokenDecimals || [18])[0]);
+ }
+
+ /**
+ * Get substrate address balance
+ * @param address substrate address
+ * @example getSubstrate("5GrwvaEF5zXb26Fz...")
+ * @returns amount of tokens on address
+ */
+ async getSubstrate(address: TSubstrateAccount): Promise<bigint> {
+ return (await this.helper.callRpc('api.query.system.account', [address])).data.free.toBigInt();
+ }
+
+ /**
+ * Get ethereum address balance
+ * @param address ethereum address
+ * @example getEthereum("0x9F0583DbB855d...")
+ * @returns amount of tokens on address
+ */
+ async getEthereum(address: TEthereumAccount): Promise<bigint> {
+ return (await this.helper.callRpc('api.rpc.eth.getBalance', [address])).toBigInt();
+ }
+
+ /**
+ * Transfer tokens to substrate address
+ * @param signer keyring of signer
+ * @param address substrate address of a recepient
+ * @param amount amount of tokens to be transfered
+ * @example transferToSubstrate(aliceKeyring, "5GrwvaEF5zXb26Fz...", 100_000_000_000n);
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async transferToSubstrate(signer: TSigner, address: TSubstrateAccount, amount: bigint | string): Promise<boolean> {
+ const result = await this.helper.executeExtrinsic(signer, 'api.tx.balances.transfer', [address, amount], true, `Unable to transfer balance from ${this.helper.getSignerAddress(signer)} to ${address}`);
+
+ let transfer = {from: null, to: null, amount: 0n} as any;
+ result.result.events.forEach(({event: {data, method, section}}) => {
+ if ((section === 'balances') && (method === 'Transfer')) {
+ transfer = {
+ from: this.helper.address.normalizeSubstrate(data[0]),
+ to: this.helper.address.normalizeSubstrate(data[1]),
+ amount: BigInt(data[2]),
+ };
+ }
+ });
+ let isSuccess = this.helper.address.normalizeSubstrate(typeof signer === 'string' ? signer : signer.address) === transfer.from;
+ isSuccess = isSuccess && this.helper.address.normalizeSubstrate(address) === transfer.to;
+ isSuccess = isSuccess && BigInt(amount) === transfer.amount;
+ return isSuccess;
+ }
+}
+
+
+class AddressGroup extends HelperGroup {
+ /**
+ * Normalizes the address to the specified ss58 format, by default ```42```.
+ * @param address substrate address
+ * @param ss58Format format for address conversion, by default ```42```
+ * @example normalizeSubstrate("unjKJQJrRd238pkUZZvzDQrfKuM39zBSnQ5zjAGAGcdRhaJTx") // returns 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
+ * @returns substrate address converted to normalized (i.e., starting with 5) or specified explicitly representation
+ */
+ normalizeSubstrate(address: TSubstrateAccount, ss58Format = 42): TSubstrateAccount {
+ return this.helper.util.normalizeSubstrateAddress(address, ss58Format);
+ }
+
+ /**
+ * Get address in the connected chain format
+ * @param address substrate address
+ * @example normalizeSubstrateToChainFormat("5GrwvaEF5zXb26Fz...") // returns unjKJQJrRd238pkUZZ... for Unique Network
+ * @returns address in chain format
+ */
+ async normalizeSubstrateToChainFormat(address: TSubstrateAccount): Promise<TSubstrateAccount> {
+ const info = this.helper.chain.getChainProperties();
+ return encodeAddress(decodeAddress(address), info.ss58Format);
+ }
+
+ /**
+ * Get substrate mirror of an ethereum address
+ * @param ethAddress ethereum address
+ * @param toChainFormat false for normalized account
+ * @example ethToSubstrate('0x9F0583DbB855d...')
+ * @returns substrate mirror of a provided ethereum address
+ */
+ async ethToSubstrate(ethAddress: TEthereumAccount, toChainFormat=false): Promise<TSubstrateAccount> {
+ if(!toChainFormat) return evmToAddress(ethAddress);
+ const info = this.helper.chain.getChainProperties();
+ return evmToAddress(ethAddress, info.ss58Format);
+ }
+
+ /**
+ * Get ethereum mirror of a substrate address
+ * @param subAddress substrate account
+ * @example substrateToEth("5DnSF6RRjwteE3BrC...")
+ * @returns ethereum mirror of a provided substrate address
+ */
+ substrateToEth(subAddress: TSubstrateAccount): TEthereumAccount {
+ return nesting.toChecksumAddress('0x' + Array.from(addressToEvm(subAddress), i => i.toString(16).padStart(2, '0')).join(''));
+ }
+}
+
+
+export class UniqueHelper extends ChainHelperBase {
+ chain: ChainGroup;
+ balance: BalanceGroup;
+ address: AddressGroup;
+ collection: CollectionGroup;
+ nft: NFTGroup;
+ rft: RFTGroup;
+ ft: FTGroup;
+
+ constructor(logger?: ILogger) {
+ super(logger);
+ this.chain = new ChainGroup(this);
+ this.balance = new BalanceGroup(this);
+ this.address = new AddressGroup(this);
+ this.collection = new CollectionGroup(this);
+ this.nft = new NFTGroup(this);
+ this.rft = new RFTGroup(this);
+ this.ft = new FTGroup(this);
+ }
+}
+
+
+class UniqueCollectionBase {
+ helper: UniqueHelper;
+ collectionId: number;
+
+ constructor(collectionId: number, uniqueHelper: UniqueHelper) {
+ this.collectionId = collectionId;
+ this.helper = uniqueHelper;
+ }
+
+ async getData() {
+ return await this.helper.collection.getData(this.collectionId);
+ }
+
+ async getLastTokenId() {
+ return await this.helper.collection.getLastTokenId(this.collectionId);
+ }
+
+ async isTokenExists(tokenId: number) {
+ return await this.helper.collection.isTokenExists(this.collectionId, tokenId);
+ }
+
+ async getAdmins() {
+ return await this.helper.collection.getAdmins(this.collectionId);
+ }
+
+ async getEffectiveLimits() {
+ return await this.helper.collection.getEffectiveLimits(this.collectionId);
+ }
+
+ async setSponsor(signer: TSigner, sponsorAddress: TSubstrateAccount, label?: string) {
+ return await this.helper.collection.setSponsor(signer, this.collectionId, sponsorAddress, label);
+ }
+
+ async confirmSponsorship(signer: TSigner, label?: string) {
+ return await this.helper.collection.confirmSponsorship(signer, this.collectionId, label);
+ }
+
+ async setLimits(signer: TSigner, limits: ICollectionLimits, label?: string) {
+ return await this.helper.collection.setLimits(signer, this.collectionId, limits, label);
+ }
+
+ async changeOwner(signer: TSigner, ownerAddress: TSubstrateAccount, label?: string) {
+ return await this.helper.collection.changeOwner(signer, this.collectionId, ownerAddress, label);
+ }
+
+ async addAdmin(signer: TSigner, adminAddressObj: ICrossAccountId, label?: string) {
+ return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj, label);
+ }
+
+ async removeAdmin(signer: TSigner, adminAddressObj: ICrossAccountId, label?: string) {
+ return await this.helper.collection.removeAdmin(signer, this.collectionId, adminAddressObj, label);
+ }
+
+ async setProperties(signer: TSigner, properties: IProperty[], label?: string) {
+ return await this.helper.collection.setProperties(signer, this.collectionId, properties, label);
+ }
+
+ async deleteProperties(signer: TSigner, propertyKeys: string[], label?: string) {
+ return await this.helper.collection.deleteProperties(signer, this.collectionId, propertyKeys, label);
+ }
+
+ async getTokenNextSponsored(tokenId: number, addressObj: ICrossAccountId) {
+ return await this.helper.collection.getTokenNextSponsored(this.collectionId, tokenId, addressObj);
+ }
+
+ async setPermissions(signer: TSigner, permissions: ICollectionPermissions, label?: string) {
+ return await this.helper.collection.setPermissions(signer, this.collectionId, permissions, label);
+ }
+
+ async enableNesting(signer: TSigner, permissions: INestingPermissions, label?: string) {
+ return await this.helper.collection.enableNesting(signer, this.collectionId, permissions, label);
+ }
+
+ async disableNesting(signer: TSigner, label?: string) {
+ return await this.helper.collection.disableNesting(signer, this.collectionId, label);
+ }
+
+ async burn(signer: TSigner, label?: string) {
+ return await this.helper.collection.burn(signer, this.collectionId, label);
+ }
+}
+
+
+class UniqueNFTCollection extends UniqueCollectionBase {
+ getTokenObject(tokenId: number) {
+ return new UniqueNFTToken(tokenId, this);
+ }
+
+ async getTokensByAddress(addressObj: ICrossAccountId) {
+ return await this.helper.nft.getTokensByAddress(this.collectionId, addressObj);
+ }
+
+ async getToken(tokenId: number, blockHashAt?: string) {
+ return await this.helper.nft.getToken(this.collectionId, tokenId, blockHashAt);
+ }
+
+ async getTokenOwner(tokenId: number, blockHashAt?: string) {
+ return await this.helper.nft.getTokenOwner(this.collectionId, tokenId, blockHashAt);
+ }
+
+ async getTokenTopmostOwner(tokenId: number, blockHashAt?: string) {
+ return await this.helper.nft.getTokenTopmostOwner(this.collectionId, tokenId, blockHashAt);
+ }
+
+ async getTokenChildren(tokenId: number, blockHashAt?: string) {
+ return await this.helper.nft.getTokenChildren(this.collectionId, tokenId, blockHashAt);
+ }
+
+ async transferToken(signer: TSigner, tokenId: number, addressObj: ICrossAccountId) {
+ return await this.helper.nft.transferToken(signer, this.collectionId, tokenId, addressObj);
+ }
+
+ async transferTokenFrom(signer: TSigner, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) {
+ return await this.helper.nft.transferTokenFrom(signer, this.collectionId, tokenId, fromAddressObj, toAddressObj);
+ }
+
+ async approveToken(signer: TSigner, tokenId: number, toAddressObj: ICrossAccountId, label?: string) {
+ return await this.helper.nft.approveToken(signer, this.collectionId, tokenId, toAddressObj, label);
+ }
+
+ async isTokenApproved(tokenId: number, toAddressObj: ICrossAccountId) {
+ return await this.helper.nft.isTokenApproved(this.collectionId, tokenId, toAddressObj);
+ }
+
+ async mintToken(signer: TSigner, owner: ICrossAccountId, properties?: IProperty[], label?: string) {
+ return await this.helper.nft.mintToken(signer, {collectionId: this.collectionId, owner, properties}, label);
+ }
+
+ async mintMultipleTokens(signer: TSigner, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[], label?: string) {
+ return await this.helper.nft.mintMultipleTokens(signer, this.collectionId, tokens, label);
+ }
+
+ async burnToken(signer: TSigner, tokenId: number, label?: string) {
+ return await this.helper.nft.burnToken(signer, this.collectionId, tokenId, label);
+ }
+
+ async setTokenProperties(signer: TSigner, tokenId: number, properties: IProperty[], label?: string) {
+ return await this.helper.nft.setTokenProperties(signer, this.collectionId, tokenId, properties, label);
+ }
+
+ async deleteTokenProperties(signer: TSigner, tokenId: number, propertyKeys: string[], label?: string) {
+ return await this.helper.nft.deleteTokenProperties(signer, this.collectionId, tokenId, propertyKeys, label);
+ }
+
+ async setTokenPropertyPermissions(signer: TSigner, permissions: ITokenPropertyPermission[], label?: string) {
+ return await this.helper.nft.setTokenPropertyPermissions(signer, this.collectionId, permissions, label);
+ }
+
+ async nestToken(signer: TSigner, tokenId: number, toTokenObj: IToken, label?: string) {
+ return await this.helper.nft.nestToken(signer, {collectionId: this.collectionId, tokenId}, toTokenObj, label);
+ }
+
+ async unnestToken(signer: TSigner, tokenId: number, fromTokenObj: IToken, toAddressObj: ICrossAccountId, label?: string) {
+ return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj, label);
+ }
+}
+
+
+class UniqueRFTCollection extends UniqueCollectionBase {
+ getTokenObject(tokenId: number) {
+ return new UniqueRFTToken(tokenId, this);
+ }
+
+ async getTokensByAddress(addressObj: ICrossAccountId) {
+ return await this.helper.rft.getTokensByAddress(this.collectionId, addressObj);
+ }
+
+ async getTop10TokenOwners(tokenId: number) {
+ return await this.helper.rft.getTokenTop10Owners(this.collectionId, tokenId);
+ }
+
+ async getTokenBalance(tokenId: number, addressObj: ICrossAccountId) {
+ return await this.helper.rft.getTokenBalance(this.collectionId, tokenId, addressObj);
+ }
+
+ async getTokenTotalPieces(tokenId: number) {
+ return await this.helper.rft.getTokenTotalPieces(this.collectionId, tokenId);
+ }
+
+ async transferToken(signer: TSigner, tokenId: number, addressObj: ICrossAccountId, amount=100n) {
+ return await this.helper.rft.transferToken(signer, this.collectionId, tokenId, addressObj, amount);
+ }
+
+ async transferTokenFrom(signer: TSigner, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=100n) {
+ return await this.helper.rft.transferTokenFrom(signer, this.collectionId, tokenId, fromAddressObj, toAddressObj, amount);
+ }
+
+ async approveToken(signer: TSigner, tokenId: number, toAddressObj: ICrossAccountId, amount=100n, label?: string) {
+ return await this.helper.rft.approveToken(signer, this.collectionId, tokenId, toAddressObj, label, amount);
+ }
+
+ async getTokenApprovedPieces(tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) {
+ return await this.helper.rft.getTokenApprovedPieces(this.collectionId, tokenId, toAddressObj, fromAddressObj);
+ }
+
+ async repartitionToken(signer: TSigner, tokenId: number, amount: bigint, label?: string) {
+ return await this.helper.rft.repartitionToken(signer, this.collectionId, tokenId, amount, label);
+ }
+
+ async mintToken(signer: TSigner, owner: ICrossAccountId, pieces=100n, properties?: IProperty[], label?: string) {
+ return await this.helper.rft.mintToken(signer, {collectionId: this.collectionId, owner, pieces, properties}, label);
+ }
+
+ async mintMultipleTokens(signer: TSigner, tokens: {owner: ICrossAccountId, pieces: bigint, properties?: IProperty[]}[], label?: string) {
+ return await this.helper.rft.mintMultipleTokens(signer, this.collectionId, tokens, label);
+ }
+
+ async burnToken(signer: TSigner, tokenId: number, amount=100n, label?: string) {
+ return await this.helper.rft.burnToken(signer, this.collectionId, tokenId, label, amount);
+ }
+
+ async setTokenProperties(signer: TSigner, tokenId: number, properties: IProperty[], label?: string) {
+ return await this.helper.rft.setTokenProperties(signer, this.collectionId, tokenId, properties, label);
+ }
+
+ async deleteTokenProperties(signer: TSigner, tokenId: number, propertyKeys: string[], label?: string) {
+ return await this.helper.rft.deleteTokenProperties(signer, this.collectionId, tokenId, propertyKeys, label);
+ }
+
+ async setTokenPropertyPermissions(signer: TSigner, permissions: ITokenPropertyPermission[], label?: string) {
+ return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions, label);
+ }
+}
+
+
+class UniqueFTCollection extends UniqueCollectionBase {
+ async mint(signer: TSigner, owner: ICrossAccountId, amount: bigint, label?: string) {
+ return await this.helper.ft.mintTokens(signer, this.collectionId, owner, amount, label);
+ }
+
+ async mintWithOneOwner(signer: TSigner, owner: ICrossAccountId, tokens: {value: bigint}[], label?: string) {
+ return await this.helper.ft.mintMultipleTokensWithOneOwner(signer, this.collectionId, owner, tokens, label);
+ }
+
+ async getBalance(addressObj: ICrossAccountId) {
+ return await this.helper.ft.getBalance(this.collectionId, addressObj);
+ }
+
+ async getTop10Owners() {
+ return await this.helper.ft.getTop10Owners(this.collectionId);
+ }
+
+ async transfer(signer: TSigner, toAddressObj: ICrossAccountId, amount: bigint) {
+ return await this.helper.ft.transfer(signer, this.collectionId, toAddressObj, amount);
+ }
+
+ async transferFrom(signer: TSigner, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount: bigint) {
+ return await this.helper.ft.transferFrom(signer, this.collectionId, fromAddressObj, toAddressObj, amount);
+ }
+
+ async burnTokens(signer: TSigner, amount: bigint, label?: string) {
+ return await this.helper.ft.burnTokens(signer, this.collectionId, amount, label);
+ }
+
+ async burnTokensFrom(signer: TSigner, fromAddressObj: ICrossAccountId, amount: bigint, label?: string) {
+ return await this.helper.ft.burnTokensFrom(signer, this.collectionId, fromAddressObj, amount, label);
+ }
+
+ async getTotalPieces() {
+ return await this.helper.ft.getTotalPieces(this.collectionId);
+ }
+
+ async approveTokens(signer: TSigner, toAddressObj: ICrossAccountId, amount=100n, label?: string) {
+ return await this.helper.ft.approveTokens(signer, this.collectionId, toAddressObj, amount, label);
+ }
+
+ async getApprovedTokens(fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) {
+ return await this.helper.ft.getApprovedTokens(this.collectionId, fromAddressObj, toAddressObj);
+ }
+}
+
+
+class UniqueTokenBase implements IToken {
+ collection: UniqueNFTCollection | UniqueRFTCollection;
+ collectionId: number;
+ tokenId: number;
+
+ constructor(tokenId: number, collection: UniqueNFTCollection | UniqueRFTCollection) {
+ this.collection = collection;
+ this.collectionId = collection.collectionId;
+ this.tokenId = tokenId;
+ }
+
+ async getNextSponsored(addressObj: ICrossAccountId) {
+ return await this.collection.getTokenNextSponsored(this.tokenId, addressObj);
+ }
+
+ async setProperties(signer: TSigner, properties: IProperty[], label?: string) {
+ return await this.collection.setTokenProperties(signer, this.tokenId, properties, label);
+ }
+
+ async deleteProperties(signer: TSigner, propertyKeys: string[], label?: string) {
+ return await this.collection.deleteTokenProperties(signer, this.tokenId, propertyKeys, label);
+ }
+}
+
+
+class UniqueNFTToken extends UniqueTokenBase {
+ collection: UniqueNFTCollection;
+
+ constructor(tokenId: number, collection: UniqueNFTCollection) {
+ super(tokenId, collection);
+ this.collection = collection;
+ }
+
+ async getData(blockHashAt?: string) {
+ return await this.collection.getToken(this.tokenId, blockHashAt);
+ }
+
+ async getOwner(blockHashAt?: string) {
+ return await this.collection.getTokenOwner(this.tokenId, blockHashAt);
+ }
+
+ async getTopmostOwner(blockHashAt?: string) {
+ return await this.collection.getTokenTopmostOwner(this.tokenId, blockHashAt);
+ }
+
+ async getChildren(blockHashAt?: string) {
+ return await this.collection.getTokenChildren(this.tokenId, blockHashAt);
+ }
+
+ async nest(signer: TSigner, toTokenObj: IToken, label?: string) {
+ return await this.collection.nestToken(signer, this.tokenId, toTokenObj, label);
+ }
+
+ async unnest(signer: TSigner, fromTokenObj: IToken, toAddressObj: ICrossAccountId, label?: string) {
+ return await this.collection.unnestToken(signer, this.tokenId, fromTokenObj, toAddressObj, label);
+ }
+
+ async transfer(signer: TSigner, addressObj: ICrossAccountId) {
+ return await this.collection.transferToken(signer, this.tokenId, addressObj);
+ }
+
+ async transferFrom(signer: TSigner, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) {
+ return await this.collection.transferTokenFrom(signer, this.tokenId, fromAddressObj, toAddressObj);
+ }
+
+ async approve(signer: TSigner, toAddressObj: ICrossAccountId, label?: string) {
+ return await this.collection.approveToken(signer, this.tokenId, toAddressObj, label);
+ }
+
+ async isApproved(toAddressObj: ICrossAccountId) {
+ return await this.collection.isTokenApproved(this.tokenId, toAddressObj);
+ }
+
+ async burn(signer: TSigner, label?: string) {
+ return await this.collection.burnToken(signer, this.tokenId, label);
+ }
+}
+
+class UniqueRFTToken extends UniqueTokenBase {
+ collection: UniqueRFTCollection;
+
+ constructor(tokenId: number, collection: UniqueRFTCollection) {
+ super(tokenId, collection);
+ this.collection = collection;
+ }
+
+ async getTop10Owners() {
+ return await this.collection.getTop10TokenOwners(this.tokenId);
+ }
+
+ async getBalance(addressObj: ICrossAccountId) {
+ return await this.collection.getTokenBalance(this.tokenId, addressObj);
+ }
+
+ async getTotalPieces() {
+ return await this.collection.getTokenTotalPieces(this.tokenId);
+ }
+
+ async transfer(signer: TSigner, addressObj: ICrossAccountId, amount=100n) {
+ return await this.collection.transferToken(signer, this.tokenId, addressObj, amount);
+ }
+
+ async transferFrom(signer: TSigner, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=100n) {
+ return await this.collection.transferTokenFrom(signer, this.tokenId, fromAddressObj, toAddressObj, amount);
+ }
+
+ async approve(signer: TSigner, toAddressObj: ICrossAccountId, amount=100n, label?: string) {
+ return await this.collection.approveToken(signer, this.tokenId, toAddressObj, amount, label);
+ }
+
+ async getApprovedPieces(fromAddressObj: ICrossAccountId, toAccountObj: ICrossAccountId) {
+ return await this.collection.getTokenApprovedPieces(this.tokenId, fromAddressObj, toAccountObj);
+ }
+
+ async repartition(signer: TSigner, amount: bigint, label?: string) {
+ return await this.collection.repartitionToken(signer, this.tokenId, amount, label);
+ }
+
+ async burn(signer: TSigner, amount=100n, label?: string) {
+ return await this.collection.burnToken(signer, this.tokenId, amount, label);
+ }
+}
\ No newline at end of file
tests/yarn.lockdiffbeforeafterboth--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -963,6 +963,13 @@
dependencies:
"@types/chai" "*"
+"@types/chai-like@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@types/chai-like/-/chai-like-1.1.1.tgz#c454039b0a2f92664fb5b7b7a2a66c3358783ae7"
+ integrity sha512-s46EZsupBuVhLn66DbRee5B0SELLmL4nFXVrBiV29BxLGm9Sh7Bful623j3AfiQRu2zAP4cnlZ3ETWB3eWc4bA==
+ dependencies:
+ "@types/chai" "*"
+
"@types/chai@*", "@types/chai@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04"
@@ -1545,6 +1552,11 @@
dependencies:
check-error "^1.0.2"
+chai-like@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/chai-like/-/chai-like-1.1.1.tgz#8c558a414c34514e814d497c772547ceb7958f64"
+ integrity sha512-VKa9z/SnhXhkT1zIjtPACFWSoWsqVoaz1Vg+ecrKo5DCKVlgL30F/pEyEvXPBOVwCgLZcWUleCM/C1okaKdTTA==
+
chai@^4.3.6:
version "4.3.6"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c"