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

difftreelog

Merge branch 'develop' into CI-41-forckless-update-parachain-relay-nodata

Alex2022-08-12parents: #b1ec0e6 #e4268af.patch.diff
in: master

155 files changed

modified.docker/Dockerfile-parachaindiffbeforeafterboth
9ENV PATH="/cargo-home/bin:$PATH"9ENV PATH="/cargo-home/bin:$PATH"
1010
1111
12
13RUN apt-get update && \12RUN apt-get update && \
14 apt-get install -y curl cmake pkg-config libssl-dev git clang && \13 apt-get install -y curl cmake pkg-config libssl-dev git clang && \
15 apt-get clean && \14 apt-get clean && \
24 rustup show23 rustup show
25RUN rustup target add wasm32-unknown-unknown --toolchain $RUST_TOOLCHAIN24RUN rustup target add wasm32-unknown-unknown --toolchain $RUST_TOOLCHAIN
2625
27
28RUN mkdir /unique_parachain26RUN mkdir /unique_parachain
29WORKDIR /unique_parachain27WORKDIR /unique_parachain
3028
29
31# ===== BUILD ======30# ===== BUILD ======
32FROM rust-builder as builder-unique31FROM rust-builder as builder-unique
3332
4140
42RUN git clone $REPO_URL -b $BRANCH && \41RUN git clone $REPO_URL -b $BRANCH && \
43 cargo build --features=$FEATURE --$PROFILE42 cargo build --features=$FEATURE --$PROFILE
43
4444
45# ===== BUILD POLKADOT =====45# ===== BUILD POLKADOT =====
46FROM rust-builder as builder-polkadot46FROM rust-builder as builder-polkadot
60FROM ubuntu:20.0460FROM ubuntu:20.04
6161
62RUN apt-get -y update && \62RUN apt-get -y update && \
63 apt-get -y upgrade && \
64 apt-get -y install curl git && \63 apt-get -y install curl git && \
65 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \64 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \
66 export NVM_DIR="$HOME/.nvm" && \65 export NVM_DIR="$HOME/.nvm" && \
added.docker/docker-compose-master.yamldiffbeforeafterboth

no changes

added.docker/docker-compose.tmp-master.j2diffbeforeafterboth

no changes

modified.gitattributesdiffbeforeafterboth
1* text=auto1* text=auto
2*.sh text eol=lf2*.sh text eol=lf
33*.ts linguist-detectable=false
added.github/workflows/build-test-master.ymldiffbeforeafterboth

no changes

modified.github/workflows/node_build_test.ymldiffbeforeafterboth
32 matrix:32 matrix:
33 include:33 include:
34 - network: "Opal"34 - network: "Opal"
35 features: "--features=opal-runtime"35 features: " "
36 - network: "Quartz"36 - network: "Quartz"
37 features: "--features=quartz-runtime"37 features: "--features=quartz-runtime"
38 - network: "Unique"38 - network: "Unique"
57 if: github.event.pull_request.draft == true57 if: github.event.pull_request.draft == true
58 run: exit 158 run: exit 1
5959
60 # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it60 - name: Clean Workspace
61 uses: AutoModality/action-clean@v1.1.0
62
63 # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
61 - uses: actions/checkout@v364 - uses: actions/checkout@v3
62 with:65 with:
63 ref: ${{ github.head_ref }} #Checking out head commit66 ref: ${{ github.head_ref }} #Checking out head commit
70 with:73 with:
71 template: .docker/docker-compose.tmp.j274 template: .docker/docker-compose.tmp.j2
72 output_file: .docker/docker-compose.${{ matrix.network }}.yml75 output_file: .docker/docker-compose.${{ matrix.network }}.yml
73 variables: |76 variables: |
74 REPO_URL=${{ github.server_url }}/${{ github.repository }}.git77 REPO_URL=${{ github.server_url }}/${{ github.repository }}.git
75 RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}78 RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
76 POLKADOT_BUILD_BRANCH=${{ env.POLKADOT_BUILD_BRANCH }}79 POLKADOT_BUILD_BRANCH=${{ env.POLKADOT_BUILD_BRANCH }}
77 FEATURE='${{ matrix.features }}'80 FEATURE=${{ matrix.features }}
78 BRANCH=${{ github.head_ref }}81 BRANCH=${{ github.head_ref }}
7982
80 - name: Show build configuration83 - name: Show build configuration
81 run: cat .docker/docker-compose.${{ matrix.network }}.yml84 run: cat .docker/docker-compose.${{ matrix.network }}.yml
100103
101 - name: Test Report104 - name: Test Report
102 uses: phoenix-actions/test-reporting@v8105 uses: phoenix-actions/test-reporting@v8
106 id: test-report
103 if: success() || failure() # run this step even if previous step failed107 if: success() || failure() # run this step even if previous step failed
104 with:108 with:
105 name: Tests ${{ matrix.network }} # Name of the check run which will be created109 name: Tests ${{ matrix.network }} # Name of the check run which will be created
modifiedCargo.lockdiffbeforeafterboth
5291 "cumulus-primitives-timestamp",5291 "cumulus-primitives-timestamp",
5292 "cumulus-primitives-utility",5292 "cumulus-primitives-utility",
5293 "derivative",5293 "derivative",
5294 "evm-coder",
5294 "fp-evm-mapping",5295 "fp-evm-mapping",
5295 "fp-rpc",5296 "fp-rpc",
5296 "fp-self-contained",5297 "fp-self-contained",
5352 "sp-transaction-pool",5353 "sp-transaction-pool",
5353 "sp-version",5354 "sp-version",
5354 "substrate-wasm-builder",5355 "substrate-wasm-builder",
5355 "unique-runtime-common",5356 "up-common",
5356 "up-data-structs",5357 "up-data-structs",
5357 "up-rpc",5358 "up-rpc",
5359 "up-sponsorship",
5358 "xcm",5360 "xcm",
5359 "xcm-builder",5361 "xcm-builder",
5360 "xcm-executor",5362 "xcm-executor",
8605 "cumulus-primitives-timestamp",8607 "cumulus-primitives-timestamp",
8606 "cumulus-primitives-utility",8608 "cumulus-primitives-utility",
8607 "derivative",8609 "derivative",
8610 "evm-coder",
8608 "fp-evm-mapping",8611 "fp-evm-mapping",
8609 "fp-rpc",8612 "fp-rpc",
8610 "fp-self-contained",8613 "fp-self-contained",
8666 "sp-transaction-pool",8669 "sp-transaction-pool",
8667 "sp-version",8670 "sp-version",
8668 "substrate-wasm-builder",8671 "substrate-wasm-builder",
8669 "unique-runtime-common",8672 "up-common",
8670 "up-data-structs",8673 "up-data-structs",
8671 "up-rpc",8674 "up-rpc",
8675 "up-sponsorship",
8672 "xcm",8676 "xcm",
8673 "xcm-builder",8677 "xcm-builder",
8674 "xcm-executor",8678 "xcm-executor",
11881name = "tests"11885name = "tests"
11882version = "0.1.0"11886version = "0.1.0"
11883dependencies = [11887dependencies = [
11888 "evm-coder",
11884 "fp-evm-mapping",11889 "fp-evm-mapping",
11885 "frame-support",11890 "frame-support",
11886 "frame-system",11891 "frame-system",
11902 "sp-io",11907 "sp-io",
11903 "sp-runtime",11908 "sp-runtime",
11904 "sp-std",11909 "sp-std",
11905 "unique-runtime-common",
11906 "up-data-structs",11910 "up-data-structs",
11911 "up-sponsorship",
11907]11912]
1190811913
11909[[package]]11914[[package]]
12387 "sp-core",12392 "sp-core",
12388 "sp-rpc",12393 "sp-rpc",
12389 "sp-runtime",12394 "sp-runtime",
12390 "unique-runtime-common",
12391 "up-data-structs",12395 "up-data-structs",
12392 "up-rpc",12396 "up-rpc",
12393]12397]
12541 "try-runtime-cli",12545 "try-runtime-cli",
12542 "unique-rpc",12546 "unique-rpc",
12543 "unique-runtime",12547 "unique-runtime",
12544 "unique-runtime-common",12548 "up-common",
12545 "up-data-structs",12549 "up-data-structs",
12546 "up-rpc",12550 "up-rpc",
12547]12551]
12590 "substrate-frame-rpc-system",12594 "substrate-frame-rpc-system",
12591 "tokio 0.2.25",12595 "tokio 0.2.25",
12592 "uc-rpc",12596 "uc-rpc",
12593 "unique-runtime-common",12597 "up-common",
12594 "up-data-structs",12598 "up-data-structs",
12595 "up-rpc",12599 "up-rpc",
12596]12600]
12608 "cumulus-primitives-timestamp",12612 "cumulus-primitives-timestamp",
12609 "cumulus-primitives-utility",12613 "cumulus-primitives-utility",
12610 "derivative",12614 "derivative",
12615 "evm-coder",
12611 "fp-evm-mapping",12616 "fp-evm-mapping",
12612 "fp-rpc",12617 "fp-rpc",
12613 "fp-self-contained",12618 "fp-self-contained",
12669 "sp-transaction-pool",12674 "sp-transaction-pool",
12670 "sp-version",12675 "sp-version",
12671 "substrate-wasm-builder",12676 "substrate-wasm-builder",
12672 "unique-runtime-common",12677 "up-common",
12673 "up-data-structs",12678 "up-data-structs",
12674 "up-rpc",12679 "up-rpc",
12680 "up-sponsorship",
12675 "xcm",12681 "xcm",
12676 "xcm-builder",12682 "xcm-builder",
12677 "xcm-executor",12683 "xcm-executor",
12678]12684]
12679
12680[[package]]
12681name = "unique-runtime-common"
12682version = "0.9.24"
12683dependencies = [
12684 "evm-coder",
12685 "fp-rpc",
12686 "frame-support",
12687 "frame-system",
12688 "pallet-common",
12689 "pallet-evm",
12690 "pallet-fungible",
12691 "pallet-nonfungible",
12692 "pallet-refungible",
12693 "pallet-unique",
12694 "pallet-unique-scheduler",
12695 "parity-scale-codec 3.1.5",
12696 "rmrk-rpc",
12697 "scale-info",
12698 "sp-consensus-aura",
12699 "sp-core",
12700 "sp-runtime",
12701 "sp-std",
12702 "up-data-structs",
12703 "up-sponsorship",
12704]
1270512685
12706[[package]]12686[[package]]
12707name = "universal-hash"12687name = "universal-hash"
12731source = "registry+https://github.com/rust-lang/crates.io-index"12711source = "registry+https://github.com/rust-lang/crates.io-index"
12732checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"12712checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
12713
12714[[package]]
12715name = "up-common"
12716version = "0.9.24"
12717dependencies = [
12718 "fp-rpc",
12719 "frame-support",
12720 "pallet-evm",
12721 "sp-consensus-aura",
12722 "sp-core",
12723 "sp-runtime",
12724 "sp-std",
12725]
1273312726
12734[[package]]12727[[package]]
12735name = "up-data-structs"12728name = "up-data-structs"
modifiedREADME.mddiffbeforeafterboth
2323
24Wider Unique Ecosystem (most of it was developed during Hackusama):24Wider Unique Ecosystem (most of it was developed during Hackusama):
2525
26- [SubstraPunks Game hosted on IPFS](https://github.com/usetech-llc/substrapunks)26- [SubstraPunks Game hosted on IPFS](https://github.com/UniqueNetwork/substrapunks)
27- [Unique Wallet and UI](https://uniqueapps.usetech.com/#/nft)27- [Unique Wallet and UI](https://wallet.unique.network)
28- [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)28- [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)
2929
30Please see our [walk-through instructions](doc/hackusama_walk_through.md) to try everything out!30Please see our [walk-through instructions](doc/hackusama_walk_through.md) to try everything out!
modifiedclient/rpc/Cargo.tomldiffbeforeafterboth
5edition = "2021"5edition = "2021"
66
7[dependencies]7[dependencies]
8unique-runtime-common = { default-features = false, path = "../../runtime/common" }
9pallet-common = { default-features = false, path = '../../pallets/common' }8pallet-common = { default-features = false, path = '../../pallets/common' }
10up-data-structs = { default-features = false, path = '../../primitives/data-structs' }9up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
11up-rpc = { path = "../../primitives/rpc" }10up-rpc = { path = "../../primitives/rpc" }
modifiednode/cli/Cargo.tomldiffbeforeafterboth
253################################################################################253################################################################################
254# Local dependencies254# Local dependencies
255255
256[dependencies.unique-runtime-common]256[dependencies.up-common]
257default-features = false
258path = "../../runtime/common"257path = "../../primitives/common"
259258
260[dependencies.unique-runtime]259[dependencies.unique-runtime]
261path = '../../runtime/unique'260path = '../../runtime/unique'
modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
23use serde::{Deserialize, Serialize};23use serde::{Deserialize, Serialize};
24use serde_json::map::Map;24use serde_json::map::Map;
2525
26use unique_runtime_common::types::*;26use up_common::types::opaque::*;
2727
28#[cfg(feature = "unique-runtime")]28#[cfg(feature = "unique-runtime")]
29pub use unique_runtime as default_runtime;29pub use unique_runtime as default_runtime;
modifiednode/cli/src/command.rsdiffbeforeafterboth
64use sp_runtime::traits::{AccountIdConversion, Block as BlockT};64use sp_runtime::traits::{AccountIdConversion, Block as BlockT};
65use std::{io::Write, net::SocketAddr, time::Duration};65use std::{io::Write, net::SocketAddr, time::Duration};
6666
67use unique_runtime_common::types::Block;67use up_common::types::opaque::Block;
6868
69macro_rules! no_runtime_err {69macro_rules! no_runtime_err {
70 ($chain_name:expr) => {70 ($chain_name:expr) => {
modifiednode/cli/src/service.rsdiffbeforeafterboth
63use fc_rpc_core::types::FilterPool;63use fc_rpc_core::types::FilterPool;
64use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};64use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};
6565
66use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};66use up_common::types::opaque::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};
6767
68// RMRK68// RMRK
69use up_data_structs::{69use up_data_structs::{
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
5050
51pallet-common = { default-features = false, path = "../../pallets/common" }51pallet-common = { default-features = false, path = "../../pallets/common" }
52unique-runtime-common = { default-features = false, path = "../../runtime/common" }52up-common = { path = "../../primitives/common" }
53pallet-unique = { path = "../../pallets/unique" }53pallet-unique = { path = "../../pallets/unique" }
54uc-rpc = { path = "../../client/rpc" }54uc-rpc = { path = "../../client/rpc" }
55up-rpc = { path = "../../primitives/rpc" }55up-rpc = { path = "../../primitives/rpc" }
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
40use sc_service::TransactionPool;40use sc_service::TransactionPool;
41use std::{collections::BTreeMap, sync::Arc};41use std::{collections::BTreeMap, sync::Arc};
4242
43use unique_runtime_common::types::{43use up_common::types::opaque::{Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance};
44 Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,44
45};
46// RMRK45// RMRK
47use up_data_structs::{46use up_data_structs::{
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
25use pallet_evm_coder_substrate::dispatch_to_evm;25use pallet_evm_coder_substrate::dispatch_to_evm;
26use sp_std::vec::Vec;26use sp_std::vec::Vec;
27use up_data_structs::{27use up_data_structs::{
28 Property, SponsoringRateLimit, OwnerRestrictedSet, AccessMode, CollectionPermissions,28 AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,
29 SponsoringRateLimit,
29};30};
30use alloc::format;31use alloc::format;
3132
409 save(self)410 save(self)
410 }411 }
412
413 /// Check that account is the owner or admin of the collection
414 ///
415 /// @param user account to verify
416 /// @return "true" if account is the owner or admin
417 fn verify_owner_or_admin(&self, user: address) -> Result<bool> {
418 Ok(check_is_owner_or_admin(user, self)
419 .map(|_| true)
420 .unwrap_or(false))
421 }
422
423 /// Returns collection type
424 ///
425 /// @return `Fungible` or `NFT` or `ReFungible`
426 fn unique_collection_type(&mut self) -> Result<string> {
427 let mode = match self.collection.mode {
428 CollectionMode::Fungible(_) => "Fungible",
429 CollectionMode::NFT => "NFT",
430 CollectionMode::ReFungible => "ReFungible",
431 };
432 Ok(mode.into())
433 }
411}434}
412435
413fn check_is_owner_or_admin<T: Config>(436fn check_is_owner_or_admin<T: Config>(
463 property_key_from_bytes(b"suffix").expect(EXPECT_CONVERT_ERROR)486 property_key_from_bytes(b"suffix").expect(EXPECT_CONVERT_ERROR)
464 }487 }
488
489 /// Key "parentNft".
490 pub fn parent_nft() -> up_data_structs::PropertyKey {
491 property_key_from_bytes(b"parentNft").expect(EXPECT_CONVERT_ERROR)
492 }
465 }493 }
466494
467 /// Values.495 /// Values.
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
535535
536 /// Can't transfer tokens to ethereum zero address536 /// Can't transfer tokens to ethereum zero address
537 AddressIsZero,537 AddressIsZero,
538 /// Target collection doesn't support this operation538
539 /// The oprtation is not supported
539 UnsupportedOperation,540 UnsupportedOperation,
540541
541 /// Insufficient funds to perform an action542 /// Insufficient funds to perform an action
1111 collection: &CollectionHandle<T>,1112 collection: &CollectionHandle<T>,
1112 sender: &T::CrossAccountId,1113 sender: &T::CrossAccountId,
1113 property_permission: PropertyKeyPermission,1114 property_permission: PropertyKeyPermission,
1114 ) -> DispatchResult {1115 ) -> DispatchResult {
1116 Self::set_scoped_property_permission(
1117 collection,
1118 sender,
1119 PropertyScope::None,
1120 property_permission,
1121 )
1122 }
1123
1124 /// Set collection property permission with scope.
1125 ///
1126 /// * `collection` - Collection handler.
1127 /// * `sender` - The owner or administrator of the collection.
1128 /// * `scope` - Property scope.
1129 /// * `property_permission` - Property permission.
1130 pub fn set_scoped_property_permission(
1131 collection: &CollectionHandle<T>,
1132 sender: &T::CrossAccountId,
1133 scope: PropertyScope,
1134 property_permission: PropertyKeyPermission,
1135 ) -> DispatchResult {
1115 collection.check_is_owner_or_admin(sender)?;1136 collection.check_is_owner_or_admin(sender)?;
11161137
1117 let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);1138 let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);
11251146
1126 CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {1147 CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {
1127 let property_permission = property_permission.clone();1148 let property_permission = property_permission.clone();
1128 permissions.try_set(property_permission.key, property_permission.permission)1149 permissions.try_scoped_set(
1150 scope,
1151 property_permission.key,
1152 property_permission.permission,
1153 )
1129 })1154 })
1130 .map_err(<Error<T>>::from)?;1155 .map_err(<Error<T>>::from)?;
1147 collection: &CollectionHandle<T>,1172 collection: &CollectionHandle<T>,
1148 sender: &T::CrossAccountId,1173 sender: &T::CrossAccountId,
1149 property_permissions: Vec<PropertyKeyPermission>,1174 property_permissions: Vec<PropertyKeyPermission>,
1150 ) -> DispatchResult {1175 ) -> DispatchResult {
1176 Self::set_scoped_token_property_permissions(
1177 collection,
1178 sender,
1179 PropertyScope::None,
1180 property_permissions,
1181 )
1182 }
1183
1184 /// Set token property permission with scope.
1185 ///
1186 /// * `collection` - Collection handler.
1187 /// * `sender` - The owner or administrator of the collection.
1188 /// * `scope` - Property scope.
1189 /// * `property_permissions` - Property permissions.
1190 #[transactional]
1191 pub fn set_scoped_token_property_permissions(
1192 collection: &CollectionHandle<T>,
1193 sender: &T::CrossAccountId,
1194 scope: PropertyScope,
1195 property_permissions: Vec<PropertyKeyPermission>,
1196 ) -> DispatchResult {
1151 for prop_pemission in property_permissions {1197 for prop_pemission in property_permissions {
1152 Self::set_property_permission(collection, sender, prop_pemission)?;1198 Self::set_scoped_property_permission(collection, sender, scope, prop_pemission)?;
1153 }1199 }
11541200
1155 Ok(())1201 Ok(())
1353/// Indicates unsupported methods by returning [Error::UnsupportedOperation].1399/// Indicates unsupported methods by returning [Error::UnsupportedOperation].
1354#[macro_export]1400#[macro_export]
1355macro_rules! unsupported {1401macro_rules! unsupported {
1356 () => {1402 ($runtime:path) => {
1357 Err(<Error<T>>::UnsupportedOperation.into())1403 Err($crate::Error::<$runtime>::UnsupportedOperation.into())
1358 };1404 };
1359}1405}
13601406
1430 .saturating_add(Self::burn_recursively_breadth_raw(max_breadth))1476 .saturating_add(Self::burn_recursively_breadth_raw(max_breadth))
1431 }1477 }
1478
1479 /// The price of retrieving token owner
1480 fn token_owner() -> Weight;
1432}1481}
14331482
1434/// Weight info extension trait for refungible pallet.1483/// Weight info extension trait for refungible pallet.
1567 ///1616 ///
1568 /// * `sender` - Must be either the owner of the token or its admin.1617 /// * `sender` - Must be either the owner of the token or its admin.
1569 /// * `token_id` - The token for which the properties are being set.1618 /// * `token_id` - The token for which the properties are being set.
1570 /// * `properties` - Properties to be set.1619 /// * `property_permissions` - Property permissions to be set.
1571 /// * `budget` - Budget for setting properties.1620 /// * `budget` - Budget for setting properties.
1572 fn set_token_property_permissions(1621 fn set_token_property_permissions(
1573 &self,1622 &self,
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
104 0104 0
105 }105 }
106
107 fn token_owner() -> Weight {
108 0
109 }
106}110}
107111
108/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete112/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
31 );31 );
32}32}
33
34// Selector: 6cf113cd
35contract Collection is Dummy, ERC165 {
36 // Set collection property.
37 //
38 // @param key Property key.
39 // @param value Propery value.
40 //
41 // Selector: setCollectionProperty(string,bytes) 2f073f66
42 function setCollectionProperty(string memory key, bytes memory value)
43 public
44 {
45 require(false, stub_error);
46 key;
47 value;
48 dummy = 0;
49 }
50
51 // Delete collection property.
52 //
53 // @param key Property key.
54 //
55 // Selector: deleteCollectionProperty(string) 7b7debce
56 function deleteCollectionProperty(string memory key) public {
57 require(false, stub_error);
58 key;
59 dummy = 0;
60 }
61
62 // Get collection property.
63 //
64 // @dev Throws error if key not found.
65 //
66 // @param key Property key.
67 // @return bytes The property corresponding to the key.
68 //
69 // Selector: collectionProperty(string) cf24fd6d
70 function collectionProperty(string memory key)
71 public
72 view
73 returns (bytes memory)
74 {
75 require(false, stub_error);
76 key;
77 dummy;
78 return hex"";
79 }
80
81 // Set the sponsor of the collection.
82 //
83 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
84 //
85 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
86 //
87 // Selector: setCollectionSponsor(address) 7623402e
88 function setCollectionSponsor(address sponsor) public {
89 require(false, stub_error);
90 sponsor;
91 dummy = 0;
92 }
93
94 // Collection sponsorship confirmation.
95 //
96 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
97 //
98 // Selector: confirmCollectionSponsorship() 3c50e97a
99 function confirmCollectionSponsorship() public {
100 require(false, stub_error);
101 dummy = 0;
102 }
103
104 // Set limits for the collection.
105 // @dev Throws error if limit not found.
106 // @param limit Name of the limit. Valid names:
107 // "accountTokenOwnershipLimit",
108 // "sponsoredDataSize",
109 // "sponsoredDataRateLimit",
110 // "tokenLimit",
111 // "sponsorTransferTimeout",
112 // "sponsorApproveTimeout"
113 // @param value Value of the limit.
114 //
115 // Selector: setCollectionLimit(string,uint32) 6a3841db
116 function setCollectionLimit(string memory limit, uint32 value) public {
117 require(false, stub_error);
118 limit;
119 value;
120 dummy = 0;
121 }
122
123 // Set limits for the collection.
124 // @dev Throws error if limit not found.
125 // @param limit Name of the limit. Valid names:
126 // "ownerCanTransfer",
127 // "ownerCanDestroy",
128 // "transfersEnabled"
129 // @param value Value of the limit.
130 //
131 // Selector: setCollectionLimit(string,bool) 993b7fba
132 function setCollectionLimit(string memory limit, bool value) public {
133 require(false, stub_error);
134 limit;
135 value;
136 dummy = 0;
137 }
138
139 // Get contract address.
140 //
141 // Selector: contractAddress() f6b4dfb4
142 function contractAddress() public view returns (address) {
143 require(false, stub_error);
144 dummy;
145 return 0x0000000000000000000000000000000000000000;
146 }
147
148 // Add collection admin by substrate address.
149 // @param new_admin Substrate administrator address.
150 //
151 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
152 function addCollectionAdminSubstrate(uint256 newAdmin) public {
153 require(false, stub_error);
154 newAdmin;
155 dummy = 0;
156 }
157
158 // Remove collection admin by substrate address.
159 // @param admin Substrate administrator address.
160 //
161 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
162 function removeCollectionAdminSubstrate(uint256 admin) public {
163 require(false, stub_error);
164 admin;
165 dummy = 0;
166 }
167
168 // Add collection admin.
169 // @param new_admin Address of the added administrator.
170 //
171 // Selector: addCollectionAdmin(address) 92e462c7
172 function addCollectionAdmin(address newAdmin) public {
173 require(false, stub_error);
174 newAdmin;
175 dummy = 0;
176 }
177
178 // Remove collection admin.
179 //
180 // @param new_admin Address of the removed administrator.
181 //
182 // Selector: removeCollectionAdmin(address) fafd7b42
183 function removeCollectionAdmin(address admin) public {
184 require(false, stub_error);
185 admin;
186 dummy = 0;
187 }
188
189 // Toggle accessibility of collection nesting.
190 //
191 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
192 //
193 // Selector: setCollectionNesting(bool) 112d4586
194 function setCollectionNesting(bool enable) public {
195 require(false, stub_error);
196 enable;
197 dummy = 0;
198 }
199
200 // Toggle accessibility of collection nesting.
201 //
202 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
203 // @param collections Addresses of collections that will be available for nesting.
204 //
205 // Selector: setCollectionNesting(bool,address[]) 64872396
206 function setCollectionNesting(bool enable, address[] memory collections)
207 public
208 {
209 require(false, stub_error);
210 enable;
211 collections;
212 dummy = 0;
213 }
214
215 // Set the collection access method.
216 // @param mode Access mode
217 // 0 for Normal
218 // 1 for AllowList
219 //
220 // Selector: setCollectionAccess(uint8) 41835d4c
221 function setCollectionAccess(uint8 mode) public {
222 require(false, stub_error);
223 mode;
224 dummy = 0;
225 }
226
227 // Add the user to the allowed list.
228 //
229 // @param user Address of a trusted user.
230 //
231 // Selector: addToCollectionAllowList(address) 67844fe6
232 function addToCollectionAllowList(address user) public {
233 require(false, stub_error);
234 user;
235 dummy = 0;
236 }
237
238 // Remove the user from the allowed list.
239 //
240 // @param user Address of a removed user.
241 //
242 // Selector: removeFromCollectionAllowList(address) 85c51acb
243 function removeFromCollectionAllowList(address user) public {
244 require(false, stub_error);
245 user;
246 dummy = 0;
247 }
248
249 // Switch permission for minting.
250 //
251 // @param mode Enable if "true".
252 //
253 // Selector: setCollectionMintMode(bool) 00018e84
254 function setCollectionMintMode(bool mode) public {
255 require(false, stub_error);
256 mode;
257 dummy = 0;
258 }
259
260 // Check that account is the owner or admin of the collection
261 //
262 // @param user account to verify
263 // @return "true" if account is the owner or admin
264 //
265 // Selector: verifyOwnerOrAdmin(address) c2282493
266 function verifyOwnerOrAdmin(address user) public view returns (bool) {
267 require(false, stub_error);
268 user;
269 dummy;
270 return false;
271 }
272
273 // Returns collection type
274 //
275 // @return `Fungible` or `NFT` or `ReFungible`
276 //
277 // Selector: uniqueCollectionType() d34b55b8
278 function uniqueCollectionType() public returns (string memory) {
279 require(false, stub_error);
280 dummy = 0;
281 return "";
282 }
283}
33284
34// Selector: 79cc6790285// Selector: 79cc6790
35contract ERC20UniqueExtensions is Dummy, ERC165 {286contract ERC20UniqueExtensions is Dummy, ERC165 {
43 }294 }
44}295}
45
46// Selector: 7d9262e6
47contract Collection is Dummy, ERC165 {
48 // Set collection property.
49 //
50 // @param key Property key.
51 // @param value Propery value.
52 //
53 // Selector: setCollectionProperty(string,bytes) 2f073f66
54 function setCollectionProperty(string memory key, bytes memory value)
55 public
56 {
57 require(false, stub_error);
58 key;
59 value;
60 dummy = 0;
61 }
62
63 // Delete collection property.
64 //
65 // @param key Property key.
66 //
67 // Selector: deleteCollectionProperty(string) 7b7debce
68 function deleteCollectionProperty(string memory key) public {
69 require(false, stub_error);
70 key;
71 dummy = 0;
72 }
73
74 // Get collection property.
75 //
76 // @dev Throws error if key not found.
77 //
78 // @param key Property key.
79 // @return bytes The property corresponding to the key.
80 //
81 // Selector: collectionProperty(string) cf24fd6d
82 function collectionProperty(string memory key)
83 public
84 view
85 returns (bytes memory)
86 {
87 require(false, stub_error);
88 key;
89 dummy;
90 return hex"";
91 }
92
93 // Set the sponsor of the collection.
94 //
95 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
96 //
97 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
98 //
99 // Selector: setCollectionSponsor(address) 7623402e
100 function setCollectionSponsor(address sponsor) public {
101 require(false, stub_error);
102 sponsor;
103 dummy = 0;
104 }
105
106 // Collection sponsorship confirmation.
107 //
108 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
109 //
110 // Selector: confirmCollectionSponsorship() 3c50e97a
111 function confirmCollectionSponsorship() public {
112 require(false, stub_error);
113 dummy = 0;
114 }
115
116 // Set limits for the collection.
117 // @dev Throws error if limit not found.
118 // @param limit Name of the limit. Valid names:
119 // "accountTokenOwnershipLimit",
120 // "sponsoredDataSize",
121 // "sponsoredDataRateLimit",
122 // "tokenLimit",
123 // "sponsorTransferTimeout",
124 // "sponsorApproveTimeout"
125 // @param value Value of the limit.
126 //
127 // Selector: setCollectionLimit(string,uint32) 6a3841db
128 function setCollectionLimit(string memory limit, uint32 value) public {
129 require(false, stub_error);
130 limit;
131 value;
132 dummy = 0;
133 }
134
135 // Set limits for the collection.
136 // @dev Throws error if limit not found.
137 // @param limit Name of the limit. Valid names:
138 // "ownerCanTransfer",
139 // "ownerCanDestroy",
140 // "transfersEnabled"
141 // @param value Value of the limit.
142 //
143 // Selector: setCollectionLimit(string,bool) 993b7fba
144 function setCollectionLimit(string memory limit, bool value) public {
145 require(false, stub_error);
146 limit;
147 value;
148 dummy = 0;
149 }
150
151 // Get contract address.
152 //
153 // Selector: contractAddress() f6b4dfb4
154 function contractAddress() public view returns (address) {
155 require(false, stub_error);
156 dummy;
157 return 0x0000000000000000000000000000000000000000;
158 }
159
160 // Add collection admin by substrate address.
161 // @param new_admin Substrate administrator address.
162 //
163 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
164 function addCollectionAdminSubstrate(uint256 newAdmin) public {
165 require(false, stub_error);
166 newAdmin;
167 dummy = 0;
168 }
169
170 // Remove collection admin by substrate address.
171 // @param admin Substrate administrator address.
172 //
173 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
174 function removeCollectionAdminSubstrate(uint256 admin) public {
175 require(false, stub_error);
176 admin;
177 dummy = 0;
178 }
179
180 // Add collection admin.
181 // @param new_admin Address of the added administrator.
182 //
183 // Selector: addCollectionAdmin(address) 92e462c7
184 function addCollectionAdmin(address newAdmin) public {
185 require(false, stub_error);
186 newAdmin;
187 dummy = 0;
188 }
189
190 // Remove collection admin.
191 //
192 // @param new_admin Address of the removed administrator.
193 //
194 // Selector: removeCollectionAdmin(address) fafd7b42
195 function removeCollectionAdmin(address admin) public {
196 require(false, stub_error);
197 admin;
198 dummy = 0;
199 }
200
201 // Toggle accessibility of collection nesting.
202 //
203 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
204 //
205 // Selector: setCollectionNesting(bool) 112d4586
206 function setCollectionNesting(bool enable) public {
207 require(false, stub_error);
208 enable;
209 dummy = 0;
210 }
211
212 // Toggle accessibility of collection nesting.
213 //
214 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
215 // @param collections Addresses of collections that will be available for nesting.
216 //
217 // Selector: setCollectionNesting(bool,address[]) 64872396
218 function setCollectionNesting(bool enable, address[] memory collections)
219 public
220 {
221 require(false, stub_error);
222 enable;
223 collections;
224 dummy = 0;
225 }
226
227 // Set the collection access method.
228 // @param mode Access mode
229 // 0 for Normal
230 // 1 for AllowList
231 //
232 // Selector: setCollectionAccess(uint8) 41835d4c
233 function setCollectionAccess(uint8 mode) public {
234 require(false, stub_error);
235 mode;
236 dummy = 0;
237 }
238
239 // Add the user to the allowed list.
240 //
241 // @param user Address of a trusted user.
242 //
243 // Selector: addToCollectionAllowList(address) 67844fe6
244 function addToCollectionAllowList(address user) public {
245 require(false, stub_error);
246 user;
247 dummy = 0;
248 }
249
250 // Remove the user from the allowed list.
251 //
252 // @param user Address of a removed user.
253 //
254 // Selector: removeFromCollectionAllowList(address) 85c51acb
255 function removeFromCollectionAllowList(address user) public {
256 require(false, stub_error);
257 user;
258 dummy = 0;
259 }
260
261 // Switch permission for minting.
262 //
263 // @param mode Enable if "true".
264 //
265 // Selector: setCollectionMintMode(bool) 00018e84
266 function setCollectionMintMode(bool mode) public {
267 require(false, stub_error);
268 mode;
269 dummy = 0;
270 }
271}
272296
273// Selector: 942e8b22297// Selector: 942e8b22
274contract ERC20 is Dummy, ERC165, ERC20Events {298contract ERC20 is Dummy, ERC165, ERC20Events {
modifiedpallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth
17use super::*;17use super::*;
18use crate::{Pallet, Config, NonfungibleHandle};18use crate::{Pallet, Config, NonfungibleHandle};
1919
20use sp_std::prelude::*;20use frame_benchmarking::{benchmarks, account};
21use pallet_common::benchmarking::{create_collection_raw, property_key, property_value};21use pallet_common::{
22 bench_init,
23 benchmarking::{create_collection_raw, property_key, property_value},
24 CommonCollectionOperations,
25};
22use frame_benchmarking::{benchmarks, account};26use sp_std::prelude::*;
23use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};27use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};
24use pallet_common::bench_init;
2528
26const SEED: u32 = 1;29const SEED: u32 = 1;
2730
209 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();212 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();
210 }: {<Pallet<T>>::delete_token_properties(&collection, &owner, item, to_delete.into_iter(), &Unlimited)?}213 }: {<Pallet<T>>::delete_token_properties(&collection, &owner, item, to_delete.into_iter(), &Unlimited)?}
214
215 token_owner {
216 bench_init!{
217 owner: sub; collection: collection(owner);
218 owner: cross_from_sub;
219 };
220 let item = create_max_item(&collection, &owner, owner.clone())?;
221
222 }: {collection.token_owner(item)}
211}223}
212224
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
119 .saturating_sub(Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1))119 .saturating_sub(Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1))
120 }120 }
121
122 fn token_owner() -> Weight {
123 <SelfWeightOf<T>>::token_owner()
124 }
121}125}
122126
123fn map_create_data<T: Config>(127fn map_create_data<T: Config>(
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
784 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)784 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
785 }785 }
786
787 /// Set property permissions for the token with scope.
788 ///
789 /// Sender should be the owner or admin of token's collection.
790 pub fn set_scoped_token_property_permissions(
791 collection: &CollectionHandle<T>,
792 sender: &T::CrossAccountId,
793 scope: PropertyScope,
794 property_permissions: Vec<PropertyKeyPermission>,
795 ) -> DispatchResult {
796 <PalletCommon<T>>::set_scoped_token_property_permissions(
797 collection,
798 sender,
799 scope,
800 property_permissions,
801 )
802 }
786803
787 /// Set property permissions for the collection.804 /// Set property permissions for the collection.
788 ///805 ///
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
373 }373 }
374}374}
375
376// Selector: 6cf113cd
377contract Collection is Dummy, ERC165 {
378 // Set collection property.
379 //
380 // @param key Property key.
381 // @param value Propery value.
382 //
383 // Selector: setCollectionProperty(string,bytes) 2f073f66
384 function setCollectionProperty(string memory key, bytes memory value)
385 public
386 {
387 require(false, stub_error);
388 key;
389 value;
390 dummy = 0;
391 }
392
393 // Delete collection property.
394 //
395 // @param key Property key.
396 //
397 // Selector: deleteCollectionProperty(string) 7b7debce
398 function deleteCollectionProperty(string memory key) public {
399 require(false, stub_error);
400 key;
401 dummy = 0;
402 }
403
404 // Get collection property.
405 //
406 // @dev Throws error if key not found.
407 //
408 // @param key Property key.
409 // @return bytes The property corresponding to the key.
410 //
411 // Selector: collectionProperty(string) cf24fd6d
412 function collectionProperty(string memory key)
413 public
414 view
415 returns (bytes memory)
416 {
417 require(false, stub_error);
418 key;
419 dummy;
420 return hex"";
421 }
422
423 // Set the sponsor of the collection.
424 //
425 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
426 //
427 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
428 //
429 // Selector: setCollectionSponsor(address) 7623402e
430 function setCollectionSponsor(address sponsor) public {
431 require(false, stub_error);
432 sponsor;
433 dummy = 0;
434 }
435
436 // Collection sponsorship confirmation.
437 //
438 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
439 //
440 // Selector: confirmCollectionSponsorship() 3c50e97a
441 function confirmCollectionSponsorship() public {
442 require(false, stub_error);
443 dummy = 0;
444 }
445
446 // Set limits for the collection.
447 // @dev Throws error if limit not found.
448 // @param limit Name of the limit. Valid names:
449 // "accountTokenOwnershipLimit",
450 // "sponsoredDataSize",
451 // "sponsoredDataRateLimit",
452 // "tokenLimit",
453 // "sponsorTransferTimeout",
454 // "sponsorApproveTimeout"
455 // @param value Value of the limit.
456 //
457 // Selector: setCollectionLimit(string,uint32) 6a3841db
458 function setCollectionLimit(string memory limit, uint32 value) public {
459 require(false, stub_error);
460 limit;
461 value;
462 dummy = 0;
463 }
464
465 // Set limits for the collection.
466 // @dev Throws error if limit not found.
467 // @param limit Name of the limit. Valid names:
468 // "ownerCanTransfer",
469 // "ownerCanDestroy",
470 // "transfersEnabled"
471 // @param value Value of the limit.
472 //
473 // Selector: setCollectionLimit(string,bool) 993b7fba
474 function setCollectionLimit(string memory limit, bool value) public {
475 require(false, stub_error);
476 limit;
477 value;
478 dummy = 0;
479 }
480
481 // Get contract address.
482 //
483 // Selector: contractAddress() f6b4dfb4
484 function contractAddress() public view returns (address) {
485 require(false, stub_error);
486 dummy;
487 return 0x0000000000000000000000000000000000000000;
488 }
489
490 // Add collection admin by substrate address.
491 // @param new_admin Substrate administrator address.
492 //
493 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
494 function addCollectionAdminSubstrate(uint256 newAdmin) public {
495 require(false, stub_error);
496 newAdmin;
497 dummy = 0;
498 }
499
500 // Remove collection admin by substrate address.
501 // @param admin Substrate administrator address.
502 //
503 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
504 function removeCollectionAdminSubstrate(uint256 admin) public {
505 require(false, stub_error);
506 admin;
507 dummy = 0;
508 }
509
510 // Add collection admin.
511 // @param new_admin Address of the added administrator.
512 //
513 // Selector: addCollectionAdmin(address) 92e462c7
514 function addCollectionAdmin(address newAdmin) public {
515 require(false, stub_error);
516 newAdmin;
517 dummy = 0;
518 }
519
520 // Remove collection admin.
521 //
522 // @param new_admin Address of the removed administrator.
523 //
524 // Selector: removeCollectionAdmin(address) fafd7b42
525 function removeCollectionAdmin(address admin) public {
526 require(false, stub_error);
527 admin;
528 dummy = 0;
529 }
530
531 // Toggle accessibility of collection nesting.
532 //
533 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
534 //
535 // Selector: setCollectionNesting(bool) 112d4586
536 function setCollectionNesting(bool enable) public {
537 require(false, stub_error);
538 enable;
539 dummy = 0;
540 }
541
542 // Toggle accessibility of collection nesting.
543 //
544 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
545 // @param collections Addresses of collections that will be available for nesting.
546 //
547 // Selector: setCollectionNesting(bool,address[]) 64872396
548 function setCollectionNesting(bool enable, address[] memory collections)
549 public
550 {
551 require(false, stub_error);
552 enable;
553 collections;
554 dummy = 0;
555 }
556
557 // Set the collection access method.
558 // @param mode Access mode
559 // 0 for Normal
560 // 1 for AllowList
561 //
562 // Selector: setCollectionAccess(uint8) 41835d4c
563 function setCollectionAccess(uint8 mode) public {
564 require(false, stub_error);
565 mode;
566 dummy = 0;
567 }
568
569 // Add the user to the allowed list.
570 //
571 // @param user Address of a trusted user.
572 //
573 // Selector: addToCollectionAllowList(address) 67844fe6
574 function addToCollectionAllowList(address user) public {
575 require(false, stub_error);
576 user;
577 dummy = 0;
578 }
579
580 // Remove the user from the allowed list.
581 //
582 // @param user Address of a removed user.
583 //
584 // Selector: removeFromCollectionAllowList(address) 85c51acb
585 function removeFromCollectionAllowList(address user) public {
586 require(false, stub_error);
587 user;
588 dummy = 0;
589 }
590
591 // Switch permission for minting.
592 //
593 // @param mode Enable if "true".
594 //
595 // Selector: setCollectionMintMode(bool) 00018e84
596 function setCollectionMintMode(bool mode) public {
597 require(false, stub_error);
598 mode;
599 dummy = 0;
600 }
601
602 // Check that account is the owner or admin of the collection
603 //
604 // @param user account to verify
605 // @return "true" if account is the owner or admin
606 //
607 // Selector: verifyOwnerOrAdmin(address) c2282493
608 function verifyOwnerOrAdmin(address user) public view returns (bool) {
609 require(false, stub_error);
610 user;
611 dummy;
612 return false;
613 }
614
615 // Returns collection type
616 //
617 // @return `Fungible` or `NFT` or `ReFungible`
618 //
619 // Selector: uniqueCollectionType() d34b55b8
620 function uniqueCollectionType() public returns (string memory) {
621 require(false, stub_error);
622 dummy = 0;
623 return "";
624 }
625}
375626
376// Selector: 780e9d63627// Selector: 780e9d63
377contract ERC721Enumerable is Dummy, ERC165 {628contract ERC721Enumerable is Dummy, ERC165 {
415 }666 }
416}667}
417
418// Selector: 7d9262e6
419contract Collection is Dummy, ERC165 {
420 // Set collection property.
421 //
422 // @param key Property key.
423 // @param value Propery value.
424 //
425 // Selector: setCollectionProperty(string,bytes) 2f073f66
426 function setCollectionProperty(string memory key, bytes memory value)
427 public
428 {
429 require(false, stub_error);
430 key;
431 value;
432 dummy = 0;
433 }
434
435 // Delete collection property.
436 //
437 // @param key Property key.
438 //
439 // Selector: deleteCollectionProperty(string) 7b7debce
440 function deleteCollectionProperty(string memory key) public {
441 require(false, stub_error);
442 key;
443 dummy = 0;
444 }
445
446 // Get collection property.
447 //
448 // @dev Throws error if key not found.
449 //
450 // @param key Property key.
451 // @return bytes The property corresponding to the key.
452 //
453 // Selector: collectionProperty(string) cf24fd6d
454 function collectionProperty(string memory key)
455 public
456 view
457 returns (bytes memory)
458 {
459 require(false, stub_error);
460 key;
461 dummy;
462 return hex"";
463 }
464
465 // Set the sponsor of the collection.
466 //
467 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
468 //
469 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
470 //
471 // Selector: setCollectionSponsor(address) 7623402e
472 function setCollectionSponsor(address sponsor) public {
473 require(false, stub_error);
474 sponsor;
475 dummy = 0;
476 }
477
478 // Collection sponsorship confirmation.
479 //
480 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
481 //
482 // Selector: confirmCollectionSponsorship() 3c50e97a
483 function confirmCollectionSponsorship() public {
484 require(false, stub_error);
485 dummy = 0;
486 }
487
488 // Set limits for the collection.
489 // @dev Throws error if limit not found.
490 // @param limit Name of the limit. Valid names:
491 // "accountTokenOwnershipLimit",
492 // "sponsoredDataSize",
493 // "sponsoredDataRateLimit",
494 // "tokenLimit",
495 // "sponsorTransferTimeout",
496 // "sponsorApproveTimeout"
497 // @param value Value of the limit.
498 //
499 // Selector: setCollectionLimit(string,uint32) 6a3841db
500 function setCollectionLimit(string memory limit, uint32 value) public {
501 require(false, stub_error);
502 limit;
503 value;
504 dummy = 0;
505 }
506
507 // Set limits for the collection.
508 // @dev Throws error if limit not found.
509 // @param limit Name of the limit. Valid names:
510 // "ownerCanTransfer",
511 // "ownerCanDestroy",
512 // "transfersEnabled"
513 // @param value Value of the limit.
514 //
515 // Selector: setCollectionLimit(string,bool) 993b7fba
516 function setCollectionLimit(string memory limit, bool value) public {
517 require(false, stub_error);
518 limit;
519 value;
520 dummy = 0;
521 }
522
523 // Get contract address.
524 //
525 // Selector: contractAddress() f6b4dfb4
526 function contractAddress() public view returns (address) {
527 require(false, stub_error);
528 dummy;
529 return 0x0000000000000000000000000000000000000000;
530 }
531
532 // Add collection admin by substrate address.
533 // @param new_admin Substrate administrator address.
534 //
535 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
536 function addCollectionAdminSubstrate(uint256 newAdmin) public {
537 require(false, stub_error);
538 newAdmin;
539 dummy = 0;
540 }
541
542 // Remove collection admin by substrate address.
543 // @param admin Substrate administrator address.
544 //
545 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
546 function removeCollectionAdminSubstrate(uint256 admin) public {
547 require(false, stub_error);
548 admin;
549 dummy = 0;
550 }
551
552 // Add collection admin.
553 // @param new_admin Address of the added administrator.
554 //
555 // Selector: addCollectionAdmin(address) 92e462c7
556 function addCollectionAdmin(address newAdmin) public {
557 require(false, stub_error);
558 newAdmin;
559 dummy = 0;
560 }
561
562 // Remove collection admin.
563 //
564 // @param new_admin Address of the removed administrator.
565 //
566 // Selector: removeCollectionAdmin(address) fafd7b42
567 function removeCollectionAdmin(address admin) public {
568 require(false, stub_error);
569 admin;
570 dummy = 0;
571 }
572
573 // Toggle accessibility of collection nesting.
574 //
575 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
576 //
577 // Selector: setCollectionNesting(bool) 112d4586
578 function setCollectionNesting(bool enable) public {
579 require(false, stub_error);
580 enable;
581 dummy = 0;
582 }
583
584 // Toggle accessibility of collection nesting.
585 //
586 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
587 // @param collections Addresses of collections that will be available for nesting.
588 //
589 // Selector: setCollectionNesting(bool,address[]) 64872396
590 function setCollectionNesting(bool enable, address[] memory collections)
591 public
592 {
593 require(false, stub_error);
594 enable;
595 collections;
596 dummy = 0;
597 }
598
599 // Set the collection access method.
600 // @param mode Access mode
601 // 0 for Normal
602 // 1 for AllowList
603 //
604 // Selector: setCollectionAccess(uint8) 41835d4c
605 function setCollectionAccess(uint8 mode) public {
606 require(false, stub_error);
607 mode;
608 dummy = 0;
609 }
610
611 // Add the user to the allowed list.
612 //
613 // @param user Address of a trusted user.
614 //
615 // Selector: addToCollectionAllowList(address) 67844fe6
616 function addToCollectionAllowList(address user) public {
617 require(false, stub_error);
618 user;
619 dummy = 0;
620 }
621
622 // Remove the user from the allowed list.
623 //
624 // @param user Address of a removed user.
625 //
626 // Selector: removeFromCollectionAllowList(address) 85c51acb
627 function removeFromCollectionAllowList(address user) public {
628 require(false, stub_error);
629 user;
630 dummy = 0;
631 }
632
633 // Switch permission for minting.
634 //
635 // @param mode Enable if "true".
636 //
637 // Selector: setCollectionMintMode(bool) 00018e84
638 function setCollectionMintMode(bool mode) public {
639 require(false, stub_error);
640 mode;
641 dummy = 0;
642 }
643}
644668
645// Selector: d74d154f669// Selector: d74d154f
646contract ERC721UniqueExtensions is Dummy, ERC165 {670contract ERC721UniqueExtensions is Dummy, ERC165 {
modifiedpallets/nonfungible/src/weights.rsdiffbeforeafterboth
3//! Autogenerated weights for pallet_nonfungible3//! Autogenerated weights for pallet_nonfungible
4//!4//!
5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
6//! DATE: 2022-07-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`6//! DATE: 2022-08-01, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
88
9// Executed Command:9// Executed Command:
46 fn set_token_property_permissions(b: u32, ) -> Weight;46 fn set_token_property_permissions(b: u32, ) -> Weight;
47 fn set_token_properties(b: u32, ) -> Weight;47 fn set_token_properties(b: u32, ) -> Weight;
48 fn delete_token_properties(b: u32, ) -> Weight;48 fn delete_token_properties(b: u32, ) -> Weight;
49 fn token_owner() -> Weight;
49}50}
5051
51/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.52/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.
56 // Storage: Nonfungible TokenData (r:0 w:1)57 // Storage: Nonfungible TokenData (r:0 w:1)
57 // Storage: Nonfungible Owned (r:0 w:1)58 // Storage: Nonfungible Owned (r:0 w:1)
58 fn create_item() -> Weight {59 fn create_item() -> Weight {
59 (20_328_000 as Weight)60 (20_909_000 as Weight)
60 .saturating_add(T::DbWeight::get().reads(2 as Weight))61 .saturating_add(T::DbWeight::get().reads(2 as Weight))
61 .saturating_add(T::DbWeight::get().writes(4 as Weight))62 .saturating_add(T::DbWeight::get().writes(4 as Weight))
62 }63 }
65 // Storage: Nonfungible TokenData (r:0 w:4)66 // Storage: Nonfungible TokenData (r:0 w:4)
66 // Storage: Nonfungible Owned (r:0 w:4)67 // Storage: Nonfungible Owned (r:0 w:4)
67 fn create_multiple_items(b: u32, ) -> Weight {68 fn create_multiple_items(b: u32, ) -> Weight {
68 (10_134_000 as Weight)69 (12_601_000 as Weight)
69 // Standard Error: 3_00070 // Standard Error: 1_000
70 .saturating_add((4_927_000 as Weight).saturating_mul(b as Weight))71 .saturating_add((4_920_000 as Weight).saturating_mul(b as Weight))
71 .saturating_add(T::DbWeight::get().reads(2 as Weight))72 .saturating_add(T::DbWeight::get().reads(2 as Weight))
72 .saturating_add(T::DbWeight::get().writes(2 as Weight))73 .saturating_add(T::DbWeight::get().writes(2 as Weight))
73 .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))74 .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))
77 // Storage: Nonfungible TokenData (r:0 w:4)78 // Storage: Nonfungible TokenData (r:0 w:4)
78 // Storage: Nonfungible Owned (r:0 w:4)79 // Storage: Nonfungible Owned (r:0 w:4)
79 fn create_multiple_items_ex(b: u32, ) -> Weight {80 fn create_multiple_items_ex(b: u32, ) -> Weight {
80 (5_710_000 as Weight)81 (0 as Weight)
81 // Standard Error: 4_00082 // Standard Error: 3_000
82 .saturating_add((7_578_000 as Weight).saturating_mul(b as Weight))83 .saturating_add((7_734_000 as Weight).saturating_mul(b as Weight))
83 .saturating_add(T::DbWeight::get().reads(1 as Weight))84 .saturating_add(T::DbWeight::get().reads(1 as Weight))
84 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))85 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
85 .saturating_add(T::DbWeight::get().writes(1 as Weight))86 .saturating_add(T::DbWeight::get().writes(1 as Weight))
93 // Storage: Nonfungible Owned (r:0 w:1)94 // Storage: Nonfungible Owned (r:0 w:1)
94 // Storage: Nonfungible TokenProperties (r:0 w:1)95 // Storage: Nonfungible TokenProperties (r:0 w:1)
95 fn burn_item() -> Weight {96 fn burn_item() -> Weight {
96 (28_433_000 as Weight)97 (29_746_000 as Weight)
97 .saturating_add(T::DbWeight::get().reads(5 as Weight))98 .saturating_add(T::DbWeight::get().reads(5 as Weight))
98 .saturating_add(T::DbWeight::get().writes(5 as Weight))99 .saturating_add(T::DbWeight::get().writes(5 as Weight))
99 }100 }
105 // Storage: Nonfungible Owned (r:0 w:1)106 // Storage: Nonfungible Owned (r:0 w:1)
106 // Storage: Nonfungible TokenProperties (r:0 w:1)107 // Storage: Nonfungible TokenProperties (r:0 w:1)
107 fn burn_recursively_self_raw() -> Weight {108 fn burn_recursively_self_raw() -> Weight {
108 (34_435_000 as Weight)109 (36_077_000 as Weight)
109 .saturating_add(T::DbWeight::get().reads(5 as Weight))110 .saturating_add(T::DbWeight::get().reads(5 as Weight))
110 .saturating_add(T::DbWeight::get().writes(5 as Weight))111 .saturating_add(T::DbWeight::get().writes(5 as Weight))
111 }112 }
119 // Storage: Common CollectionById (r:1 w:0)120 // Storage: Common CollectionById (r:1 w:0)
120 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {121 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {
121 (0 as Weight)122 (0 as Weight)
122 // Standard Error: 1_539_000123 // Standard Error: 1_605_000
123 .saturating_add((304_456_000 as Weight).saturating_mul(b as Weight))124 .saturating_add((312_391_000 as Weight).saturating_mul(b as Weight))
124 .saturating_add(T::DbWeight::get().reads(7 as Weight))125 .saturating_add(T::DbWeight::get().reads(7 as Weight))
125 .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))126 .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))
126 .saturating_add(T::DbWeight::get().writes(6 as Weight))127 .saturating_add(T::DbWeight::get().writes(6 as Weight))
131 // Storage: Nonfungible Allowance (r:1 w:0)132 // Storage: Nonfungible Allowance (r:1 w:0)
132 // Storage: Nonfungible Owned (r:0 w:2)133 // Storage: Nonfungible Owned (r:0 w:2)
133 fn transfer() -> Weight {134 fn transfer() -> Weight {
134 (24_376_000 as Weight)135 (25_248_000 as Weight)
135 .saturating_add(T::DbWeight::get().reads(4 as Weight))136 .saturating_add(T::DbWeight::get().reads(4 as Weight))
136 .saturating_add(T::DbWeight::get().writes(5 as Weight))137 .saturating_add(T::DbWeight::get().writes(5 as Weight))
137 }138 }
138 // Storage: Nonfungible TokenData (r:1 w:0)139 // Storage: Nonfungible TokenData (r:1 w:0)
139 // Storage: Nonfungible Allowance (r:1 w:1)140 // Storage: Nonfungible Allowance (r:1 w:1)
140 fn approve() -> Weight {141 fn approve() -> Weight {
141 (15_890_000 as Weight)142 (16_321_000 as Weight)
142 .saturating_add(T::DbWeight::get().reads(2 as Weight))143 .saturating_add(T::DbWeight::get().reads(2 as Weight))
143 .saturating_add(T::DbWeight::get().writes(1 as Weight))144 .saturating_add(T::DbWeight::get().writes(1 as Weight))
144 }145 }
147 // Storage: Nonfungible AccountBalance (r:2 w:2)148 // Storage: Nonfungible AccountBalance (r:2 w:2)
148 // Storage: Nonfungible Owned (r:0 w:2)149 // Storage: Nonfungible Owned (r:0 w:2)
149 fn transfer_from() -> Weight {150 fn transfer_from() -> Weight {
150 (28_634_000 as Weight)151 (29_325_000 as Weight)
151 .saturating_add(T::DbWeight::get().reads(4 as Weight))152 .saturating_add(T::DbWeight::get().reads(4 as Weight))
152 .saturating_add(T::DbWeight::get().writes(6 as Weight))153 .saturating_add(T::DbWeight::get().writes(6 as Weight))
153 }154 }
159 // Storage: Nonfungible Owned (r:0 w:1)160 // Storage: Nonfungible Owned (r:0 w:1)
160 // Storage: Nonfungible TokenProperties (r:0 w:1)161 // Storage: Nonfungible TokenProperties (r:0 w:1)
161 fn burn_from() -> Weight {162 fn burn_from() -> Weight {
162 (32_201_000 as Weight)163 (33_323_000 as Weight)
163 .saturating_add(T::DbWeight::get().reads(5 as Weight))164 .saturating_add(T::DbWeight::get().reads(5 as Weight))
164 .saturating_add(T::DbWeight::get().writes(6 as Weight))165 .saturating_add(T::DbWeight::get().writes(6 as Weight))
165 }166 }
166 // Storage: Common CollectionPropertyPermissions (r:1 w:1)167 // Storage: Common CollectionPropertyPermissions (r:1 w:1)
167 fn set_token_property_permissions(b: u32, ) -> Weight {168 fn set_token_property_permissions(b: u32, ) -> Weight {
168 (0 as Weight)169 (0 as Weight)
169 // Standard Error: 57_000170 // Standard Error: 62_000
170 .saturating_add((15_232_000 as Weight).saturating_mul(b as Weight))171 .saturating_add((16_222_000 as Weight).saturating_mul(b as Weight))
171 .saturating_add(T::DbWeight::get().reads(1 as Weight))172 .saturating_add(T::DbWeight::get().reads(1 as Weight))
172 .saturating_add(T::DbWeight::get().writes(1 as Weight))173 .saturating_add(T::DbWeight::get().writes(1 as Weight))
173 }174 }
174 // Storage: Common CollectionPropertyPermissions (r:1 w:0)175 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
175 // Storage: Nonfungible TokenProperties (r:1 w:1)176 // Storage: Nonfungible TokenProperties (r:1 w:1)
176 fn set_token_properties(b: u32, ) -> Weight {177 fn set_token_properties(b: u32, ) -> Weight {
177 (0 as Weight)178 (0 as Weight)
178 // Standard Error: 1_648_000179 // Standard Error: 1_750_000
179 .saturating_add((288_654_000 as Weight).saturating_mul(b as Weight))180 .saturating_add((304_476_000 as Weight).saturating_mul(b as Weight))
180 .saturating_add(T::DbWeight::get().reads(2 as Weight))181 .saturating_add(T::DbWeight::get().reads(2 as Weight))
181 .saturating_add(T::DbWeight::get().writes(1 as Weight))182 .saturating_add(T::DbWeight::get().writes(1 as Weight))
182 }183 }
183 // Storage: Common CollectionPropertyPermissions (r:1 w:0)184 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
184 // Storage: Nonfungible TokenProperties (r:1 w:1)185 // Storage: Nonfungible TokenProperties (r:1 w:1)
185 fn delete_token_properties(b: u32, ) -> Weight {186 fn delete_token_properties(b: u32, ) -> Weight {
186 (0 as Weight)187 (0 as Weight)
187 // Standard Error: 1_632_000188 // Standard Error: 1_638_000
188 .saturating_add((289_190_000 as Weight).saturating_mul(b as Weight))189 .saturating_add((294_096_000 as Weight).saturating_mul(b as Weight))
189 .saturating_add(T::DbWeight::get().reads(2 as Weight))190 .saturating_add(T::DbWeight::get().reads(2 as Weight))
190 .saturating_add(T::DbWeight::get().writes(1 as Weight))191 .saturating_add(T::DbWeight::get().writes(1 as Weight))
191 }192 }
193 // Storage: Nonfungible TokenData (r:1 w:0)
194 fn token_owner() -> Weight {
195 (2_986_000 as Weight)
196 .saturating_add(T::DbWeight::get().reads(1 as Weight))
197 }
192}198}
193199
194// For backwards compatibility and tests200// For backwards compatibility and tests
198 // Storage: Nonfungible TokenData (r:0 w:1)204 // Storage: Nonfungible TokenData (r:0 w:1)
199 // Storage: Nonfungible Owned (r:0 w:1)205 // Storage: Nonfungible Owned (r:0 w:1)
200 fn create_item() -> Weight {206 fn create_item() -> Weight {
201 (20_328_000 as Weight)207 (20_909_000 as Weight)
202 .saturating_add(RocksDbWeight::get().reads(2 as Weight))208 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
203 .saturating_add(RocksDbWeight::get().writes(4 as Weight))209 .saturating_add(RocksDbWeight::get().writes(4 as Weight))
204 }210 }
207 // Storage: Nonfungible TokenData (r:0 w:4)213 // Storage: Nonfungible TokenData (r:0 w:4)
208 // Storage: Nonfungible Owned (r:0 w:4)214 // Storage: Nonfungible Owned (r:0 w:4)
209 fn create_multiple_items(b: u32, ) -> Weight {215 fn create_multiple_items(b: u32, ) -> Weight {
210 (10_134_000 as Weight)216 (12_601_000 as Weight)
211 // Standard Error: 3_000217 // Standard Error: 1_000
212 .saturating_add((4_927_000 as Weight).saturating_mul(b as Weight))218 .saturating_add((4_920_000 as Weight).saturating_mul(b as Weight))
213 .saturating_add(RocksDbWeight::get().reads(2 as Weight))219 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
214 .saturating_add(RocksDbWeight::get().writes(2 as Weight))220 .saturating_add(RocksDbWeight::get().writes(2 as Weight))
215 .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))221 .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))
219 // Storage: Nonfungible TokenData (r:0 w:4)225 // Storage: Nonfungible TokenData (r:0 w:4)
220 // Storage: Nonfungible Owned (r:0 w:4)226 // Storage: Nonfungible Owned (r:0 w:4)
221 fn create_multiple_items_ex(b: u32, ) -> Weight {227 fn create_multiple_items_ex(b: u32, ) -> Weight {
222 (5_710_000 as Weight)228 (0 as Weight)
223 // Standard Error: 4_000229 // Standard Error: 3_000
224 .saturating_add((7_578_000 as Weight).saturating_mul(b as Weight))230 .saturating_add((7_734_000 as Weight).saturating_mul(b as Weight))
225 .saturating_add(RocksDbWeight::get().reads(1 as Weight))231 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
226 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))232 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
227 .saturating_add(RocksDbWeight::get().writes(1 as Weight))233 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
235 // Storage: Nonfungible Owned (r:0 w:1)241 // Storage: Nonfungible Owned (r:0 w:1)
236 // Storage: Nonfungible TokenProperties (r:0 w:1)242 // Storage: Nonfungible TokenProperties (r:0 w:1)
237 fn burn_item() -> Weight {243 fn burn_item() -> Weight {
238 (28_433_000 as Weight)244 (29_746_000 as Weight)
239 .saturating_add(RocksDbWeight::get().reads(5 as Weight))245 .saturating_add(RocksDbWeight::get().reads(5 as Weight))
240 .saturating_add(RocksDbWeight::get().writes(5 as Weight))246 .saturating_add(RocksDbWeight::get().writes(5 as Weight))
241 }247 }
247 // Storage: Nonfungible Owned (r:0 w:1)253 // Storage: Nonfungible Owned (r:0 w:1)
248 // Storage: Nonfungible TokenProperties (r:0 w:1)254 // Storage: Nonfungible TokenProperties (r:0 w:1)
249 fn burn_recursively_self_raw() -> Weight {255 fn burn_recursively_self_raw() -> Weight {
250 (34_435_000 as Weight)256 (36_077_000 as Weight)
251 .saturating_add(RocksDbWeight::get().reads(5 as Weight))257 .saturating_add(RocksDbWeight::get().reads(5 as Weight))
252 .saturating_add(RocksDbWeight::get().writes(5 as Weight))258 .saturating_add(RocksDbWeight::get().writes(5 as Weight))
253 }259 }
261 // Storage: Common CollectionById (r:1 w:0)267 // Storage: Common CollectionById (r:1 w:0)
262 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {268 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {
263 (0 as Weight)269 (0 as Weight)
264 // Standard Error: 1_539_000270 // Standard Error: 1_605_000
265 .saturating_add((304_456_000 as Weight).saturating_mul(b as Weight))271 .saturating_add((312_391_000 as Weight).saturating_mul(b as Weight))
266 .saturating_add(RocksDbWeight::get().reads(7 as Weight))272 .saturating_add(RocksDbWeight::get().reads(7 as Weight))
267 .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))273 .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))
268 .saturating_add(RocksDbWeight::get().writes(6 as Weight))274 .saturating_add(RocksDbWeight::get().writes(6 as Weight))
273 // Storage: Nonfungible Allowance (r:1 w:0)279 // Storage: Nonfungible Allowance (r:1 w:0)
274 // Storage: Nonfungible Owned (r:0 w:2)280 // Storage: Nonfungible Owned (r:0 w:2)
275 fn transfer() -> Weight {281 fn transfer() -> Weight {
276 (24_376_000 as Weight)282 (25_248_000 as Weight)
277 .saturating_add(RocksDbWeight::get().reads(4 as Weight))283 .saturating_add(RocksDbWeight::get().reads(4 as Weight))
278 .saturating_add(RocksDbWeight::get().writes(5 as Weight))284 .saturating_add(RocksDbWeight::get().writes(5 as Weight))
279 }285 }
280 // Storage: Nonfungible TokenData (r:1 w:0)286 // Storage: Nonfungible TokenData (r:1 w:0)
281 // Storage: Nonfungible Allowance (r:1 w:1)287 // Storage: Nonfungible Allowance (r:1 w:1)
282 fn approve() -> Weight {288 fn approve() -> Weight {
283 (15_890_000 as Weight)289 (16_321_000 as Weight)
284 .saturating_add(RocksDbWeight::get().reads(2 as Weight))290 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
285 .saturating_add(RocksDbWeight::get().writes(1 as Weight))291 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
286 }292 }
289 // Storage: Nonfungible AccountBalance (r:2 w:2)295 // Storage: Nonfungible AccountBalance (r:2 w:2)
290 // Storage: Nonfungible Owned (r:0 w:2)296 // Storage: Nonfungible Owned (r:0 w:2)
291 fn transfer_from() -> Weight {297 fn transfer_from() -> Weight {
292 (28_634_000 as Weight)298 (29_325_000 as Weight)
293 .saturating_add(RocksDbWeight::get().reads(4 as Weight))299 .saturating_add(RocksDbWeight::get().reads(4 as Weight))
294 .saturating_add(RocksDbWeight::get().writes(6 as Weight))300 .saturating_add(RocksDbWeight::get().writes(6 as Weight))
295 }301 }
301 // Storage: Nonfungible Owned (r:0 w:1)307 // Storage: Nonfungible Owned (r:0 w:1)
302 // Storage: Nonfungible TokenProperties (r:0 w:1)308 // Storage: Nonfungible TokenProperties (r:0 w:1)
303 fn burn_from() -> Weight {309 fn burn_from() -> Weight {
304 (32_201_000 as Weight)310 (33_323_000 as Weight)
305 .saturating_add(RocksDbWeight::get().reads(5 as Weight))311 .saturating_add(RocksDbWeight::get().reads(5 as Weight))
306 .saturating_add(RocksDbWeight::get().writes(6 as Weight))312 .saturating_add(RocksDbWeight::get().writes(6 as Weight))
307 }313 }
308 // Storage: Common CollectionPropertyPermissions (r:1 w:1)314 // Storage: Common CollectionPropertyPermissions (r:1 w:1)
309 fn set_token_property_permissions(b: u32, ) -> Weight {315 fn set_token_property_permissions(b: u32, ) -> Weight {
310 (0 as Weight)316 (0 as Weight)
311 // Standard Error: 57_000317 // Standard Error: 62_000
312 .saturating_add((15_232_000 as Weight).saturating_mul(b as Weight))318 .saturating_add((16_222_000 as Weight).saturating_mul(b as Weight))
313 .saturating_add(RocksDbWeight::get().reads(1 as Weight))319 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
314 .saturating_add(RocksDbWeight::get().writes(1 as Weight))320 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
315 }321 }
316 // Storage: Common CollectionPropertyPermissions (r:1 w:0)322 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
317 // Storage: Nonfungible TokenProperties (r:1 w:1)323 // Storage: Nonfungible TokenProperties (r:1 w:1)
318 fn set_token_properties(b: u32, ) -> Weight {324 fn set_token_properties(b: u32, ) -> Weight {
319 (0 as Weight)325 (0 as Weight)
320 // Standard Error: 1_648_000326 // Standard Error: 1_750_000
321 .saturating_add((288_654_000 as Weight).saturating_mul(b as Weight))327 .saturating_add((304_476_000 as Weight).saturating_mul(b as Weight))
322 .saturating_add(RocksDbWeight::get().reads(2 as Weight))328 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
323 .saturating_add(RocksDbWeight::get().writes(1 as Weight))329 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
324 }330 }
325 // Storage: Common CollectionPropertyPermissions (r:1 w:0)331 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
326 // Storage: Nonfungible TokenProperties (r:1 w:1)332 // Storage: Nonfungible TokenProperties (r:1 w:1)
327 fn delete_token_properties(b: u32, ) -> Weight {333 fn delete_token_properties(b: u32, ) -> Weight {
328 (0 as Weight)334 (0 as Weight)
329 // Standard Error: 1_632_000335 // Standard Error: 1_638_000
330 .saturating_add((289_190_000 as Weight).saturating_mul(b as Weight))336 .saturating_add((294_096_000 as Weight).saturating_mul(b as Weight))
331 .saturating_add(RocksDbWeight::get().reads(2 as Weight))337 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
332 .saturating_add(RocksDbWeight::get().writes(1 as Weight))338 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
333 }339 }
340 // Storage: Nonfungible TokenData (r:1 w:0)
341 fn token_owner() -> Weight {
342 (2_986_000 as Weight)
343 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
344 }
334}345}
335346
modifiedpallets/refungible/src/benchmarking.rsdiffbeforeafterboth
17use super::*;17use super::*;
18use crate::{Pallet, Config, RefungibleHandle};18use crate::{Pallet, Config, RefungibleHandle};
1919
20use sp_std::prelude::*;20use core::convert::TryInto;
21use pallet_common::benchmarking::{create_collection_raw, property_key, property_value, create_data};21use core::iter::IntoIterator;
22use frame_benchmarking::{benchmarks, account};22use frame_benchmarking::{benchmarks, account};
23use up_data_structs::{23use pallet_common::{
24 CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,24 bench_init,
25 budget::Unlimited,25 benchmarking::{create_collection_raw, property_key, property_value, create_data},
26};26};
27use pallet_common::bench_init;27use sp_core::H160;
28use core::convert::TryInto;28use sp_std::prelude::*;
29use core::iter::IntoIterator;29use up_data_structs::{
30 CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,
31 budget::Unlimited,
32};
3033
31const SEED: u32 = 1;34const SEED: u32 = 1;
3235
33fn create_max_item_data<CrossAccountId: Ord>(36fn create_max_item_data<CrossAccountId: Ord>(
34 users: impl IntoIterator<Item = (CrossAccountId, u128)>,37 users: impl IntoIterator<Item = (CrossAccountId, u128)>,
35) -> CreateRefungibleExData<CrossAccountId> {38) -> CreateRefungibleExData<CrossAccountId> {
36 let const_data = create_data::<CUSTOM_DATA_LIMIT>();
37 CreateRefungibleExData {39 CreateRefungibleExData {
38 const_data,
39 users: users40 users: users
40 .into_iter()41 .into_iter()
41 .collect::<BTreeMap<_, _>>()42 .collect::<BTreeMap<_, _>>()
59) -> Result<RefungibleHandle<T>, DispatchError> {61) -> Result<RefungibleHandle<T>, DispatchError> {
60 create_collection_raw(62 create_collection_raw(
61 owner,63 owner,
62 CollectionMode::NFT,64 CollectionMode::ReFungible,
63 <Pallet<T>>::init_collection,65 <Pallet<T>>::init_collection,
64 RefungibleHandle::cast,66 RefungibleHandle::cast,
65 )67 )
278 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;281 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
279 }: {<Pallet<T>>::repartition(&collection, &owner, item, 200)?}282 }: {<Pallet<T>>::repartition(&collection, &owner, item, 200)?}
283
284 set_parent_nft_unchecked {
285 bench_init!{
286 owner: sub; collection: collection(owner);
287 sender: cross_from_sub(owner); owner: cross_sub;
288 };
289 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
290
291 }: {<Pallet<T>>::set_parent_nft_unchecked(&collection, item, owner, T::CrossAccountId::from_eth(H160::default()))?}
292
293 token_owner {
294 bench_init!{
295 owner: sub; collection: collection(owner);
296 sender: cross_from_sub(owner); owner: cross_sub;
297 };
298 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
299 }: {<Pallet<T>>::token_owner(collection.id, item)}
280}300}
281301
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
149 0149 0
150 }150 }
151
152 fn token_owner() -> Weight {
153 <SelfWeightOf<T>>::token_owner()
154 }
151}155}
152156
153fn map_create_data<T: Config>(157fn map_create_data<T: Config>(
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
41use sp_core::H160;41use sp_core::H160;
42use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};42use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
43use up_data_structs::{43use up_data_structs::{
44 CollectionId, CollectionPropertiesVec, Property, PropertyKey, PropertyKeyPermission,44 CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey,
45 PropertyPermission, TokenId,45 PropertyKeyPermission, PropertyPermission, TokenId,
46};46};
4747
413}413}
414414
415/// Returns amount of pieces of `token` that `owner` have415/// Returns amount of pieces of `token` that `owner` have
416fn balance<T: Config>(416pub fn balance<T: Config>(
417 collection: &RefungibleHandle<T>,417 collection: &RefungibleHandle<T>,
418 token: TokenId,418 token: TokenId,
419 owner: &T::CrossAccountId,419 owner: &T::CrossAccountId,
424}424}
425425
426/// Throws if `owner_balance` is lower than total amount of `token` pieces426/// Throws if `owner_balance` is lower than total amount of `token` pieces
427fn ensure_single_owner<T: Config>(427pub fn ensure_single_owner<T: Config>(
428 collection: &RefungibleHandle<T>,428 collection: &RefungibleHandle<T>,
429 token: TokenId,429 token: TokenId,
430 owner_balance: u128,430 owner_balance: u128,
789 Ok(true)789 Ok(true)
790 }790 }
791
792 /// Returns EVM address for refungible token
793 ///
794 /// @param token ID of the token
795 fn token_contract_address(&self, token: uint256) -> Result<address> {
796 Ok(T::EvmTokenAddressMapping::token_to_address(
797 self.id,
798 token.try_into().map_err(|_| "token id overflow")?,
799 ))
800 }
791}801}
792802
793#[solidity_interface(803#[solidity_interface(
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
2121
22extern crate alloc;22extern crate alloc;
23
24#[cfg(not(feature = "std"))]
25use alloc::format;
26
23use core::{27use core::{
24 char::{REPLACEMENT_CHARACTER, decode_utf16},28 char::{REPLACEMENT_CHARACTER, decode_utf16},
25 convert::TryInto,29 convert::TryInto,
26 ops::Deref,30 ops::Deref,
27};31};
28use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};32use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight};
29use pallet_common::{33use pallet_common::{
30 CommonWeightInfo,34 CommonWeightInfo,
31 erc::{CommonEvmHandler, PrecompileResult},35 erc::{CommonEvmHandler, PrecompileResult, static_property::key},
36 eth::map_eth_to_id,
32};37};
33use pallet_evm::{account::CrossAccountId, PrecompileHandle};38use pallet_evm::{account::CrossAccountId, PrecompileHandle};
34use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};39use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
35use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};40use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
41use sp_core::H160;
36use sp_std::vec::Vec;42use sp_std::vec::Vec;
37use up_data_structs::TokenId;43use up_data_structs::{mapping::TokenAddressMapping, PropertyScope, TokenId};
3844
39use crate::{45use crate::{
40 Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,46 Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,
41 weights::WeightInfo, TotalSupply,47 TokenProperties, TotalSupply, weights::WeightInfo,
42};48};
4349
44pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);50pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);
51
52#[solidity_interface(name = "ERC1633")]
53impl<T: Config> RefungibleTokenHandle<T> {
54 fn parent_token(&self) -> Result<address> {
55 self.consume_store_reads(2)?;
56 let props = <TokenProperties<T>>::get((self.id, self.1));
57 let key = key::parent_nft();
58
59 let key_scoped = PropertyScope::Eth
60 .apply(key)
61 .expect("property key shouldn't exceed length limit");
62 if let Some(value) = props.get(&key_scoped) {
63 Ok(H160::from_slice(value.as_slice()))
64 } else {
65 Ok(*T::CrossTokenAddressMapping::token_to_address(self.id, self.1).as_eth())
66 }
67 }
68
69 fn parent_token_id(&self) -> Result<uint256> {
70 self.consume_store_reads(2)?;
71 let props = <TokenProperties<T>>::get((self.id, self.1));
72 let key = key::parent_nft();
73
74 let key_scoped = PropertyScope::Eth
75 .apply(key)
76 .expect("property key shouldn't exceed length limit");
77 if let Some(value) = props.get(&key_scoped) {
78 let nft_token_address = H160::from_slice(value.as_slice());
79 let nft_token_account = T::CrossAccountId::from_eth(nft_token_address);
80 let (_, token_id) = T::CrossTokenAddressMapping::address_to_token(&nft_token_account)
81 .ok_or("parent NFT should contain NFT token address")?;
82
83 Ok(token_id.into())
84 } else {
85 Ok(self.1.into())
86 }
87 }
88}
89
90#[solidity_interface(name = "ERC1633UniqueExtensions")]
91impl<T: Config> RefungibleTokenHandle<T> {
92 #[solidity(rename_selector = "setParentNFT")]
93 #[weight(<CommonWeights<T>>::token_owner() + <SelfWeightOf<T>>::set_parent_nft_unchecked())]
94 fn set_parent_nft(
95 &mut self,
96 caller: caller,
97 collection: address,
98 nft_id: uint256,
99 ) -> Result<bool> {
100 self.consume_store_reads(1)?;
101 let caller = T::CrossAccountId::from_eth(caller);
102 let nft_collection = map_eth_to_id(&collection).ok_or("collection not found")?;
103 let nft_token = nft_id.try_into()?;
104
105 <Pallet<T>>::set_parent_nft(&self.0, self.1, caller, nft_collection, nft_token)
106 .map_err(dispatch_to_evm::<T>)?;
107
108 Ok(true)
109 }
110}
45111
46#[derive(ToLog)]112#[derive(ToLog)]
47pub enum ERC20Events {113pub enum ERC20Events {
120 .weight_calls_budget(<StructureWeight<T>>::find_parent());186 .weight_calls_budget(<StructureWeight<T>>::find_parent());
121187
122 <Pallet<T>>::transfer(self, &caller, &to, self.1, amount, &budget)188 <Pallet<T>>::transfer(self, &caller, &to, self.1, amount, &budget)
123 .map_err(|_| "transfer error")?;189 .map_err(dispatch_to_evm::<T>)?;
124 Ok(true)190 Ok(true)
125 }191 }
126192
241307
242#[solidity_interface(name = "UniqueRefungibleToken", is(ERC20, ERC20UniqueExtensions,))]308#[solidity_interface(
309 name = "UniqueRefungibleToken",
310 is(ERC20, ERC20UniqueExtensions, ERC1633, ERC1633UniqueExtensions)
311)]
243impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}312impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}
244313
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
99use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};99use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
100use pallet_evm_coder_substrate::WithRecorder;100use pallet_evm_coder_substrate::WithRecorder;
101use pallet_common::{101use pallet_common::{
102 CommonCollectionOperations, Error as CommonError, Event as CommonEvent,102 CollectionHandle, CommonCollectionOperations,
103 dispatch::CollectionDispatch,
104 erc::static_property::{key, property_value_from_bytes},
105 Error as CommonError,
103 eth::collection_id_to_address, Pallet as PalletCommon,106 eth::collection_id_to_address,
107 Event as CommonEvent, Pallet as PalletCommon,
104};108};
105use pallet_structure::Pallet as PalletStructure;109use pallet_structure::Pallet as PalletStructure;
106use scale_info::TypeInfo;110use scale_info::TypeInfo;
107use sp_core::H160;111use sp_core::H160;
108use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};112use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};
109use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};113use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
110use up_data_structs::{114use up_data_structs::{
111 AccessMode, budget::Budget, CollectionId, CreateCollectionData, CustomDataLimit,115 AccessMode, budget::Budget, CollectionId, CollectionMode, CollectionPropertiesVec,
112 mapping::TokenAddressMapping, MAX_REFUNGIBLE_PIECES, MAX_ITEMS_PER_BATCH, TokenId, Property,116 CreateCollectionData, CustomDataLimit, mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH,
113 PropertyKey, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,117 MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyPermission,
114 TrySetProperty, CollectionPropertiesVec,118 PropertyScope, PropertyValue, TokenId, TrySetProperty,
115};119};
116use frame_support::BoundedBTreeMap;120use frame_support::BoundedBTreeMap;
117use derivative::Derivative;121use derivative::Derivative;
1341 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)1345 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
1342 }1346 }
1347
1348 pub fn set_scoped_token_property_permissions(
1349 collection: &RefungibleHandle<T>,
1350 sender: &T::CrossAccountId,
1351 scope: PropertyScope,
1352 property_permissions: Vec<PropertyKeyPermission>,
1353 ) -> DispatchResult {
1354 <PalletCommon<T>>::set_scoped_token_property_permissions(
1355 collection,
1356 sender,
1357 scope,
1358 property_permissions,
1359 )
1360 }
13431361
1344 /// Returns 10 token in no particular order.1362 /// Returns 10 token in no particular order.
1345 ///1363 ///
1363 }1381 }
1364 }1382 }
1383
1384 /// Sets the NFT token as a parent for the RFT token
1385 ///
1386 /// Throws if `sender` is not the owner of the NFT token.
1387 /// Throws if `sender` is not the owner of all of the RFT token pieces.
1388 pub fn set_parent_nft(
1389 collection: &RefungibleHandle<T>,
1390 rft_token_id: TokenId,
1391 sender: T::CrossAccountId,
1392 nft_collection: CollectionId,
1393 nft_token: TokenId,
1394 ) -> DispatchResult {
1395 let handle = <CollectionHandle<T>>::try_get(nft_collection)?;
1396 if handle.mode != CollectionMode::NFT {
1397 return Err("Only NFT token could be parent to RFT".into());
1398 }
1399 let dispatch = T::CollectionDispatch::dispatch(handle);
1400 let dispatch = dispatch.as_dyn();
1401
1402 let owner = dispatch.token_owner(nft_token).ok_or("owner not found")?;
1403 if owner != sender {
1404 return Err("Only owned token could be set as parent".into());
1405 }
1406
1407 let nft_token_address =
1408 T::CrossTokenAddressMapping::token_to_address(nft_collection, nft_token);
1409
1410 Self::set_parent_nft_unchecked(collection, rft_token_id, sender, nft_token_address)
1411 }
1412
1413 /// Sets the NFT token as a parent for the RFT token
1414 ///
1415 /// `sender` should be the owner of the NFT token.
1416 /// Throws if `sender` is not the owner of all of the RFT token pieces.
1417 pub fn set_parent_nft_unchecked(
1418 collection: &RefungibleHandle<T>,
1419 rft_token_id: TokenId,
1420 sender: T::CrossAccountId,
1421 nft_token_address: T::CrossAccountId,
1422 ) -> DispatchResult {
1423 let owner_balance = <Balance<T>>::get((collection.id, rft_token_id, &sender));
1424 let total_supply = <TotalSupply<T>>::get((collection.id, rft_token_id));
1425 if total_supply != owner_balance {
1426 return Err("token has multiple owners".into());
1427 }
1428
1429 let parent_nft_property_key = key::parent_nft();
1430
1431 let parent_nft_property_value =
1432 property_value_from_bytes(&nft_token_address.as_eth().to_fixed_bytes())
1433 .expect("address should fit in value length limit");
1434
1435 <Pallet<T>>::set_scoped_token_property(
1436 collection.id,
1437 rft_token_id,
1438 PropertyScope::Eth,
1439 Property {
1440 key: parent_nft_property_key,
1441 value: parent_nft_property_value,
1442 },
1443 )?;
1444
1445 Ok(())
1446 }
1365}1447}
13661448
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
371 }371 }
372}372}
373
374// Selector: 6cf113cd
375contract Collection is Dummy, ERC165 {
376 // Set collection property.
377 //
378 // @param key Property key.
379 // @param value Propery value.
380 //
381 // Selector: setCollectionProperty(string,bytes) 2f073f66
382 function setCollectionProperty(string memory key, bytes memory value)
383 public
384 {
385 require(false, stub_error);
386 key;
387 value;
388 dummy = 0;
389 }
390
391 // Delete collection property.
392 //
393 // @param key Property key.
394 //
395 // Selector: deleteCollectionProperty(string) 7b7debce
396 function deleteCollectionProperty(string memory key) public {
397 require(false, stub_error);
398 key;
399 dummy = 0;
400 }
401
402 // Get collection property.
403 //
404 // @dev Throws error if key not found.
405 //
406 // @param key Property key.
407 // @return bytes The property corresponding to the key.
408 //
409 // Selector: collectionProperty(string) cf24fd6d
410 function collectionProperty(string memory key)
411 public
412 view
413 returns (bytes memory)
414 {
415 require(false, stub_error);
416 key;
417 dummy;
418 return hex"";
419 }
420
421 // Set the sponsor of the collection.
422 //
423 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
424 //
425 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
426 //
427 // Selector: setCollectionSponsor(address) 7623402e
428 function setCollectionSponsor(address sponsor) public {
429 require(false, stub_error);
430 sponsor;
431 dummy = 0;
432 }
433
434 // Collection sponsorship confirmation.
435 //
436 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
437 //
438 // Selector: confirmCollectionSponsorship() 3c50e97a
439 function confirmCollectionSponsorship() public {
440 require(false, stub_error);
441 dummy = 0;
442 }
443
444 // Set limits for the collection.
445 // @dev Throws error if limit not found.
446 // @param limit Name of the limit. Valid names:
447 // "accountTokenOwnershipLimit",
448 // "sponsoredDataSize",
449 // "sponsoredDataRateLimit",
450 // "tokenLimit",
451 // "sponsorTransferTimeout",
452 // "sponsorApproveTimeout"
453 // @param value Value of the limit.
454 //
455 // Selector: setCollectionLimit(string,uint32) 6a3841db
456 function setCollectionLimit(string memory limit, uint32 value) public {
457 require(false, stub_error);
458 limit;
459 value;
460 dummy = 0;
461 }
462
463 // Set limits for the collection.
464 // @dev Throws error if limit not found.
465 // @param limit Name of the limit. Valid names:
466 // "ownerCanTransfer",
467 // "ownerCanDestroy",
468 // "transfersEnabled"
469 // @param value Value of the limit.
470 //
471 // Selector: setCollectionLimit(string,bool) 993b7fba
472 function setCollectionLimit(string memory limit, bool value) public {
473 require(false, stub_error);
474 limit;
475 value;
476 dummy = 0;
477 }
478
479 // Get contract address.
480 //
481 // Selector: contractAddress() f6b4dfb4
482 function contractAddress() public view returns (address) {
483 require(false, stub_error);
484 dummy;
485 return 0x0000000000000000000000000000000000000000;
486 }
487
488 // Add collection admin by substrate address.
489 // @param new_admin Substrate administrator address.
490 //
491 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
492 function addCollectionAdminSubstrate(uint256 newAdmin) public {
493 require(false, stub_error);
494 newAdmin;
495 dummy = 0;
496 }
497
498 // Remove collection admin by substrate address.
499 // @param admin Substrate administrator address.
500 //
501 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
502 function removeCollectionAdminSubstrate(uint256 admin) public {
503 require(false, stub_error);
504 admin;
505 dummy = 0;
506 }
507
508 // Add collection admin.
509 // @param new_admin Address of the added administrator.
510 //
511 // Selector: addCollectionAdmin(address) 92e462c7
512 function addCollectionAdmin(address newAdmin) public {
513 require(false, stub_error);
514 newAdmin;
515 dummy = 0;
516 }
517
518 // Remove collection admin.
519 //
520 // @param new_admin Address of the removed administrator.
521 //
522 // Selector: removeCollectionAdmin(address) fafd7b42
523 function removeCollectionAdmin(address admin) public {
524 require(false, stub_error);
525 admin;
526 dummy = 0;
527 }
528
529 // Toggle accessibility of collection nesting.
530 //
531 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
532 //
533 // Selector: setCollectionNesting(bool) 112d4586
534 function setCollectionNesting(bool enable) public {
535 require(false, stub_error);
536 enable;
537 dummy = 0;
538 }
539
540 // Toggle accessibility of collection nesting.
541 //
542 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
543 // @param collections Addresses of collections that will be available for nesting.
544 //
545 // Selector: setCollectionNesting(bool,address[]) 64872396
546 function setCollectionNesting(bool enable, address[] memory collections)
547 public
548 {
549 require(false, stub_error);
550 enable;
551 collections;
552 dummy = 0;
553 }
554
555 // Set the collection access method.
556 // @param mode Access mode
557 // 0 for Normal
558 // 1 for AllowList
559 //
560 // Selector: setCollectionAccess(uint8) 41835d4c
561 function setCollectionAccess(uint8 mode) public {
562 require(false, stub_error);
563 mode;
564 dummy = 0;
565 }
566
567 // Add the user to the allowed list.
568 //
569 // @param user Address of a trusted user.
570 //
571 // Selector: addToCollectionAllowList(address) 67844fe6
572 function addToCollectionAllowList(address user) public {
573 require(false, stub_error);
574 user;
575 dummy = 0;
576 }
577
578 // Remove the user from the allowed list.
579 //
580 // @param user Address of a removed user.
581 //
582 // Selector: removeFromCollectionAllowList(address) 85c51acb
583 function removeFromCollectionAllowList(address user) public {
584 require(false, stub_error);
585 user;
586 dummy = 0;
587 }
588
589 // Switch permission for minting.
590 //
591 // @param mode Enable if "true".
592 //
593 // Selector: setCollectionMintMode(bool) 00018e84
594 function setCollectionMintMode(bool mode) public {
595 require(false, stub_error);
596 mode;
597 dummy = 0;
598 }
599
600 // Check that account is the owner or admin of the collection
601 //
602 // @param user account to verify
603 // @return "true" if account is the owner or admin
604 //
605 // Selector: verifyOwnerOrAdmin(address) c2282493
606 function verifyOwnerOrAdmin(address user) public view returns (bool) {
607 require(false, stub_error);
608 user;
609 dummy;
610 return false;
611 }
612
613 // Returns collection type
614 //
615 // @return `Fungible` or `NFT` or `ReFungible`
616 //
617 // Selector: uniqueCollectionType() d34b55b8
618 function uniqueCollectionType() public returns (string memory) {
619 require(false, stub_error);
620 dummy = 0;
621 return "";
622 }
623}
373624
374// Selector: 780e9d63625// Selector: 780e9d63
375contract ERC721Enumerable is Dummy, ERC165 {626contract ERC721Enumerable is Dummy, ERC165 {
413 }664 }
414}665}
415666
416// Selector: 7d9262e6667// Selector: 7c3bef89
417contract Collection is Dummy, ERC165 {
418 // Set collection property.
419 //
420 // @param key Property key.
421 // @param value Propery value.
422 //
423 // Selector: setCollectionProperty(string,bytes) 2f073f66
424 function setCollectionProperty(string memory key, bytes memory value)
425 public
426 {
427 require(false, stub_error);
428 key;
429 value;
430 dummy = 0;
431 }
432
433 // Delete collection property.
434 //
435 // @param key Property key.
436 //
437 // Selector: deleteCollectionProperty(string) 7b7debce
438 function deleteCollectionProperty(string memory key) public {
439 require(false, stub_error);
440 key;
441 dummy = 0;
442 }
443
444 // Get collection property.
445 //
446 // @dev Throws error if key not found.
447 //
448 // @param key Property key.
449 // @return bytes The property corresponding to the key.
450 //
451 // Selector: collectionProperty(string) cf24fd6d
452 function collectionProperty(string memory key)
453 public
454 view
455 returns (bytes memory)
456 {
457 require(false, stub_error);
458 key;
459 dummy;
460 return hex"";
461 }
462
463 // Set the sponsor of the collection.
464 //
465 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
466 //
467 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
468 //
469 // Selector: setCollectionSponsor(address) 7623402e
470 function setCollectionSponsor(address sponsor) public {
471 require(false, stub_error);
472 sponsor;
473 dummy = 0;
474 }
475
476 // Collection sponsorship confirmation.
477 //
478 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
479 //
480 // Selector: confirmCollectionSponsorship() 3c50e97a
481 function confirmCollectionSponsorship() public {
482 require(false, stub_error);
483 dummy = 0;
484 }
485
486 // Set limits for the collection.
487 // @dev Throws error if limit not found.
488 // @param limit Name of the limit. Valid names:
489 // "accountTokenOwnershipLimit",
490 // "sponsoredDataSize",
491 // "sponsoredDataRateLimit",
492 // "tokenLimit",
493 // "sponsorTransferTimeout",
494 // "sponsorApproveTimeout"
495 // @param value Value of the limit.
496 //
497 // Selector: setCollectionLimit(string,uint32) 6a3841db
498 function setCollectionLimit(string memory limit, uint32 value) public {
499 require(false, stub_error);
500 limit;
501 value;
502 dummy = 0;
503 }
504
505 // Set limits for the collection.
506 // @dev Throws error if limit not found.
507 // @param limit Name of the limit. Valid names:
508 // "ownerCanTransfer",
509 // "ownerCanDestroy",
510 // "transfersEnabled"
511 // @param value Value of the limit.
512 //
513 // Selector: setCollectionLimit(string,bool) 993b7fba
514 function setCollectionLimit(string memory limit, bool value) public {
515 require(false, stub_error);
516 limit;
517 value;
518 dummy = 0;
519 }
520
521 // Get contract address.
522 //
523 // Selector: contractAddress() f6b4dfb4
524 function contractAddress() public view returns (address) {
525 require(false, stub_error);
526 dummy;
527 return 0x0000000000000000000000000000000000000000;
528 }
529
530 // Add collection admin by substrate address.
531 // @param new_admin Substrate administrator address.
532 //
533 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
534 function addCollectionAdminSubstrate(uint256 newAdmin) public {
535 require(false, stub_error);
536 newAdmin;
537 dummy = 0;
538 }
539
540 // Remove collection admin by substrate address.
541 // @param admin Substrate administrator address.
542 //
543 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
544 function removeCollectionAdminSubstrate(uint256 admin) public {
545 require(false, stub_error);
546 admin;
547 dummy = 0;
548 }
549
550 // Add collection admin.
551 // @param new_admin Address of the added administrator.
552 //
553 // Selector: addCollectionAdmin(address) 92e462c7
554 function addCollectionAdmin(address newAdmin) public {
555 require(false, stub_error);
556 newAdmin;
557 dummy = 0;
558 }
559
560 // Remove collection admin.
561 //
562 // @param new_admin Address of the removed administrator.
563 //
564 // Selector: removeCollectionAdmin(address) fafd7b42
565 function removeCollectionAdmin(address admin) public {
566 require(false, stub_error);
567 admin;
568 dummy = 0;
569 }
570
571 // Toggle accessibility of collection nesting.
572 //
573 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
574 //
575 // Selector: setCollectionNesting(bool) 112d4586
576 function setCollectionNesting(bool enable) public {
577 require(false, stub_error);
578 enable;
579 dummy = 0;
580 }
581
582 // Toggle accessibility of collection nesting.
583 //
584 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
585 // @param collections Addresses of collections that will be available for nesting.
586 //
587 // Selector: setCollectionNesting(bool,address[]) 64872396
588 function setCollectionNesting(bool enable, address[] memory collections)
589 public
590 {
591 require(false, stub_error);
592 enable;
593 collections;
594 dummy = 0;
595 }
596
597 // Set the collection access method.
598 // @param mode Access mode
599 // 0 for Normal
600 // 1 for AllowList
601 //
602 // Selector: setCollectionAccess(uint8) 41835d4c
603 function setCollectionAccess(uint8 mode) public {
604 require(false, stub_error);
605 mode;
606 dummy = 0;
607 }
608
609 // Add the user to the allowed list.
610 //
611 // @param user Address of a trusted user.
612 //
613 // Selector: addToCollectionAllowList(address) 67844fe6
614 function addToCollectionAllowList(address user) public {
615 require(false, stub_error);
616 user;
617 dummy = 0;
618 }
619
620 // Remove the user from the allowed list.
621 //
622 // @param user Address of a removed user.
623 //
624 // Selector: removeFromCollectionAllowList(address) 85c51acb
625 function removeFromCollectionAllowList(address user) public {
626 require(false, stub_error);
627 user;
628 dummy = 0;
629 }
630
631 // Switch permission for minting.
632 //
633 // @param mode Enable if "true".
634 //
635 // Selector: setCollectionMintMode(bool) 00018e84
636 function setCollectionMintMode(bool mode) public {
637 require(false, stub_error);
638 mode;
639 dummy = 0;
640 }
641}
642
643// Selector: d74d154f
644contract ERC721UniqueExtensions is Dummy, ERC165 {668contract ERC721UniqueExtensions is Dummy, ERC165 {
645 // @notice Transfer ownership of an RFT669 // @notice Transfer ownership of an RFT
646 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`670 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`
720 return false;744 return false;
721 }745 }
746
747 // Returns EVM address for refungible token
748 //
749 // @param token ID of the token
750 //
751 // Selector: tokenContractAddress(uint256) ab76fac6
752 function tokenContractAddress(uint256 token) public view returns (address) {
753 require(false, stub_error);
754 token;
755 dummy;
756 return 0x0000000000000000000000000000000000000000;
757 }
722}758}
723759
724contract UniqueRefungible is760contract UniqueRefungible is
modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth
31 );31 );
32}32}
33
34// Selector: 042f1106
35contract ERC1633UniqueExtensions is Dummy, ERC165 {
36 // Selector: setParentNFT(address,uint256) 042f1106
37 function setParentNFT(address collection, uint256 nftId)
38 public
39 returns (bool)
40 {
41 require(false, stub_error);
42 collection;
43 nftId;
44 dummy = 0;
45 return false;
46 }
47}
48
49// Selector: 5755c3f2
50contract ERC1633 is Dummy, ERC165 {
51 // Selector: parentToken() 80a54001
52 function parentToken() public view returns (address) {
53 require(false, stub_error);
54 dummy;
55 return 0x0000000000000000000000000000000000000000;
56 }
57
58 // Selector: parentTokenId() d7f083f3
59 function parentTokenId() public view returns (uint256) {
60 require(false, stub_error);
61 dummy;
62 return 0;
63 }
64}
3365
34// Selector: 942e8b2266// Selector: 942e8b22
35contract ERC20 is Dummy, ERC165, ERC20Events {67contract ERC20 is Dummy, ERC165, ERC20Events {
214 Dummy,
215 ERC165,
216 ERC20,
217 ERC20UniqueExtensions,
218 ERC1633,
219 ERC1633UniqueExtensions
220{}
182221
modifiedpallets/refungible/src/weights.rsdiffbeforeafterboth
3//! Autogenerated weights for pallet_refungible3//! Autogenerated weights for pallet_refungible
4//!4//!
5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
6//! DATE: 2022-07-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`6//! DATE: 2022-08-01, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
88
9// Executed Command:9// Executed Command:
53 fn set_token_properties(b: u32, ) -> Weight;53 fn set_token_properties(b: u32, ) -> Weight;
54 fn delete_token_properties(b: u32, ) -> Weight;54 fn delete_token_properties(b: u32, ) -> Weight;
55 fn repartition_item() -> Weight;55 fn repartition_item() -> Weight;
56 fn set_parent_nft_unchecked() -> Weight;
57 fn token_owner() -> Weight;
56}58}
5759
58/// Weights for pallet_refungible using the Substrate node and recommended hardware.60/// Weights for pallet_refungible using the Substrate node and recommended hardware.
65 // Storage: Refungible TokenData (r:0 w:1)67 // Storage: Refungible TokenData (r:0 w:1)
66 // Storage: Refungible Owned (r:0 w:1)68 // Storage: Refungible Owned (r:0 w:1)
67 fn create_item() -> Weight {69 fn create_item() -> Weight {
68 (21_310_000 as Weight)70 (25_197_000 as Weight)
69 .saturating_add(T::DbWeight::get().reads(2 as Weight))71 .saturating_add(T::DbWeight::get().reads(2 as Weight))
70 .saturating_add(T::DbWeight::get().writes(6 as Weight))72 .saturating_add(T::DbWeight::get().writes(6 as Weight))
71 }73 }
76 // Storage: Refungible TokenData (r:0 w:4)78 // Storage: Refungible TokenData (r:0 w:4)
77 // Storage: Refungible Owned (r:0 w:4)79 // Storage: Refungible Owned (r:0 w:4)
78 fn create_multiple_items(b: u32, ) -> Weight {80 fn create_multiple_items(b: u32, ) -> Weight {
79 (9_552_000 as Weight)81 (10_852_000 as Weight)
80 // Standard Error: 2_00082 // Standard Error: 2_000
81 .saturating_add((7_056_000 as Weight).saturating_mul(b as Weight))83 .saturating_add((8_087_000 as Weight).saturating_mul(b as Weight))
82 .saturating_add(T::DbWeight::get().reads(2 as Weight))84 .saturating_add(T::DbWeight::get().reads(2 as Weight))
83 .saturating_add(T::DbWeight::get().writes(2 as Weight))85 .saturating_add(T::DbWeight::get().writes(2 as Weight))
84 .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))86 .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
90 // Storage: Refungible TokenData (r:0 w:4)92 // Storage: Refungible TokenData (r:0 w:4)
91 // Storage: Refungible Owned (r:0 w:4)93 // Storage: Refungible Owned (r:0 w:4)
92 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {94 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {
93 (4_857_000 as Weight)95 (9_978_000 as Weight)
94 // Standard Error: 2_00096 // Standard Error: 2_000
95 .saturating_add((9_838_000 as Weight).saturating_mul(b as Weight))97 .saturating_add((10_848_000 as Weight).saturating_mul(b as Weight))
96 .saturating_add(T::DbWeight::get().reads(1 as Weight))98 .saturating_add(T::DbWeight::get().reads(1 as Weight))
97 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))99 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
98 .saturating_add(T::DbWeight::get().writes(1 as Weight))100 .saturating_add(T::DbWeight::get().writes(1 as Weight))
105 // Storage: Refungible Balance (r:0 w:4)107 // Storage: Refungible Balance (r:0 w:4)
106 // Storage: Refungible Owned (r:0 w:4)108 // Storage: Refungible Owned (r:0 w:4)
107 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {109 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {
108 (11_335_000 as Weight)110 (15_419_000 as Weight)
109 // Standard Error: 2_000111 // Standard Error: 2_000
110 .saturating_add((6_784_000 as Weight).saturating_mul(b as Weight))112 .saturating_add((7_813_000 as Weight).saturating_mul(b as Weight))
111 .saturating_add(T::DbWeight::get().reads(1 as Weight))113 .saturating_add(T::DbWeight::get().reads(1 as Weight))
112 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))114 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
113 .saturating_add(T::DbWeight::get().writes(3 as Weight))115 .saturating_add(T::DbWeight::get().writes(3 as Weight))
118 // Storage: Refungible AccountBalance (r:1 w:1)120 // Storage: Refungible AccountBalance (r:1 w:1)
119 // Storage: Refungible Owned (r:0 w:1)121 // Storage: Refungible Owned (r:0 w:1)
120 fn burn_item_partial() -> Weight {122 fn burn_item_partial() -> Weight {
121 (21_239_000 as Weight)123 (25_578_000 as Weight)
122 .saturating_add(T::DbWeight::get().reads(3 as Weight))124 .saturating_add(T::DbWeight::get().reads(3 as Weight))
123 .saturating_add(T::DbWeight::get().writes(4 as Weight))125 .saturating_add(T::DbWeight::get().writes(4 as Weight))
124 }126 }
130 // Storage: Refungible Owned (r:0 w:1)132 // Storage: Refungible Owned (r:0 w:1)
131 // Storage: Refungible TokenProperties (r:0 w:1)133 // Storage: Refungible TokenProperties (r:0 w:1)
132 fn burn_item_fully() -> Weight {134 fn burn_item_fully() -> Weight {
133 (29_426_000 as Weight)135 (33_593_000 as Weight)
134 .saturating_add(T::DbWeight::get().reads(4 as Weight))136 .saturating_add(T::DbWeight::get().reads(4 as Weight))
135 .saturating_add(T::DbWeight::get().writes(7 as Weight))137 .saturating_add(T::DbWeight::get().writes(7 as Weight))
136 }138 }
137 // Storage: Refungible Balance (r:2 w:2)139 // Storage: Refungible Balance (r:2 w:2)
138 fn transfer_normal() -> Weight {140 fn transfer_normal() -> Weight {
139 (17_743_000 as Weight)141 (21_049_000 as Weight)
140 .saturating_add(T::DbWeight::get().reads(2 as Weight))142 .saturating_add(T::DbWeight::get().reads(2 as Weight))
141 .saturating_add(T::DbWeight::get().writes(2 as Weight))143 .saturating_add(T::DbWeight::get().writes(2 as Weight))
142 }144 }
143 // Storage: Refungible Balance (r:2 w:2)145 // Storage: Refungible Balance (r:2 w:2)
144 // Storage: Refungible AccountBalance (r:1 w:1)146 // Storage: Refungible AccountBalance (r:1 w:1)
145 // Storage: Refungible Owned (r:0 w:1)147 // Storage: Refungible Owned (r:0 w:1)
146 fn transfer_creating() -> Weight {148 fn transfer_creating() -> Weight {
147 (20_699_000 as Weight)149 (24_646_000 as Weight)
148 .saturating_add(T::DbWeight::get().reads(3 as Weight))150 .saturating_add(T::DbWeight::get().reads(3 as Weight))
149 .saturating_add(T::DbWeight::get().writes(4 as Weight))151 .saturating_add(T::DbWeight::get().writes(4 as Weight))
150 }152 }
151 // Storage: Refungible Balance (r:2 w:2)153 // Storage: Refungible Balance (r:2 w:2)
152 // Storage: Refungible AccountBalance (r:1 w:1)154 // Storage: Refungible AccountBalance (r:1 w:1)
153 // Storage: Refungible Owned (r:0 w:1)155 // Storage: Refungible Owned (r:0 w:1)
154 fn transfer_removing() -> Weight {156 fn transfer_removing() -> Weight {
155 (22_833_000 as Weight)157 (26_570_000 as Weight)
156 .saturating_add(T::DbWeight::get().reads(3 as Weight))158 .saturating_add(T::DbWeight::get().reads(3 as Weight))
157 .saturating_add(T::DbWeight::get().writes(4 as Weight))159 .saturating_add(T::DbWeight::get().writes(4 as Weight))
158 }160 }
159 // Storage: Refungible Balance (r:2 w:2)161 // Storage: Refungible Balance (r:2 w:2)
160 // Storage: Refungible AccountBalance (r:2 w:2)162 // Storage: Refungible AccountBalance (r:2 w:2)
161 // Storage: Refungible Owned (r:0 w:2)163 // Storage: Refungible Owned (r:0 w:2)
162 fn transfer_creating_removing() -> Weight {164 fn transfer_creating_removing() -> Weight {
163 (24_936_000 as Weight)165 (28_906_000 as Weight)
164 .saturating_add(T::DbWeight::get().reads(4 as Weight))166 .saturating_add(T::DbWeight::get().reads(4 as Weight))
165 .saturating_add(T::DbWeight::get().writes(6 as Weight))167 .saturating_add(T::DbWeight::get().writes(6 as Weight))
166 }168 }
167 // Storage: Refungible Balance (r:1 w:0)169 // Storage: Refungible Balance (r:1 w:0)
168 // Storage: Refungible Allowance (r:0 w:1)170 // Storage: Refungible Allowance (r:0 w:1)
169 fn approve() -> Weight {171 fn approve() -> Weight {
170 (13_446_000 as Weight)172 (16_451_000 as Weight)
171 .saturating_add(T::DbWeight::get().reads(1 as Weight))173 .saturating_add(T::DbWeight::get().reads(1 as Weight))
172 .saturating_add(T::DbWeight::get().writes(1 as Weight))174 .saturating_add(T::DbWeight::get().writes(1 as Weight))
173 }175 }
174 // Storage: Refungible Allowance (r:1 w:1)176 // Storage: Refungible Allowance (r:1 w:1)
175 // Storage: Refungible Balance (r:2 w:2)177 // Storage: Refungible Balance (r:2 w:2)
176 fn transfer_from_normal() -> Weight {178 fn transfer_from_normal() -> Weight {
177 (24_777_000 as Weight)179 (29_545_000 as Weight)
178 .saturating_add(T::DbWeight::get().reads(3 as Weight))180 .saturating_add(T::DbWeight::get().reads(3 as Weight))
179 .saturating_add(T::DbWeight::get().writes(3 as Weight))181 .saturating_add(T::DbWeight::get().writes(3 as Weight))
180 }182 }
183 // Storage: Refungible AccountBalance (r:1 w:1)185 // Storage: Refungible AccountBalance (r:1 w:1)
184 // Storage: Refungible Owned (r:0 w:1)186 // Storage: Refungible Owned (r:0 w:1)
185 fn transfer_from_creating() -> Weight {187 fn transfer_from_creating() -> Weight {
186 (28_483_000 as Weight)188 (33_392_000 as Weight)
187 .saturating_add(T::DbWeight::get().reads(4 as Weight))189 .saturating_add(T::DbWeight::get().reads(4 as Weight))
188 .saturating_add(T::DbWeight::get().writes(5 as Weight))190 .saturating_add(T::DbWeight::get().writes(5 as Weight))
189 }191 }
192 // Storage: Refungible AccountBalance (r:1 w:1)194 // Storage: Refungible AccountBalance (r:1 w:1)
193 // Storage: Refungible Owned (r:0 w:1)195 // Storage: Refungible Owned (r:0 w:1)
194 fn transfer_from_removing() -> Weight {196 fn transfer_from_removing() -> Weight {
195 (29_896_000 as Weight)197 (35_446_000 as Weight)
196 .saturating_add(T::DbWeight::get().reads(4 as Weight))198 .saturating_add(T::DbWeight::get().reads(4 as Weight))
197 .saturating_add(T::DbWeight::get().writes(5 as Weight))199 .saturating_add(T::DbWeight::get().writes(5 as Weight))
198 }200 }
201 // Storage: Refungible AccountBalance (r:2 w:2)203 // Storage: Refungible AccountBalance (r:2 w:2)
202 // Storage: Refungible Owned (r:0 w:2)204 // Storage: Refungible Owned (r:0 w:2)
203 fn transfer_from_creating_removing() -> Weight {205 fn transfer_from_creating_removing() -> Weight {
204 (32_070_000 as Weight)206 (37_762_000 as Weight)
205 .saturating_add(T::DbWeight::get().reads(5 as Weight))207 .saturating_add(T::DbWeight::get().reads(5 as Weight))
206 .saturating_add(T::DbWeight::get().writes(7 as Weight))208 .saturating_add(T::DbWeight::get().writes(7 as Weight))
207 }209 }
214 // Storage: Refungible Owned (r:0 w:1)216 // Storage: Refungible Owned (r:0 w:1)
215 // Storage: Refungible TokenProperties (r:0 w:1)217 // Storage: Refungible TokenProperties (r:0 w:1)
216 fn burn_from() -> Weight {218 fn burn_from() -> Weight {
217 (36_789_000 as Weight)219 (42_620_000 as Weight)
218 .saturating_add(T::DbWeight::get().reads(5 as Weight))220 .saturating_add(T::DbWeight::get().reads(5 as Weight))
219 .saturating_add(T::DbWeight::get().writes(8 as Weight))221 .saturating_add(T::DbWeight::get().writes(8 as Weight))
220 }222 }
221 // Storage: Common CollectionPropertyPermissions (r:1 w:1)223 // Storage: Common CollectionPropertyPermissions (r:1 w:1)
222 fn set_token_property_permissions(b: u32, ) -> Weight {224 fn set_token_property_permissions(b: u32, ) -> Weight {
223 (0 as Weight)225 (0 as Weight)
224 // Standard Error: 62_000226 // Standard Error: 65_000
225 .saturating_add((15_803_000 as Weight).saturating_mul(b as Weight))227 .saturating_add((16_513_000 as Weight).saturating_mul(b as Weight))
226 .saturating_add(T::DbWeight::get().reads(1 as Weight))228 .saturating_add(T::DbWeight::get().reads(1 as Weight))
227 .saturating_add(T::DbWeight::get().writes(1 as Weight))229 .saturating_add(T::DbWeight::get().writes(1 as Weight))
228 }230 }
229 // Storage: Common CollectionPropertyPermissions (r:1 w:0)231 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
230 // Storage: Refungible TokenProperties (r:1 w:1)232 // Storage: Refungible TokenProperties (r:1 w:1)
231 fn set_token_properties(b: u32, ) -> Weight {233 fn set_token_properties(b: u32, ) -> Weight {
232 (0 as Weight)234 (0 as Weight)
233 // Standard Error: 1_668_000235 // Standard Error: 1_583_000
234 .saturating_add((302_308_000 as Weight).saturating_mul(b as Weight))236 .saturating_add((291_392_000 as Weight).saturating_mul(b as Weight))
235 .saturating_add(T::DbWeight::get().reads(2 as Weight))237 .saturating_add(T::DbWeight::get().reads(2 as Weight))
236 .saturating_add(T::DbWeight::get().writes(1 as Weight))238 .saturating_add(T::DbWeight::get().writes(1 as Weight))
237 }239 }
238 // Storage: Common CollectionPropertyPermissions (r:1 w:0)240 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
239 // Storage: Refungible TokenProperties (r:1 w:1)241 // Storage: Refungible TokenProperties (r:1 w:1)
240 fn delete_token_properties(b: u32, ) -> Weight {242 fn delete_token_properties(b: u32, ) -> Weight {
241 (0 as Weight)243 (0 as Weight)
242 // Standard Error: 1_619_000244 // Standard Error: 1_699_000
243 .saturating_add((294_574_000 as Weight).saturating_mul(b as Weight))245 .saturating_add((293_270_000 as Weight).saturating_mul(b as Weight))
244 .saturating_add(T::DbWeight::get().reads(2 as Weight))246 .saturating_add(T::DbWeight::get().reads(2 as Weight))
245 .saturating_add(T::DbWeight::get().writes(1 as Weight))247 .saturating_add(T::DbWeight::get().writes(1 as Weight))
246 }248 }
247 // Storage: Refungible TotalSupply (r:1 w:1)249 // Storage: Refungible TotalSupply (r:1 w:1)
248 // Storage: Refungible Balance (r:1 w:1)250 // Storage: Refungible Balance (r:1 w:1)
249 fn repartition_item() -> Weight {251 fn repartition_item() -> Weight {
250 (8_325_000 as Weight)252 (19_206_000 as Weight)
251 .saturating_add(T::DbWeight::get().reads(2 as Weight))253 .saturating_add(T::DbWeight::get().reads(2 as Weight))
252 .saturating_add(T::DbWeight::get().writes(2 as Weight))254 .saturating_add(T::DbWeight::get().writes(2 as Weight))
253 }255 }
256 // Storage: Refungible Balance (r:1 w:0)
257 // Storage: Refungible TotalSupply (r:1 w:0)
258 // Storage: Refungible TokenProperties (r:1 w:1)
259 fn set_parent_nft_unchecked() -> Weight {
260 (10_189_000 as Weight)
261 .saturating_add(T::DbWeight::get().reads(3 as Weight))
262 .saturating_add(T::DbWeight::get().writes(1 as Weight))
263 }
264 // Storage: Refungible Balance (r:2 w:0)
265 fn token_owner() -> Weight {
266 (8_205_000 as Weight)
267 .saturating_add(T::DbWeight::get().reads(2 as Weight))
268 }
254}269}
255270
256// For backwards compatibility and tests271// For backwards compatibility and tests
262 // Storage: Refungible TokenData (r:0 w:1)277 // Storage: Refungible TokenData (r:0 w:1)
263 // Storage: Refungible Owned (r:0 w:1)278 // Storage: Refungible Owned (r:0 w:1)
264 fn create_item() -> Weight {279 fn create_item() -> Weight {
265 (21_310_000 as Weight)280 (25_197_000 as Weight)
266 .saturating_add(RocksDbWeight::get().reads(2 as Weight))281 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
267 .saturating_add(RocksDbWeight::get().writes(6 as Weight))282 .saturating_add(RocksDbWeight::get().writes(6 as Weight))
268 }283 }
273 // Storage: Refungible TokenData (r:0 w:4)288 // Storage: Refungible TokenData (r:0 w:4)
274 // Storage: Refungible Owned (r:0 w:4)289 // Storage: Refungible Owned (r:0 w:4)
275 fn create_multiple_items(b: u32, ) -> Weight {290 fn create_multiple_items(b: u32, ) -> Weight {
276 (9_552_000 as Weight)291 (10_852_000 as Weight)
277 // Standard Error: 2_000292 // Standard Error: 2_000
278 .saturating_add((7_056_000 as Weight).saturating_mul(b as Weight))293 .saturating_add((8_087_000 as Weight).saturating_mul(b as Weight))
279 .saturating_add(RocksDbWeight::get().reads(2 as Weight))294 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
280 .saturating_add(RocksDbWeight::get().writes(2 as Weight))295 .saturating_add(RocksDbWeight::get().writes(2 as Weight))
281 .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))296 .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
287 // Storage: Refungible TokenData (r:0 w:4)302 // Storage: Refungible TokenData (r:0 w:4)
288 // Storage: Refungible Owned (r:0 w:4)303 // Storage: Refungible Owned (r:0 w:4)
289 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {304 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {
290 (4_857_000 as Weight)305 (9_978_000 as Weight)
291 // Standard Error: 2_000306 // Standard Error: 2_000
292 .saturating_add((9_838_000 as Weight).saturating_mul(b as Weight))307 .saturating_add((10_848_000 as Weight).saturating_mul(b as Weight))
293 .saturating_add(RocksDbWeight::get().reads(1 as Weight))308 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
294 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))309 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
295 .saturating_add(RocksDbWeight::get().writes(1 as Weight))310 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
302 // Storage: Refungible Balance (r:0 w:4)317 // Storage: Refungible Balance (r:0 w:4)
303 // Storage: Refungible Owned (r:0 w:4)318 // Storage: Refungible Owned (r:0 w:4)
304 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {319 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {
305 (11_335_000 as Weight)320 (15_419_000 as Weight)
306 // Standard Error: 2_000321 // Standard Error: 2_000
307 .saturating_add((6_784_000 as Weight).saturating_mul(b as Weight))322 .saturating_add((7_813_000 as Weight).saturating_mul(b as Weight))
308 .saturating_add(RocksDbWeight::get().reads(1 as Weight))323 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
309 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))324 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
310 .saturating_add(RocksDbWeight::get().writes(3 as Weight))325 .saturating_add(RocksDbWeight::get().writes(3 as Weight))
315 // Storage: Refungible AccountBalance (r:1 w:1)330 // Storage: Refungible AccountBalance (r:1 w:1)
316 // Storage: Refungible Owned (r:0 w:1)331 // Storage: Refungible Owned (r:0 w:1)
317 fn burn_item_partial() -> Weight {332 fn burn_item_partial() -> Weight {
318 (21_239_000 as Weight)333 (25_578_000 as Weight)
319 .saturating_add(RocksDbWeight::get().reads(3 as Weight))334 .saturating_add(RocksDbWeight::get().reads(3 as Weight))
320 .saturating_add(RocksDbWeight::get().writes(4 as Weight))335 .saturating_add(RocksDbWeight::get().writes(4 as Weight))
321 }336 }
327 // Storage: Refungible Owned (r:0 w:1)342 // Storage: Refungible Owned (r:0 w:1)
328 // Storage: Refungible TokenProperties (r:0 w:1)343 // Storage: Refungible TokenProperties (r:0 w:1)
329 fn burn_item_fully() -> Weight {344 fn burn_item_fully() -> Weight {
330 (29_426_000 as Weight)345 (33_593_000 as Weight)
331 .saturating_add(RocksDbWeight::get().reads(4 as Weight))346 .saturating_add(RocksDbWeight::get().reads(4 as Weight))
332 .saturating_add(RocksDbWeight::get().writes(7 as Weight))347 .saturating_add(RocksDbWeight::get().writes(7 as Weight))
333 }348 }
334 // Storage: Refungible Balance (r:2 w:2)349 // Storage: Refungible Balance (r:2 w:2)
335 fn transfer_normal() -> Weight {350 fn transfer_normal() -> Weight {
336 (17_743_000 as Weight)351 (21_049_000 as Weight)
337 .saturating_add(RocksDbWeight::get().reads(2 as Weight))352 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
338 .saturating_add(RocksDbWeight::get().writes(2 as Weight))353 .saturating_add(RocksDbWeight::get().writes(2 as Weight))
339 }354 }
340 // Storage: Refungible Balance (r:2 w:2)355 // Storage: Refungible Balance (r:2 w:2)
341 // Storage: Refungible AccountBalance (r:1 w:1)356 // Storage: Refungible AccountBalance (r:1 w:1)
342 // Storage: Refungible Owned (r:0 w:1)357 // Storage: Refungible Owned (r:0 w:1)
343 fn transfer_creating() -> Weight {358 fn transfer_creating() -> Weight {
344 (20_699_000 as Weight)359 (24_646_000 as Weight)
345 .saturating_add(RocksDbWeight::get().reads(3 as Weight))360 .saturating_add(RocksDbWeight::get().reads(3 as Weight))
346 .saturating_add(RocksDbWeight::get().writes(4 as Weight))361 .saturating_add(RocksDbWeight::get().writes(4 as Weight))
347 }362 }
348 // Storage: Refungible Balance (r:2 w:2)363 // Storage: Refungible Balance (r:2 w:2)
349 // Storage: Refungible AccountBalance (r:1 w:1)364 // Storage: Refungible AccountBalance (r:1 w:1)
350 // Storage: Refungible Owned (r:0 w:1)365 // Storage: Refungible Owned (r:0 w:1)
351 fn transfer_removing() -> Weight {366 fn transfer_removing() -> Weight {
352 (22_833_000 as Weight)367 (26_570_000 as Weight)
353 .saturating_add(RocksDbWeight::get().reads(3 as Weight))368 .saturating_add(RocksDbWeight::get().reads(3 as Weight))
354 .saturating_add(RocksDbWeight::get().writes(4 as Weight))369 .saturating_add(RocksDbWeight::get().writes(4 as Weight))
355 }370 }
356 // Storage: Refungible Balance (r:2 w:2)371 // Storage: Refungible Balance (r:2 w:2)
357 // Storage: Refungible AccountBalance (r:2 w:2)372 // Storage: Refungible AccountBalance (r:2 w:2)
358 // Storage: Refungible Owned (r:0 w:2)373 // Storage: Refungible Owned (r:0 w:2)
359 fn transfer_creating_removing() -> Weight {374 fn transfer_creating_removing() -> Weight {
360 (24_936_000 as Weight)375 (28_906_000 as Weight)
361 .saturating_add(RocksDbWeight::get().reads(4 as Weight))376 .saturating_add(RocksDbWeight::get().reads(4 as Weight))
362 .saturating_add(RocksDbWeight::get().writes(6 as Weight))377 .saturating_add(RocksDbWeight::get().writes(6 as Weight))
363 }378 }
364 // Storage: Refungible Balance (r:1 w:0)379 // Storage: Refungible Balance (r:1 w:0)
365 // Storage: Refungible Allowance (r:0 w:1)380 // Storage: Refungible Allowance (r:0 w:1)
366 fn approve() -> Weight {381 fn approve() -> Weight {
367 (13_446_000 as Weight)382 (16_451_000 as Weight)
368 .saturating_add(RocksDbWeight::get().reads(1 as Weight))383 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
369 .saturating_add(RocksDbWeight::get().writes(1 as Weight))384 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
370 }385 }
371 // Storage: Refungible Allowance (r:1 w:1)386 // Storage: Refungible Allowance (r:1 w:1)
372 // Storage: Refungible Balance (r:2 w:2)387 // Storage: Refungible Balance (r:2 w:2)
373 fn transfer_from_normal() -> Weight {388 fn transfer_from_normal() -> Weight {
374 (24_777_000 as Weight)389 (29_545_000 as Weight)
375 .saturating_add(RocksDbWeight::get().reads(3 as Weight))390 .saturating_add(RocksDbWeight::get().reads(3 as Weight))
376 .saturating_add(RocksDbWeight::get().writes(3 as Weight))391 .saturating_add(RocksDbWeight::get().writes(3 as Weight))
377 }392 }
380 // Storage: Refungible AccountBalance (r:1 w:1)395 // Storage: Refungible AccountBalance (r:1 w:1)
381 // Storage: Refungible Owned (r:0 w:1)396 // Storage: Refungible Owned (r:0 w:1)
382 fn transfer_from_creating() -> Weight {397 fn transfer_from_creating() -> Weight {
383 (28_483_000 as Weight)398 (33_392_000 as Weight)
384 .saturating_add(RocksDbWeight::get().reads(4 as Weight))399 .saturating_add(RocksDbWeight::get().reads(4 as Weight))
385 .saturating_add(RocksDbWeight::get().writes(5 as Weight))400 .saturating_add(RocksDbWeight::get().writes(5 as Weight))
386 }401 }
389 // Storage: Refungible AccountBalance (r:1 w:1)404 // Storage: Refungible AccountBalance (r:1 w:1)
390 // Storage: Refungible Owned (r:0 w:1)405 // Storage: Refungible Owned (r:0 w:1)
391 fn transfer_from_removing() -> Weight {406 fn transfer_from_removing() -> Weight {
392 (29_896_000 as Weight)407 (35_446_000 as Weight)
393 .saturating_add(RocksDbWeight::get().reads(4 as Weight))408 .saturating_add(RocksDbWeight::get().reads(4 as Weight))
394 .saturating_add(RocksDbWeight::get().writes(5 as Weight))409 .saturating_add(RocksDbWeight::get().writes(5 as Weight))
395 }410 }
398 // Storage: Refungible AccountBalance (r:2 w:2)413 // Storage: Refungible AccountBalance (r:2 w:2)
399 // Storage: Refungible Owned (r:0 w:2)414 // Storage: Refungible Owned (r:0 w:2)
400 fn transfer_from_creating_removing() -> Weight {415 fn transfer_from_creating_removing() -> Weight {
401 (32_070_000 as Weight)416 (37_762_000 as Weight)
402 .saturating_add(RocksDbWeight::get().reads(5 as Weight))417 .saturating_add(RocksDbWeight::get().reads(5 as Weight))
403 .saturating_add(RocksDbWeight::get().writes(7 as Weight))418 .saturating_add(RocksDbWeight::get().writes(7 as Weight))
404 }419 }
411 // Storage: Refungible Owned (r:0 w:1)426 // Storage: Refungible Owned (r:0 w:1)
412 // Storage: Refungible TokenProperties (r:0 w:1)427 // Storage: Refungible TokenProperties (r:0 w:1)
413 fn burn_from() -> Weight {428 fn burn_from() -> Weight {
414 (36_789_000 as Weight)429 (42_620_000 as Weight)
415 .saturating_add(RocksDbWeight::get().reads(5 as Weight))430 .saturating_add(RocksDbWeight::get().reads(5 as Weight))
416 .saturating_add(RocksDbWeight::get().writes(8 as Weight))431 .saturating_add(RocksDbWeight::get().writes(8 as Weight))
417 }432 }
418 // Storage: Common CollectionPropertyPermissions (r:1 w:1)433 // Storage: Common CollectionPropertyPermissions (r:1 w:1)
419 fn set_token_property_permissions(b: u32, ) -> Weight {434 fn set_token_property_permissions(b: u32, ) -> Weight {
420 (0 as Weight)435 (0 as Weight)
421 // Standard Error: 62_000436 // Standard Error: 65_000
422 .saturating_add((15_803_000 as Weight).saturating_mul(b as Weight))437 .saturating_add((16_513_000 as Weight).saturating_mul(b as Weight))
423 .saturating_add(RocksDbWeight::get().reads(1 as Weight))438 .saturating_add(RocksDbWeight::get().reads(1 as Weight))
424 .saturating_add(RocksDbWeight::get().writes(1 as Weight))439 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
425 }440 }
426 // Storage: Common CollectionPropertyPermissions (r:1 w:0)441 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
427 // Storage: Refungible TokenProperties (r:1 w:1)442 // Storage: Refungible TokenProperties (r:1 w:1)
428 fn set_token_properties(b: u32, ) -> Weight {443 fn set_token_properties(b: u32, ) -> Weight {
429 (0 as Weight)444 (0 as Weight)
430 // Standard Error: 1_668_000445 // Standard Error: 1_583_000
431 .saturating_add((302_308_000 as Weight).saturating_mul(b as Weight))446 .saturating_add((291_392_000 as Weight).saturating_mul(b as Weight))
432 .saturating_add(RocksDbWeight::get().reads(2 as Weight))447 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
433 .saturating_add(RocksDbWeight::get().writes(1 as Weight))448 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
434 }449 }
435 // Storage: Common CollectionPropertyPermissions (r:1 w:0)450 // Storage: Common CollectionPropertyPermissions (r:1 w:0)
436 // Storage: Refungible TokenProperties (r:1 w:1)451 // Storage: Refungible TokenProperties (r:1 w:1)
437 fn delete_token_properties(b: u32, ) -> Weight {452 fn delete_token_properties(b: u32, ) -> Weight {
438 (0 as Weight)453 (0 as Weight)
439 // Standard Error: 1_619_000454 // Standard Error: 1_699_000
440 .saturating_add((294_574_000 as Weight).saturating_mul(b as Weight))455 .saturating_add((293_270_000 as Weight).saturating_mul(b as Weight))
441 .saturating_add(RocksDbWeight::get().reads(2 as Weight))456 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
442 .saturating_add(RocksDbWeight::get().writes(1 as Weight))457 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
443 }458 }
444 // Storage: Refungible TotalSupply (r:1 w:1)459 // Storage: Refungible TotalSupply (r:1 w:1)
445 // Storage: Refungible Balance (r:1 w:1)460 // Storage: Refungible Balance (r:1 w:1)
446 fn repartition_item() -> Weight {461 fn repartition_item() -> Weight {
447 (8_325_000 as Weight)462 (19_206_000 as Weight)
448 .saturating_add(RocksDbWeight::get().reads(2 as Weight))463 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
449 .saturating_add(RocksDbWeight::get().writes(2 as Weight))464 .saturating_add(RocksDbWeight::get().writes(2 as Weight))
450 }465 }
466 // Storage: Refungible Balance (r:1 w:0)
467 // Storage: Refungible TotalSupply (r:1 w:0)
468 // Storage: Refungible TokenProperties (r:1 w:1)
469 fn set_parent_nft_unchecked() -> Weight {
470 (10_189_000 as Weight)
471 .saturating_add(RocksDbWeight::get().reads(3 as Weight))
472 .saturating_add(RocksDbWeight::get().writes(1 as Weight))
473 }
474 // Storage: Refungible Balance (r:2 w:0)
475 fn token_owner() -> Weight {
476 (8_205_000 as Weight)
477 .saturating_add(RocksDbWeight::get().reads(2 as Weight))
478 }
451}479}
452480
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
17//! Implementation of CollectionHelpers contract.17//! Implementation of CollectionHelpers contract.
1818
19use core::marker::PhantomData;19use core::marker::PhantomData;
20use ethereum as _;
20use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};
22use frame_support::traits::Get;
21use ethereum as _;23use pallet_common::{
24 CollectionById, CollectionHandle,
25 dispatch::CollectionDispatch,
26 erc::{
27 CollectionHelpersEvents,
28 static_property::{key, value as property_value},
29 },
30 Pallet as PalletCommon,
31};
22use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};32use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
23use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId, PrecompileHandle};33use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
34use pallet_evm_coder_substrate::dispatch_to_evm;
24use up_data_structs::{35use up_data_structs::{
25 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,36 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,
26 CollectionMode, PropertyValue,37 CollectionMode, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,
27};38};
28use frame_support::traits::Get;39
29use pallet_common::{
30 CollectionById,
31 erc::{
32 static_property::{key, value as property_value},
33 CollectionHelpersEvents,
34 },
35 dispatch::CollectionDispatch,
36};
37use crate::{SelfWeightOf, Config, weights::WeightInfo};40use crate::{Config, SelfWeightOf, weights::WeightInfo};
3841
39use sp_std::vec::Vec;42use sp_std::{vec, vec::Vec};
40use alloc::format;43use alloc::format;
4144
42/// See [`CollectionHelpersCall`]45/// See [`CollectionHelpersCall`]
151 Ok(data)154 Ok(data)
152}155}
156
157fn parent_nft_property_permissions() -> PropertyKeyPermission {
158 PropertyKeyPermission {
159 key: key::parent_nft(),
160 permission: PropertyPermission {
161 mutable: false,
162 collection_admin: false,
163 token_owner: true,
164 },
165 }
166}
167
168fn create_refungible_collection_internal<
169 T: Config + pallet_nonfungible::Config + pallet_refungible::Config,
170>(
171 caller: caller,
172 name: string,
173 description: string,
174 token_prefix: string,
175 base_uri: string,
176 add_properties: bool,
177) -> Result<address> {
178 let (caller, name, description, token_prefix, base_uri_value) =
179 convert_data::<T>(caller, name, description, token_prefix, base_uri)?;
180 let data = make_data::<T>(
181 name,
182 CollectionMode::ReFungible,
183 description,
184 token_prefix,
185 base_uri_value,
186 add_properties,
187 )?;
188
189 let collection_id = T::CollectionDispatch::create(caller.clone(), data)
190 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
191
192 let handle = <CollectionHandle<T>>::try_get(collection_id).map_err(dispatch_to_evm::<T>)?;
193 <PalletCommon<T>>::set_scoped_token_property_permissions(
194 &handle,
195 &caller,
196 PropertyScope::Eth,
197 vec![parent_nft_property_permissions()],
198 )
199 .map_err(dispatch_to_evm::<T>)?;
200
201 let address = pallet_common::eth::collection_id_to_address(collection_id);
202 Ok(address)
203}
153204
154/// @title Contract, which allows users to operate with collections205/// @title Contract, which allows users to operate with collections
155#[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]206#[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]
216267
217 #[weight(<SelfWeightOf<T>>::create_collection())]268 #[weight(<SelfWeightOf<T>>::create_collection())]
218 fn create_refungible_collection(269 fn create_refungible_collection(
219 &self,270 &mut self,
220 caller: caller,271 caller: caller,
221 name: string,272 name: string,
222 description: string,273 description: string,
223 token_prefix: string,274 token_prefix: string,
224 ) -> Result<address> {275 ) -> Result<address> {
225 let (caller, name, description, token_prefix, _base_uri) =
226 convert_data::<T>(caller, name, description, token_prefix, "".into())?;
227 let data = make_data::<T>(276 create_refungible_collection_internal::<T>(
277 caller,
228 name,278 name,
229 CollectionMode::ReFungible,
230 description,279 description,
231 token_prefix,280 token_prefix,
232 Default::default(),281 Default::default(),
233 false,282 false,
234 )?;283 )
235 let collection_id = T::CollectionDispatch::create(caller, data)
236 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
237
238 let address = pallet_common::eth::collection_id_to_address(collection_id);
239 Ok(address)
240 }284 }
241285
242 #[weight(<SelfWeightOf<T>>::create_collection())]286 #[weight(<SelfWeightOf<T>>::create_collection())]
249 token_prefix: string,293 token_prefix: string,
250 base_uri: string,294 base_uri: string,
251 ) -> Result<address> {295 ) -> Result<address> {
252 let (caller, name, description, token_prefix, base_uri_value) =
253 convert_data::<T>(caller, name, description, token_prefix, base_uri)?;296 create_refungible_collection_internal::<T>(
254 let data = make_data::<T>(297 caller,
255 name,298 name,
256 CollectionMode::NFT,299 description,
257 description,300 token_prefix,
258 token_prefix,301 base_uri,
259 base_uri_value,302 true,
260 true,303 )
261 )?;
262 let collection_id = T::CollectionDispatch::create(caller, data)
263 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
264
265 let address = pallet_common::eth::collection_id_to_address(collection_id);
266 Ok(address)
267 }304 }
268305
269 /// Check if a collection exists306 /// Check if a collection exists
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth
72 string memory name,72 string memory name,
73 string memory description,73 string memory description,
74 string memory tokenPrefix74 string memory tokenPrefix
75 ) public view returns (address) {75 ) public returns (address) {
76 require(false, stub_error);76 require(false, stub_error);
77 name;77 name;
78 description;78 description;
79 tokenPrefix;79 tokenPrefix;
80 dummy;80 dummy = 0;
81 return 0x0000000000000000000000000000000000000000;81 return 0x0000000000000000000000000000000000000000;
82 }82 }
8383
addedprimitives/common/Cargo.tomldiffbeforeafterboth

no changes

addedprimitives/common/src/constants.rsdiffbeforeafterboth

no changes

addedprimitives/common/src/lib.rsdiffbeforeafterboth

no changes

addedprimitives/common/src/types.rsdiffbeforeafterboth

no changes

modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
1050pub enum PropertyScope {1050pub enum PropertyScope {
1051 None,1051 None,
1052 Rmrk,1052 Rmrk,
1053 Eth,
1053}1054}
10541055
1055impl PropertyScope {1056impl PropertyScope {
1058 let scope_str: &[u8] = match self {1059 let scope_str: &[u8] = match self {
1059 Self::None => return Ok(key),1060 Self::None => return Ok(key),
1060 Self::Rmrk => b"rmrk",1061 Self::Rmrk => b"rmrk",
1062 Self::Eth => b"eth",
1061 };1063 };
10621064
1063 [scope_str, b":", key.as_slice()]1065 [scope_str, b":", key.as_slice()]
deletedruntime/common/Cargo.tomldiffbeforeafterboth

no changes

addedruntime/common/config/ethereum.rsdiffbeforeafterboth

no changes

addedruntime/common/config/mod.rsdiffbeforeafterboth

no changes

addedruntime/common/config/orml.rsdiffbeforeafterboth

no changes

addedruntime/common/config/pallets/mod.rsdiffbeforeafterboth

no changes

addedruntime/common/config/pallets/rmrk.rsdiffbeforeafterboth

no changes

addedruntime/common/config/pallets/scheduler.rsdiffbeforeafterboth

no changes

addedruntime/common/config/parachain.rsdiffbeforeafterboth

no changes

addedruntime/common/config/sponsoring.rsdiffbeforeafterboth

no changes

addedruntime/common/config/substrate.rsdiffbeforeafterboth

no changes

addedruntime/common/config/xcm.rsdiffbeforeafterboth

no changes

addedruntime/common/constants.rsdiffbeforeafterboth

no changes

addedruntime/common/construct_runtime/mod.rsdiffbeforeafterboth

no changes

addedruntime/common/construct_runtime/util.rsdiffbeforeafterboth

no changes

addedruntime/common/dispatch.rsdiffbeforeafterboth

no changes

addedruntime/common/ethereum/mod.rsdiffbeforeafterboth

no changes

addedruntime/common/ethereum/self_contained_call.rsdiffbeforeafterboth

no changes

addedruntime/common/ethereum/sponsoring.rsdiffbeforeafterboth

no changes

addedruntime/common/ethereum/transaction_converter.rsdiffbeforeafterboth

no changes

addedruntime/common/instance.rsdiffbeforeafterboth

no changes

addedruntime/common/mod.rsdiffbeforeafterboth

no changes

addedruntime/common/runtime_apis.rsdiffbeforeafterboth

no changes

addedruntime/common/scheduler.rsdiffbeforeafterboth

no changes

addedruntime/common/sponsoring.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/constants.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/dispatch.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/eth_sponsoring.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/lib.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/runtime_apis.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/sponsoring.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/types.rsdiffbeforeafterboth

no changes

deletedruntime/common/src/weights.rsdiffbeforeafterboth

no changes

addedruntime/common/weights.rsdiffbeforeafterboth

no changes

modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
16targets = ['x86_64-unknown-linux-gnu']16targets = ['x86_64-unknown-linux-gnu']
1717
18[features]18[features]
19default = ['std']19default = ['std', 'opal-runtime']
20runtime-benchmarks = [20runtime-benchmarks = [
21 'hex-literal',21 'hex-literal',
22 'frame-benchmarking',22 'frame-benchmarking',
113 'xcm/std',113 'xcm/std',
114 'xcm-builder/std',114 'xcm-builder/std',
115 'xcm-executor/std',115 'xcm-executor/std',
116 'unique-runtime-common/std',116 'up-common/std',
117 'rmrk-rpc/std',117 'rmrk-rpc/std',
118 'evm-coder/std',
119 'up-sponsorship/std',
118120
119 "orml-vesting/std",121 "orml-vesting/std",
120]122]
121limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']123limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
124opal-runtime = ['refungible', 'scheduler', 'rmrk']
125
126refungible = []
127scheduler = []
128rmrk = []
122129
123################################################################################130################################################################################
124# Substrate Dependencies131# Substrate Dependencies
396403
397[dependencies]404[dependencies]
398log = { version = "0.4.16", default-features = false }405log = { version = "0.4.16", default-features = false }
399unique-runtime-common = { path = "../common", default-features = false }406up-common = { path = "../../primitives/common", default-features = false }
400scale-info = { version = "2.0.1", default-features = false, features = [407scale-info = { version = "2.0.1", default-features = false, features = [
401 "derive",408 "derive",
402] }409] }
426pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }433pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
427fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }434fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
428fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }435fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
436evm-coder = { default-features = false, path = '../../crates/evm-coder' }
437up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
429438
430################################################################################439################################################################################
431# Build Dependencies440# Build Dependencies
modifiedruntime/opal/src/lib.rsdiffbeforeafterboth
25#[cfg(feature = "std")]25#[cfg(feature = "std")]
26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
2727
28use sp_api::impl_runtime_apis;28use frame_support::parameter_types;
29
29use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};30use sp_version::RuntimeVersion;
30use sp_runtime::DispatchError;
31use fp_self_contained::*;
32// #[cfg(any(feature = "std", test))]
33// pub use sp_runtime::BuildStorage;
34
35use sp_runtime::{31use sp_runtime::create_runtime_str;
36 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
37 traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},
38 transaction_validity::{TransactionSource, TransactionValidity},
39 ApplyExtrinsicResult, RuntimeAppPublic,
40};
4132
42use sp_std::prelude::*;33use up_common::types::*;
4334
44#[cfg(feature = "std")]35#[path = "../../common/mod.rs"]
45use sp_version::NativeVersion;36mod runtime_common;
46use sp_version::RuntimeVersion;37
47pub use pallet_transaction_payment::{38pub use runtime_common::*;
48 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,
49};
50// A few exports that help ease life for downstream crates.
51pub use pallet_balances::Call as BalancesCall;
52pub use pallet_evm::{
53 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
54 OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
55};
56pub use frame_support::{
57 construct_runtime, match_types,
58 dispatch::DispatchResult,
59 PalletId, parameter_types, StorageValue, ConsensusEngineId,
60 traits::{
61 tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
62 Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
63 OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,
64 },
65 weights::{
66 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
67 DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
68 WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
69 WeightToFee,
70 },
71};
72use pallet_unique_scheduler::DispatchCall;
73use up_data_structs::{
74 CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
75 CollectionStats, RpcCollection,
76 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
77 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
78 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
79 RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
80};
81
82// use pallet_contracts::weights::WeightInfo;
83// #[cfg(any(feature = "std", test))]
84use frame_system::{
85 self as frame_system, EnsureRoot, EnsureSigned,
86 limits::{BlockWeights, BlockLength},
87};
88use sp_arithmetic::{
89 traits::{BaseArithmetic, Unsigned},
90};
91use smallvec::smallvec;
92// use scale_info::TypeInfo;
93use codec::{Encode, Decode};
94use fp_rpc::TransactionStatus;
95use sp_runtime::{
96 traits::{
97 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,
98 Saturating, CheckedConversion,
99 },
100 generic::Era,
101 transaction_validity::TransactionValidityError,
102 DispatchErrorWithPostInfo, SaturatedConversion,
103};
104
105// pub use pallet_timestamp::Call as TimestampCall;
106pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
107
108// Polkadot imports
109use pallet_xcm::XcmPassthrough;
110use polkadot_parachain::primitives::Sibling;
111use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
112use xcm_builder::{
113 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
114 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
115 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
116 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
117 ParentIsPreset,
118};
119use xcm_executor::{Config, XcmExecutor, Assets};
120use sp_std::{cmp::Ordering, marker::PhantomData};
121
122use xcm::latest::{
123 // Xcm,
124 AssetId::{Concrete},
125 Fungibility::Fungible as XcmFungible,
126 MultiAsset,
127 Error as XcmError,
128};
129use xcm_executor::traits::{MatchesFungible, WeightTrader};
130//use xcm_executor::traits::MatchesFungible;
131
132use unique_runtime_common::{
133 impl_common_runtime_apis,
134 types::*,
135 constants::*,
136 dispatch::{CollectionDispatchT, CollectionDispatch},
137 sponsoring::UniqueSponsorshipHandler,
138 eth_sponsoring::UniqueEthSponsorshipHandler,
139 weights::CommonWeights,
140};
14139
142pub const RUNTIME_NAME: &str = "opal";40pub const RUNTIME_NAME: &str = "opal";
143pub const TOKEN_SYMBOL: &str = "OPL";41pub const TOKEN_SYMBOL: &str = "OPL";
144
145type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
146
147impl RuntimeInstance for Runtime {
148 type CrossAccountId = self::CrossAccountId;
149 type TransactionConverter = self::TransactionConverter;
150
151 fn get_transaction_converter() -> TransactionConverter {
152 TransactionConverter
153 }
154}
155
156/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
157/// never know...
158pub type AccountIndex = u32;
159
160/// Balance of an account.
161pub type Balance = u128;
162
163/// Index of a transaction in the chain.
164pub type Index = u32;
165
166/// A hash of some data used by the chain.
167pub type Hash = sp_core::H256;
168
169/// Digest item type.
170pub type DigestItem = generic::DigestItem;
171
172/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
173/// the specifics of the runtime. They can then be made to be agnostic over specific formats
174/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
175/// to even the core data structures.
176pub mod opaque {
177 use sp_std::prelude::*;
178 use sp_runtime::impl_opaque_keys;
179 use super::Aura;
180
181 pub use unique_runtime_common::types::*;
182
183 impl_opaque_keys! {
184 pub struct SessionKeys {
185 pub aura: Aura,
186 }
187 }
188}
18942
190/// This runtime version.43/// This runtime version.
191pub const VERSION: RuntimeVersion = RuntimeVersion {44pub const VERSION: RuntimeVersion = RuntimeVersion {
199 state_version: 0,52 state_version: 0,
200};53};
201
202#[derive(codec::Encode, codec::Decode)]
203pub enum XCMPMessage<XAccountId, XBalance> {
204 /// Transfer tokens to the given account from the Parachain account.
205 TransferToken(XAccountId, XBalance),
206}
207
208/// The version information used to identify this runtime when compiled natively.
209#[cfg(feature = "std")]
210pub fn native_version() -> NativeVersion {
211 NativeVersion {
212 runtime_version: VERSION,
213 can_author_with: Default::default(),
214 }
215}
216
217type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
218
219pub struct DealWithFees;
220impl OnUnbalanced<NegativeImbalance> for DealWithFees {
221 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
222 if let Some(fees) = fees_then_tips.next() {
223 // for fees, 100% to treasury
224 let mut split = fees.ration(100, 0);
225 if let Some(tips) = fees_then_tips.next() {
226 // for tips, if any, 100% to treasury
227 tips.ration_merge_into(100, 0, &mut split);
228 }
229 Treasury::on_unbalanced(split.0);
230 // Author::on_unbalanced(split.1);
231 }
232 }
233}
23454
235parameter_types! {55parameter_types! {
236 pub const BlockHashCount: BlockNumber = 2400;
237 pub RuntimeBlockLength: BlockLength =
238 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
239 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
240 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
241 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
242 .base_block(BlockExecutionWeight::get())
243 .for_class(DispatchClass::all(), |weights| {
244 weights.base_extrinsic = ExtrinsicBaseWeight::get();
245 })
246 .for_class(DispatchClass::Normal, |weights| {
247 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
248 })
249 .for_class(DispatchClass::Operational, |weights| {
250 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
251 // Operational transactions have some extra reserved space, so that they
252 // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
253 weights.reserved = Some(
254 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
255 );
256 })
257 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
258 .build_or_panic();
259 pub const Version: RuntimeVersion = VERSION;56 pub const Version: RuntimeVersion = VERSION;
260 pub const SS58Prefix: u8 = 42;57 pub const SS58Prefix: u8 = 42;
261}
262
263parameter_types! {
264 pub const ChainId: u64 = 8882;58 pub const ChainId: u64 = 8882;
265}59}
266
267pub struct FixedFee;
268impl FeeCalculator for FixedFee {
269 fn min_gas_price() -> (U256, u64) {
270 (MIN_GAS_PRICE.into(), 0)
271 }
272}
273
274// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
275// (contract, which only writes a lot of data),
276// approximating on top of our real store write weight
277parameter_types! {
278 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
279 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
280 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
281}
282
283/// Limiting EVM execution to 50% of block for substrate users and management tasks
284/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
285/// scheduled fairly
286const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
287parameter_types! {
288 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
289}
290
291pub enum FixedGasWeightMapping {}
292impl GasWeightMapping for FixedGasWeightMapping {
293 fn gas_to_weight(gas: u64) -> Weight {
294 gas.saturating_mul(WeightPerGas::get())
295 }
296 fn weight_to_gas(weight: Weight) -> u64 {
297 weight / WeightPerGas::get()
298 }
299}
300
301impl pallet_evm::account::Config for Runtime {
302 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
303 type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
304 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
305}
306
307impl pallet_evm::Config for Runtime {
308 type BlockGasLimit = BlockGasLimit;
309 type FeeCalculator = FixedFee;
310 type GasWeightMapping = FixedGasWeightMapping;
311 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
312 type CallOrigin = EnsureAddressTruncated<Self>;
313 type WithdrawOrigin = EnsureAddressTruncated<Self>;
314 type AddressMapping = HashedAddressMapping<Self::Hashing>;
315 type PrecompilesType = ();
316 type PrecompilesValue = ();
317 type Currency = Balances;
318 type Event = Event;
319 type OnMethodCall = (
320 pallet_evm_migration::OnMethodCall<Self>,
321 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
322 CollectionDispatchT<Self>,
323 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
324 );
325 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
326 type ChainId = ChainId;
327 type Runner = pallet_evm::runner::stack::Runner<Self>;
328 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
329 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
330 type FindAuthor = EthereumFindAuthor<Aura>;
331}
332
333impl pallet_evm_migration::Config for Runtime {
334 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
335}
336
337pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
338impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
339 fn find_author<'a, I>(digests: I) -> Option<H160>
340 where
341 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
342 {
343 if let Some(author_index) = F::find_author(digests) {
344 let authority_id = Aura::authorities()[author_index as usize].clone();
345 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
346 }
347 None
348 }
349}
350
351impl pallet_ethereum::Config for Runtime {
352 type Event = Event;
353 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
354}
355
356impl pallet_randomness_collective_flip::Config for Runtime {}
357
358impl frame_system::Config for Runtime {
359 /// The data to be stored in an account.
360 type AccountData = pallet_balances::AccountData<Balance>;
361 /// The identifier used to distinguish between accounts.
362 type AccountId = AccountId;
363 /// The basic call filter to use in dispatchable.
364 type BaseCallFilter = Everything;
365 /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
366 type BlockHashCount = BlockHashCount;
367 /// The maximum length of a block (in bytes).
368 type BlockLength = RuntimeBlockLength;
369 /// The index type for blocks.
370 type BlockNumber = BlockNumber;
371 /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
372 type BlockWeights = RuntimeBlockWeights;
373 /// The aggregated dispatch type that is available for extrinsics.
374 type Call = Call;
375 /// The weight of database operations that the runtime can invoke.
376 type DbWeight = RocksDbWeight;
377 /// The ubiquitous event type.
378 type Event = Event;
379 /// The type for hashing blocks and tries.
380 type Hash = Hash;
381 /// The hashing algorithm used.
382 type Hashing = BlakeTwo256;
383 /// The header type.
384 type Header = generic::Header<BlockNumber, BlakeTwo256>;
385 /// The index type for storing how many extrinsics an account has signed.
386 type Index = Index;
387 /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
388 type Lookup = AccountIdLookup<AccountId, ()>;
389 /// What to do if an account is fully reaped from the system.
390 type OnKilledAccount = ();
391 /// What to do if a new account is created.
392 type OnNewAccount = ();
393 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
394 /// The ubiquitous origin type.
395 type Origin = Origin;
396 /// This type is being generated by `construct_runtime!`.
397 type PalletInfo = PalletInfo;
398 /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
399 type SS58Prefix = SS58Prefix;
400 /// Weight information for the extrinsics of this pallet.
401 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
402 /// Version of the runtime.
403 type Version = Version;
404 type MaxConsumers = ConstU32<16>;
405}
406
407parameter_types! {
408 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
409}
410
411impl pallet_timestamp::Config for Runtime {
412 /// A timestamp: milliseconds since the unix epoch.
413 type Moment = u64;
414 type OnTimestampSet = ();
415 type MinimumPeriod = MinimumPeriod;
416 type WeightInfo = ();
417}
418
419parameter_types! {
420 // pub const ExistentialDeposit: u128 = 500;
421 pub const ExistentialDeposit: u128 = 0;
422 pub const MaxLocks: u32 = 50;
423 pub const MaxReserves: u32 = 50;
424}
425
426impl pallet_balances::Config for Runtime {
427 type MaxLocks = MaxLocks;
428 type MaxReserves = MaxReserves;
429 type ReserveIdentifier = [u8; 16];
430 /// The type for recording an account's balance.
431 type Balance = Balance;
432 /// The ubiquitous event type.
433 type Event = Event;
434 type DustRemoval = Treasury;
435 type ExistentialDeposit = ExistentialDeposit;
436 type AccountStore = System;
437 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
438}
439
440pub const fn deposit(items: u32, bytes: u32) -> Balance {
441 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE
442}
443
444/*
445parameter_types! {
446 pub TombstoneDeposit: Balance = deposit(
447 1,
448 sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,
449 );
450 pub DepositPerContract: Balance = TombstoneDeposit::get();
451 pub const DepositPerStorageByte: Balance = deposit(0, 1);
452 pub const DepositPerStorageItem: Balance = deposit(1, 0);
453 pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
454 pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;
455 pub const SignedClaimHandicap: u32 = 2;
456 pub const MaxDepth: u32 = 32;
457 pub const MaxValueSize: u32 = 16 * 1024;
458 pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb
459 // The lazy deletion runs inside on_initialize.
460 pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
461 RuntimeBlockWeights::get().max_block;
462 // The weight needed for decoding the queue should be less or equal than a fifth
463 // of the overall weight dedicated to the lazy deletion.
464 pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
465 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
466 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
467 )) / 5) as u32;
468 pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
469}
470
471impl pallet_contracts::Config for Runtime {
472 type Time = Timestamp;
473 type Randomness = RandomnessCollectiveFlip;
474 type Currency = Balances;
475 type Event = Event;
476 type RentPayment = ();
477 type SignedClaimHandicap = SignedClaimHandicap;
478 type TombstoneDeposit = TombstoneDeposit;
479 type DepositPerContract = DepositPerContract;
480 type DepositPerStorageByte = DepositPerStorageByte;
481 type DepositPerStorageItem = DepositPerStorageItem;
482 type RentFraction = RentFraction;
483 type SurchargeReward = SurchargeReward;
484 type WeightPrice = pallet_transaction_payment::Pallet<Self>;
485 type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
486 type ChainExtension = NFTExtension;
487 type DeletionQueueDepth = DeletionQueueDepth;
488 type DeletionWeightLimit = DeletionWeightLimit;
489 type Schedule = Schedule;
490 type CallStack = [pallet_contracts::Frame<Self>; 31];
491}
492*/
493
494parameter_types! {
495 /// This value increases the priority of `Operational` transactions by adding
496 /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
497 pub const OperationalFeeMultiplier: u8 = 5;
498}
499
500/// Linear implementor of `WeightToFeePolynomial`
501pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
502
503impl<T> WeightToFeePolynomial for LinearFee<T>
504where
505 T: BaseArithmetic + From<u32> + Copy + Unsigned,
506{
507 type Balance = T;
508
509 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
510 smallvec!(WeightToFeeCoefficient {
511 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
512 coeff_frac: Perbill::zero(),
513 negative: false,
514 degree: 1,
515 })
516 }
517}
518
519impl pallet_transaction_payment::Config for Runtime {
520 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
521 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
522 type OperationalFeeMultiplier = OperationalFeeMultiplier;
523 type WeightToFee = LinearFee<Balance>;
524 type FeeMultiplierUpdate = ();
525}
526
527parameter_types! {
528 pub const ProposalBond: Permill = Permill::from_percent(5);
529 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
530 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
531 pub const SpendPeriod: BlockNumber = 5 * MINUTES;
532 pub const Burn: Permill = Permill::from_percent(0);
533 pub const TipCountdown: BlockNumber = 1 * DAYS;
534 pub const TipFindersFee: Percent = Percent::from_percent(20);
535 pub const TipReportDepositBase: Balance = 1 * UNIQUE;
536 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
537 pub const BountyDepositBase: Balance = 1 * UNIQUE;
538 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
539 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
540 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
541 pub const MaximumReasonLength: u32 = 16384;
542 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
543 pub const BountyValueMinimum: Balance = 5 * UNIQUE;
544 pub const MaxApprovals: u32 = 100;
545}
546
547impl pallet_treasury::Config for Runtime {
548 type PalletId = TreasuryModuleId;
549 type Currency = Balances;
550 type ApproveOrigin = EnsureRoot<AccountId>;
551 type RejectOrigin = EnsureRoot<AccountId>;
552 type Event = Event;
553 type OnSlash = ();
554 type ProposalBond = ProposalBond;
555 type ProposalBondMinimum = ProposalBondMinimum;
556 type ProposalBondMaximum = ProposalBondMaximum;
557 type SpendPeriod = SpendPeriod;
558 type Burn = Burn;
559 type BurnDestination = ();
560 type SpendFunds = ();
561 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
562 type MaxApprovals = MaxApprovals;
563}
564
565impl pallet_sudo::Config for Runtime {
566 type Event = Event;
567 type Call = Call;
568}
569
570pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
571
572impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
573 for RelayChainBlockNumberProvider<T>
574{
575 type BlockNumber = BlockNumber;
576
577 fn current_block_number() -> Self::BlockNumber {
578 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
579 .map(|d| d.relay_parent_number)
580 .unwrap_or_default()
581 }
582}
583
584parameter_types! {
585 pub const MinVestedTransfer: Balance = 10 * UNIQUE;
586 pub const MaxVestingSchedules: u32 = 28;
587}
588
589impl orml_vesting::Config for Runtime {
590 type Event = Event;
591 type Currency = pallet_balances::Pallet<Runtime>;
592 type MinVestedTransfer = MinVestedTransfer;
593 type VestedTransferOrigin = EnsureSigned<AccountId>;
594 type WeightInfo = ();
595 type MaxVestingSchedules = MaxVestingSchedules;
596 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
597}
598
599parameter_types! {
600 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
601 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
602}
603
604impl cumulus_pallet_parachain_system::Config for Runtime {
605 type Event = Event;
606 type SelfParaId = parachain_info::Pallet<Self>;
607 type OnSystemEvent = ();
608 // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
609 // MaxDownwardMessageWeight,
610 // XcmExecutor<XcmConfig>,
611 // Call,
612 // >;
613 type OutboundXcmpMessageSource = XcmpQueue;
614 type DmpMessageHandler = DmpQueue;
615 type ReservedDmpWeight = ReservedDmpWeight;
616 type ReservedXcmpWeight = ReservedXcmpWeight;
617 type XcmpMessageHandler = XcmpQueue;
618}
619
620impl parachain_info::Config for Runtime {}
621
622impl cumulus_pallet_aura_ext::Config for Runtime {}
623
624parameter_types! {
625 pub const RelayLocation: MultiLocation = MultiLocation::parent();
626 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
627 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
628 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
629}
630
631/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
632/// when determining ownership of accounts for asset transacting and when attempting to use XCM
633/// `Transact` in order to determine the dispatch Origin.
634pub type LocationToAccountId = (
635 // The parent (Relay-chain) origin converts to the default `AccountId`.
636 ParentIsPreset<AccountId>,
637 // Sibling parachain origins convert to AccountId via the `ParaId::into`.
638 SiblingParachainConvertsVia<Sibling, AccountId>,
639 // Straight up local `AccountId32` origins just alias directly to `AccountId`.
640 AccountId32Aliases<RelayNetwork, AccountId>,
641);
642
643pub struct OnlySelfCurrency;
644impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
645 fn matches_fungible(a: &MultiAsset) -> Option<B> {
646 match (&a.id, &a.fun) {
647 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
648 _ => None,
649 }
650 }
651}
652
653/// Means for transacting assets on this chain.
654pub type LocalAssetTransactor = CurrencyAdapter<
655 // Use this currency:
656 Balances,
657 // Use this currency when it is a fungible asset matching the given location or name:
658 OnlySelfCurrency,
659 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
660 LocationToAccountId,
661 // Our chain's account ID type (we can't get away without mentioning it explicitly):
662 AccountId,
663 // We don't track any teleports.
664 (),
665>;
666
667/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
668/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
669/// biases the kind of local `Origin` it will become.
670pub type XcmOriginToTransactDispatchOrigin = (
671 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
672 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
673 // foreign chains who want to have a local sovereign account on this chain which they control.
674 SovereignSignedViaLocation<LocationToAccountId, Origin>,
675 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
676 // recognised.
677 RelayChainAsNative<RelayOrigin, Origin>,
678 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
679 // recognised.
680 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
681 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
682 // transaction from the Root origin.
683 ParentAsSuperuser<Origin>,
684 // Native signed account converter; this just converts an `AccountId32` origin into a normal
685 // `Origin::Signed` origin of the same 32-byte value.
686 SignedAccountId32AsNative<RelayNetwork, Origin>,
687 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
688 XcmPassthrough<Origin>,
689);
690
691parameter_types! {
692 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
693 pub UnitWeightCost: Weight = 1_000_000;
694 // 1200 UNIQUEs buy 1 second of weight.
695 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
696 pub const MaxInstructions: u32 = 100;
697 pub const MaxAuthorities: u32 = 100_000;
698}
699
700match_types! {
701 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
702 MultiLocation { parents: 1, interior: Here } |
703 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
704 };
705}
706
707pub type Barrier = (
708 TakeWeightCredit,
709 AllowTopLevelPaidExecutionFrom<Everything>,
710 // ^^^ Parent & its unit plurality gets free execution
711);
712
713pub struct UsingOnlySelfCurrencyComponents<
714 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
715 AssetId: Get<MultiLocation>,
716 AccountId,
717 Currency: CurrencyT<AccountId>,
718 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
719>(
720 Weight,
721 Currency::Balance,
722 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
723);
724impl<
725 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
726 AssetId: Get<MultiLocation>,
727 AccountId,
728 Currency: CurrencyT<AccountId>,
729 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
730 > WeightTrader
731 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
732{
733 fn new() -> Self {
734 Self(0, Zero::zero(), PhantomData)
735 }
736
737 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
738 let amount = WeightToFee::weight_to_fee(&weight);
739 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
740
741 // location to this parachain through relay chain
742 let option1: xcm::v1::AssetId = Concrete(MultiLocation {
743 parents: 1,
744 interior: X1(Parachain(ParachainInfo::parachain_id().into())),
745 });
746 // direct location
747 let option2: xcm::v1::AssetId = Concrete(MultiLocation {
748 parents: 0,
749 interior: Here,
750 });
751
752 let required = if payment.fungible.contains_key(&option1) {
753 (option1, u128_amount).into()
754 } else if payment.fungible.contains_key(&option2) {
755 (option2, u128_amount).into()
756 } else {
757 (Concrete(MultiLocation::default()), u128_amount).into()
758 };
759
760 let unused = payment
761 .checked_sub(required)
762 .map_err(|_| XcmError::TooExpensive)?;
763 self.0 = self.0.saturating_add(weight);
764 self.1 = self.1.saturating_add(amount);
765 Ok(unused)
766 }
767
768 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
769 let weight = weight.min(self.0);
770 let amount = WeightToFee::weight_to_fee(&weight);
771 self.0 -= weight;
772 self.1 = self.1.saturating_sub(amount);
773 let amount: u128 = amount.saturated_into();
774 if amount > 0 {
775 Some((AssetId::get(), amount).into())
776 } else {
777 None
778 }
779 }
780}
781impl<
782 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
783 AssetId: Get<MultiLocation>,
784 AccountId,
785 Currency: CurrencyT<AccountId>,
786 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
787 > Drop
788 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
789{
790 fn drop(&mut self) {
791 OnUnbalanced::on_unbalanced(Currency::issue(self.1));
792 }
793}
794
795pub struct XcmConfig;
796impl Config for XcmConfig {
797 type Call = Call;
798 type XcmSender = XcmRouter;
799 // How to withdraw and deposit an asset.
800 type AssetTransactor = LocalAssetTransactor;
801 type OriginConverter = XcmOriginToTransactDispatchOrigin;
802 type IsReserve = NativeAsset;
803 type IsTeleporter = (); // Teleportation is disabled
804 type LocationInverter = LocationInverter<Ancestry>;
805 type Barrier = Barrier;
806 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
807 type Trader =
808 UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
809 type ResponseHandler = (); // Don't handle responses for now.
810 type SubscriptionService = PolkadotXcm;
811
812 type AssetTrap = PolkadotXcm;
813 type AssetClaims = PolkadotXcm;
814}
815
816// parameter_types! {
817// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
818// }
819
820/// No local origins on this chain are allowed to dispatch XCM sends/executions.
821pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
822
823/// The means for routing XCM messages which are not for local execution into the right message
824/// queues.
825pub type XcmRouter = (
826 // Two routers - use UMP to communicate with the relay chain:
827 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
828 // ..and XCMP to communicate with the sibling chains.
829 XcmpQueue,
830);
831
832impl pallet_evm_coder_substrate::Config for Runtime {}
833
834impl pallet_xcm::Config for Runtime {
835 type Event = Event;
836 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
837 type XcmRouter = XcmRouter;
838 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
839 type XcmExecuteFilter = Everything;
840 type XcmExecutor = XcmExecutor<XcmConfig>;
841 type XcmTeleportFilter = Everything;
842 type XcmReserveTransferFilter = Everything;
843 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
844 type LocationInverter = LocationInverter<Ancestry>;
845 type Origin = Origin;
846 type Call = Call;
847 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
848 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
849}
850
851impl cumulus_pallet_xcm::Config for Runtime {
852 type Event = Event;
853 type XcmExecutor = XcmExecutor<XcmConfig>;
854}
855
856impl cumulus_pallet_xcmp_queue::Config for Runtime {
857 type WeightInfo = ();
858 type Event = Event;
859 type XcmExecutor = XcmExecutor<XcmConfig>;
860 type ChannelInfo = ParachainSystem;
861 type VersionWrapper = ();
862 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
863 type ControllerOrigin = EnsureRoot<AccountId>;
864 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
865}
866
867impl cumulus_pallet_dmp_queue::Config for Runtime {
868 type Event = Event;
869 type XcmExecutor = XcmExecutor<XcmConfig>;
870 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
871}
872
873impl pallet_aura::Config for Runtime {
874 type AuthorityId = AuraId;
875 type DisabledValidators = ();
876 type MaxAuthorities = MaxAuthorities;
877}
878
879parameter_types! {
880 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
881 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
882}
883
884impl pallet_common::Config for Runtime {
885 type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
886 type Event = Event;
887 type Currency = Balances;
888 type CollectionCreationPrice = CollectionCreationPrice;
889 type TreasuryAccountId = TreasuryAccountId;
890 type CollectionDispatch = CollectionDispatchT<Self>;
891
892 type EvmTokenAddressMapping = EvmTokenAddressMapping;
893 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
894 type ContractAddress = EvmCollectionHelpersAddress;
895}
896
897impl pallet_structure::Config for Runtime {
898 type Event = Event;
899 type Call = Call;
900 type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
901}
902
903impl pallet_fungible::Config for Runtime {
904 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
905}
906impl pallet_refungible::Config for Runtime {
907 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
908}
909impl pallet_nonfungible::Config for Runtime {
910 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
911}
912
913impl pallet_proxy_rmrk_core::Config for Runtime {
914 type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
915 type Event = Event;
916}
917
918impl pallet_proxy_rmrk_equip::Config for Runtime {
919 type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
920 type Event = Event;
921}
922
923impl pallet_unique::Config for Runtime {
924 type Event = Event;
925 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
926 type CommonWeightInfo = CommonWeights<Self>;
927 type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
928}
929
930parameter_types! {
931 pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
932}
933
934/// Used for the pallet inflation
935impl pallet_inflation::Config for Runtime {
936 type Currency = Balances;
937 type TreasuryAccountId = TreasuryAccountId;
938 type InflationBlockInterval = InflationBlockInterval;
939 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
940}
941
942parameter_types! {
943 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
944 RuntimeBlockWeights::get().max_block;
945 pub const MaxScheduledPerBlock: u32 = 50;
946}
947
948type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
949use frame_support::traits::NamedReservableCurrency;
950
951fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
952 (
953 frame_system::CheckSpecVersion::<Runtime>::new(),
954 frame_system::CheckGenesis::<Runtime>::new(),
955 frame_system::CheckEra::<Runtime>::from(Era::Immortal),
956 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
957 from,
958 )),
959 frame_system::CheckWeight::<Runtime>::new(),
960 // sponsoring transaction logic
961 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
962 )
963}
964
965pub struct SchedulerPaymentExecutor;
966impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
967 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
968where
969 <T as frame_system::Config>::Call: Member
970 + Dispatchable<Origin = Origin, Info = DispatchInfo>
971 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
972 + GetDispatchInfo
973 + From<frame_system::Call<Runtime>>,
974 SelfContainedSignedInfo: Send + Sync + 'static,
975 Call: From<<T as frame_system::Config>::Call>
976 + From<<T as pallet_unique_scheduler::Config>::Call>
977 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
978 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
979{
980 fn dispatch_call(
981 signer: <T as frame_system::Config>::AccountId,
982 call: <T as pallet_unique_scheduler::Config>::Call,
983 ) -> Result<
984 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
985 TransactionValidityError,
986 > {
987 let dispatch_info = call.get_dispatch_info();
988 let extrinsic = fp_self_contained::CheckedExtrinsic::<
989 AccountId,
990 Call,
991 SignedExtraScheduler,
992 SelfContainedSignedInfo,
993 > {
994 signed:
995 CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
996 signer.clone().into(),
997 get_signed_extras(signer.into()),
998 ),
999 function: call.into(),
1000 };
1001
1002 extrinsic.apply::<Runtime>(&dispatch_info, 0)
1003 }
1004
1005 fn reserve_balance(
1006 id: [u8; 16],
1007 sponsor: <T as frame_system::Config>::AccountId,
1008 call: <T as pallet_unique_scheduler::Config>::Call,
1009 count: u32,
1010 ) -> Result<(), DispatchError> {
1011 let dispatch_info = call.get_dispatch_info();
1012 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
1013 .saturating_mul(count.into());
1014
1015 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
1016 &id,
1017 &(sponsor.into()),
1018 weight,
1019 )
1020 }
1021
1022 fn pay_for_call(
1023 id: [u8; 16],
1024 sponsor: <T as frame_system::Config>::AccountId,
1025 call: <T as pallet_unique_scheduler::Config>::Call,
1026 ) -> Result<u128, DispatchError> {
1027 let dispatch_info = call.get_dispatch_info();
1028 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
1029 Ok(
1030 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
1031 &id,
1032 &(sponsor.into()),
1033 weight,
1034 ),
1035 )
1036 }
1037
1038 fn cancel_reserve(
1039 id: [u8; 16],
1040 sponsor: <T as frame_system::Config>::AccountId,
1041 ) -> Result<u128, DispatchError> {
1042 Ok(
1043 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
1044 &id,
1045 &(sponsor.into()),
1046 u128::MAX,
1047 ),
1048 )
1049 }
1050}
1051
1052parameter_types! {
1053 pub const NoPreimagePostponement: Option<u32> = Some(10);
1054 pub const Preimage: Option<u32> = Some(10);
1055}
1056
1057/// Used the compare the privilege of an origin inside the scheduler.
1058pub struct OriginPrivilegeCmp;
1059
1060impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
1061 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
1062 Some(Ordering::Equal)
1063 }
1064}
1065
1066impl pallet_unique_scheduler::Config for Runtime {
1067 type Event = Event;
1068 type Origin = Origin;
1069 type Currency = Balances;
1070 type PalletsOrigin = OriginCaller;
1071 type Call = Call;
1072 type MaximumWeight = MaximumSchedulerWeight;
1073 type ScheduleOrigin = EnsureSigned<AccountId>;
1074 type MaxScheduledPerBlock = MaxScheduledPerBlock;
1075 type WeightInfo = ();
1076 type CallExecutor = SchedulerPaymentExecutor;
1077 type OriginPrivilegeCmp = OriginPrivilegeCmp;
1078 type PreimageProvider = ();
1079 type NoPreimagePostponement = NoPreimagePostponement;
1080}
1081
1082type EvmSponsorshipHandler = (
1083 UniqueEthSponsorshipHandler<Runtime>,
1084 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
1085);
1086
1087type SponsorshipHandler = (
1088 UniqueSponsorshipHandler<Runtime>,
1089 //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
1090 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
1091);
1092
1093impl pallet_evm_transaction_payment::Config for Runtime {
1094 type EvmSponsorshipHandler = EvmSponsorshipHandler;
1095 type Currency = Balances;
1096}
1097
1098impl pallet_charge_transaction::Config for Runtime {
1099 type SponsorshipHandler = SponsorshipHandler;
1100}
1101
1102// impl pallet_contract_helpers::Config for Runtime {
1103// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
1104// }
1105
1106parameter_types! {
1107 // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
1108 pub const HelpersContractAddress: H160 = H160([
1109 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
1110 ]);
1111
1112 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
1113 pub const EvmCollectionHelpersAddress: H160 = H160([
1114 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
1115 ]);
1116}
1117
1118impl pallet_evm_contract_helpers::Config for Runtime {
1119 type ContractAddress = HelpersContractAddress;
1120 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
1121}
112260
1123construct_runtime!(61construct_runtime!(opal);
1124 pub enum Runtime where
1125 Block = Block,
1126 NodeBlock = opaque::Block,
1127 UncheckedExtrinsic = UncheckedExtrinsic
1128 {
1129 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
1130 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
1131
1132 Aura: pallet_aura::{Pallet, Config<T>} = 22,
1133 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
1134
1135 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
1136 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
1137 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
1138 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
1139 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
1140 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
1141 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
1142 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
1143 // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
1144 // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
1145
1146 // XCM helpers.
1147 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
1148 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
1149 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
1150 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
1151
1152 // Unique Pallets
1153 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
1154 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
1155 Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
1156 // free = 63
1157 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
1158 // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
1159 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
1160 Fungible: pallet_fungible::{Pallet, Storage} = 67,
1161 Refungible: pallet_refungible::{Pallet, Storage} = 68,
1162 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
1163 Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
1164 RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
1165 RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
1166
1167 // Frontier
1168 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
1169 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
1170
1171 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
1172 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
1173 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
1174 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
1175 }
1176);
1177
1178pub struct TransactionConverter;
1179
1180impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
1181 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
1182 UncheckedExtrinsic::new_unsigned(
1183 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1184 )
1185 }
1186}
1187
1188impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
1189 fn convert_transaction(
1190 &self,
1191 transaction: pallet_ethereum::Transaction,
1192 ) -> opaque::UncheckedExtrinsic {
1193 let extrinsic = UncheckedExtrinsic::new_unsigned(
1194 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1195 );
1196 let encoded = extrinsic.encode();
1197 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
1198 .expect("Encoded extrinsic is always valid")
1199 }
1200}
1201
1202/// The address format for describing accounts.
1203pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1204/// Block header type as expected by this runtime.
1205pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1206/// Block type as expected by this runtime.
1207pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1208/// A Block signed with a Justification
1209pub type SignedBlock = generic::SignedBlock<Block>;
1210/// BlockId type as expected by this runtime.
1211pub type BlockId = generic::BlockId<Block>;
1212/// The SignedExtension to the basic transaction logic.
1213pub type SignedExtra = (
1214 frame_system::CheckSpecVersion<Runtime>,
1215 // system::CheckTxVersion<Runtime>,
1216 frame_system::CheckGenesis<Runtime>,
1217 frame_system::CheckEra<Runtime>,
1218 frame_system::CheckNonce<Runtime>,
1219 frame_system::CheckWeight<Runtime>,
1220 ChargeTransactionPayment,
1221 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
1222 pallet_ethereum::FakeTransactionFinalizer<Runtime>,
1223);
1224pub type SignedExtraScheduler = (
1225 frame_system::CheckSpecVersion<Runtime>,
1226 frame_system::CheckGenesis<Runtime>,
1227 frame_system::CheckEra<Runtime>,
1228 frame_system::CheckNonce<Runtime>,
1229 frame_system::CheckWeight<Runtime>,
1230);
1231/// Unchecked extrinsic type as expected by this runtime.
1232pub type UncheckedExtrinsic =
1233 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
1234/// Extrinsic type that has already been checked.
1235pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
1236/// Executive: handles dispatch to the various modules.
1237pub type Executive = frame_executive::Executive<
1238 Runtime,
1239 Block,
1240 frame_system::ChainContext<Runtime>,
1241 Runtime,
1242 AllPalletsReversedWithSystemFirst,
1243>;
1244
1245impl_opaque_keys! {
1246 pub struct SessionKeys {
1247 pub aura: Aura,
1248 }
1249}
1250
1251impl fp_self_contained::SelfContainedCall for Call {
1252 type SignedInfo = H160;
1253
1254 fn is_self_contained(&self) -> bool {
1255 match self {
1256 Call::Ethereum(call) => call.is_self_contained(),
1257 _ => false,
1258 }
1259 }
1260
1261 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
1262 match self {
1263 Call::Ethereum(call) => call.check_self_contained(),
1264 _ => None,
1265 }
1266 }
1267
1268 fn validate_self_contained(
1269 &self,
1270 info: &Self::SignedInfo,
1271 dispatch_info: &DispatchInfoOf<Call>,
1272 len: usize,
1273 ) -> Option<TransactionValidity> {
1274 match self {
1275 Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
1276 _ => None,
1277 }
1278 }
1279
1280 fn pre_dispatch_self_contained(
1281 &self,
1282 info: &Self::SignedInfo,
1283 ) -> Option<Result<(), TransactionValidityError>> {
1284 match self {
1285 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
1286 _ => None,
1287 }
1288 }
1289
1290 fn apply_self_contained(
1291 self,
1292 info: Self::SignedInfo,
1293 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
1294 match self {
1295 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
1296 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
1297 )),
1298 _ => None,
1299 }
1300 }
1301}
1302
1303macro_rules! dispatch_unique_runtime {
1304 ($collection:ident.$method:ident($($name:ident),*)) => {{
1305 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
1306 let dispatch = collection.as_dyn();
1307
1308 Ok::<_, DispatchError>(dispatch.$method($($name),*))
1309 }};
1310}
131162
1312impl_common_runtime_apis! {63impl_common_runtime_apis!();
1313 #![custom_apis]
1314
1315 impl rmrk_rpc::RmrkApi<
1316 Block,
1317 AccountId,
1318 RmrkCollectionInfo<AccountId>,
1319 RmrkInstanceInfo<AccountId>,
1320 RmrkResourceInfo,
1321 RmrkPropertyInfo,
1322 RmrkBaseInfo<AccountId>,
1323 RmrkPartType,
1324 RmrkTheme
1325 > for Runtime {
1326 fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {
1327 pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>()
1328 }
1329
1330 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
1331 pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id)
1332 }
1333
1334 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
1335 pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id)
1336 }
1337
1338 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
1339 pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id)
1340 }
1341
1342 fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
1343 pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id)
1344 }
1345
1346 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
1347 pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys)
1348 }
1349
1350 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
1351 pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys)
1352 }
1353
1354 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
1355 pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id)
1356 }
1357
1358 fn nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
1359 pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id)
1360 }
1361
1362 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
1363 pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id)
1364 }
1365
1366 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
1367 pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id)
1368 }
1369
1370 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
1371 pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id)
1372 }
1373
1374 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
1375 pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys)
1376 }
1377 }
1378}
1379
1380struct CheckInherents;
1381
1382impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
1383 fn check_inherents(
1384 block: &Block,
1385 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
1386 ) -> sp_inherents::CheckInherentsResult {
1387 let relay_chain_slot = relay_state_proof
1388 .read_slot()
1389 .expect("Could not read the relay chain slot from the proof");
1390
1391 let inherent_data =
1392 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
1393 relay_chain_slot,
1394 sp_std::time::Duration::from_secs(6),
1395 )
1396 .create_inherent_data()
1397 .expect("Could not create the timestamp inherent data");
1398
1399 inherent_data.check_extrinsics(block)
1400 }
1401}
140264
1403cumulus_pallet_parachain_system::register_validate_block!(65cumulus_pallet_parachain_system::register_validate_block!(
1404 Runtime = Runtime,66 Runtime = Runtime,
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
16targets = ['x86_64-unknown-linux-gnu']16targets = ['x86_64-unknown-linux-gnu']
1717
18[features]18[features]
19default = ['std']19default = ['std', 'quartz-runtime']
20runtime-benchmarks = [20runtime-benchmarks = [
21 'hex-literal',21 'hex-literal',
22 'frame-benchmarking',22 'frame-benchmarking',
113 'xcm/std',113 'xcm/std',
114 'xcm-builder/std',114 'xcm-builder/std',
115 'xcm-executor/std',115 'xcm-executor/std',
116 'unique-runtime-common/std',116 'up-common/std',
117117
118 "orml-vesting/std",118 "orml-vesting/std",
119]119]
120limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']120limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
121quartz-runtime = []
122
123refungible = []
124scheduler = []
125rmrk = []
121126
122################################################################################127################################################################################
123# Substrate Dependencies128# Substrate Dependencies
403408
404[dependencies]409[dependencies]
405log = { version = "0.4.16", default-features = false }410log = { version = "0.4.16", default-features = false }
406unique-runtime-common = { path = "../common", default-features = false }411up-common = { path = "../../primitives/common", default-features = false }
407scale-info = { version = "2.0.1", default-features = false, features = [412scale-info = { version = "2.0.1", default-features = false, features = [
408 "derive",413 "derive",
409] }414] }
432pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }437pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
433fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }438fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
434fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }439fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
440evm-coder = { default-features = false, path = '../../crates/evm-coder' }
441up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
435442
436################################################################################443################################################################################
437# Build Dependencies444# Build Dependencies
modifiedruntime/quartz/src/lib.rsdiffbeforeafterboth
25#[cfg(feature = "std")]25#[cfg(feature = "std")]
26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
2727
28use sp_api::impl_runtime_apis;28use frame_support::parameter_types;
29
29use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};30use sp_version::RuntimeVersion;
30use sp_runtime::DispatchError;
31use fp_self_contained::*;
32// #[cfg(any(feature = "std", test))]
33// pub use sp_runtime::BuildStorage;
34
35use sp_runtime::{31use sp_runtime::create_runtime_str;
36 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
37 traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},
38 transaction_validity::{TransactionSource, TransactionValidity},
39 ApplyExtrinsicResult, RuntimeAppPublic,
40};
4132
42use sp_std::prelude::*;33use up_common::types::*;
4334
44#[cfg(feature = "std")]35#[path = "../../common/mod.rs"]
45use sp_version::NativeVersion;36mod runtime_common;
46use sp_version::RuntimeVersion;37
47pub use pallet_transaction_payment::{38pub use runtime_common::*;
48 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,
49};
50// A few exports that help ease life for downstream crates.
51pub use pallet_balances::Call as BalancesCall;
52pub use pallet_evm::{
53 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
54 OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
55};
56pub use frame_support::{
57 construct_runtime, match_types,
58 dispatch::DispatchResult,
59 PalletId, parameter_types, StorageValue, ConsensusEngineId,
60 traits::{
61 tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
62 Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
63 OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,
64 },
65 weights::{
66 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
67 DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
68 WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
69 WeightToFee,
70 },
71};
72use pallet_unique_scheduler::DispatchCall;
73use up_data_structs::{
74 CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
75 CollectionStats, RpcCollection,
76 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
77 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
78 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
79 RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
80};
81
82// use pallet_contracts::weights::WeightInfo;
83// #[cfg(any(feature = "std", test))]
84use frame_system::{
85 self as frame_system, EnsureRoot, EnsureSigned,
86 limits::{BlockWeights, BlockLength},
87};
88use sp_arithmetic::{
89 traits::{BaseArithmetic, Unsigned},
90};
91use smallvec::smallvec;
92use codec::{Encode, Decode};
93use fp_rpc::TransactionStatus;
94use sp_runtime::{
95 traits::{
96 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,
97 Saturating, CheckedConversion,
98 },
99 generic::Era,
100 transaction_validity::TransactionValidityError,
101 DispatchErrorWithPostInfo, SaturatedConversion,
102};
103
104// pub use pallet_timestamp::Call as TimestampCall;
105pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
106
107// Polkadot imports
108use pallet_xcm::XcmPassthrough;
109use polkadot_parachain::primitives::Sibling;
110use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
111use xcm_builder::{
112 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
113 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
114 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
115 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
116 ParentIsPreset,
117};
118use xcm_executor::{Config, XcmExecutor, Assets};
119use sp_std::{cmp::Ordering, marker::PhantomData};
120
121use xcm::latest::{
122 // Xcm,
123 AssetId::{Concrete},
124 Fungibility::Fungible as XcmFungible,
125 MultiAsset,
126 Error as XcmError,
127};
128use xcm_executor::traits::{MatchesFungible, WeightTrader};
129
130use unique_runtime_common::{
131 impl_common_runtime_apis,
132 types::*,
133 constants::*,
134 dispatch::{CollectionDispatchT, CollectionDispatch},
135 sponsoring::UniqueSponsorshipHandler,
136 eth_sponsoring::UniqueEthSponsorshipHandler,
137 weights::CommonWeights,
138};
13939
140pub const RUNTIME_NAME: &str = "quartz";40pub const RUNTIME_NAME: &str = "quartz";
141pub const TOKEN_SYMBOL: &str = "QTZ";41pub const TOKEN_SYMBOL: &str = "QTZ";
142
143type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
144
145impl RuntimeInstance for Runtime {
146 type CrossAccountId = self::CrossAccountId;
147
148 type TransactionConverter = self::TransactionConverter;
149
150 fn get_transaction_converter() -> TransactionConverter {
151 TransactionConverter
152 }
153}
154
155/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
156/// never know...
157pub type AccountIndex = u32;
158
159/// Balance of an account.
160pub type Balance = u128;
161
162/// Index of a transaction in the chain.
163pub type Index = u32;
164
165/// A hash of some data used by the chain.
166pub type Hash = sp_core::H256;
167
168/// Digest item type.
169pub type DigestItem = generic::DigestItem;
170
171/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
172/// the specifics of the runtime. They can then be made to be agnostic over specific formats
173/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
174/// to even the core data structures.
175pub mod opaque {
176 use sp_std::prelude::*;
177 use sp_runtime::impl_opaque_keys;
178 use super::Aura;
179
180 pub use unique_runtime_common::types::*;
181
182 impl_opaque_keys! {
183 pub struct SessionKeys {
184 pub aura: Aura,
185 }
186 }
187}
18842
189/// This runtime version.43/// This runtime version.
190pub const VERSION: RuntimeVersion = RuntimeVersion {44pub const VERSION: RuntimeVersion = RuntimeVersion {
198 state_version: 0,52 state_version: 0,
199};53};
200
201#[derive(codec::Encode, codec::Decode)]
202pub enum XCMPMessage<XAccountId, XBalance> {
203 /// Transfer tokens to the given account from the Parachain account.
204 TransferToken(XAccountId, XBalance),
205}
206
207/// The version information used to identify this runtime when compiled natively.
208#[cfg(feature = "std")]
209pub fn native_version() -> NativeVersion {
210 NativeVersion {
211 runtime_version: VERSION,
212 can_author_with: Default::default(),
213 }
214}
215
216type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
217
218pub struct DealWithFees;
219impl OnUnbalanced<NegativeImbalance> for DealWithFees {
220 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
221 if let Some(fees) = fees_then_tips.next() {
222 // for fees, 100% to treasury
223 let mut split = fees.ration(100, 0);
224 if let Some(tips) = fees_then_tips.next() {
225 // for tips, if any, 100% to treasury
226 tips.ration_merge_into(100, 0, &mut split);
227 }
228 Treasury::on_unbalanced(split.0);
229 // Author::on_unbalanced(split.1);
230 }
231 }
232}
23354
234parameter_types! {55parameter_types! {
235 pub const BlockHashCount: BlockNumber = 2400;
236 pub RuntimeBlockLength: BlockLength =
237 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
238 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
239 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
240 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
241 .base_block(BlockExecutionWeight::get())
242 .for_class(DispatchClass::all(), |weights| {
243 weights.base_extrinsic = ExtrinsicBaseWeight::get();
244 })
245 .for_class(DispatchClass::Normal, |weights| {
246 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
247 })
248 .for_class(DispatchClass::Operational, |weights| {
249 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
250 // Operational transactions have some extra reserved space, so that they
251 // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
252 weights.reserved = Some(
253 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
254 );
255 })
256 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
257 .build_or_panic();
258 pub const Version: RuntimeVersion = VERSION;56 pub const Version: RuntimeVersion = VERSION;
259 pub const SS58Prefix: u8 = 255;57 pub const SS58Prefix: u8 = 255;
260}
261
262parameter_types! {
263 pub const ChainId: u64 = 8881;58 pub const ChainId: u64 = 8881;
264}59}
265
266pub struct FixedFee;
267impl FeeCalculator for FixedFee {
268 fn min_gas_price() -> (U256, u64) {
269 (MIN_GAS_PRICE.into(), 0)
270 }
271}
272
273// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
274// (contract, which only writes a lot of data),
275// approximating on top of our real store write weight
276parameter_types! {
277 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
278 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
279 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
280}
281
282/// Limiting EVM execution to 50% of block for substrate users and management tasks
283/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
284/// scheduled fairly
285const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
286parameter_types! {
287 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
288}
289
290pub enum FixedGasWeightMapping {}
291impl GasWeightMapping for FixedGasWeightMapping {
292 fn gas_to_weight(gas: u64) -> Weight {
293 gas.saturating_mul(WeightPerGas::get())
294 }
295 fn weight_to_gas(weight: Weight) -> u64 {
296 weight / WeightPerGas::get()
297 }
298}
299
300impl pallet_evm::account::Config for Runtime {
301 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
302 type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;
303 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
304}
305
306impl pallet_evm::Config for Runtime {
307 type BlockGasLimit = BlockGasLimit;
308 type FeeCalculator = FixedFee;
309 type GasWeightMapping = FixedGasWeightMapping;
310 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
311 type CallOrigin = EnsureAddressTruncated<Self>;
312 type WithdrawOrigin = EnsureAddressTruncated<Self>;
313 type AddressMapping = HashedAddressMapping<Self::Hashing>;
314 type PrecompilesType = ();
315 type PrecompilesValue = ();
316 type Currency = Balances;
317 type Event = Event;
318 type OnMethodCall = (
319 pallet_evm_migration::OnMethodCall<Self>,
320 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
321 CollectionDispatchT<Self>,
322 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
323 );
324 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
325 type ChainId = ChainId;
326 type Runner = pallet_evm::runner::stack::Runner<Self>;
327 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
328 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
329 type FindAuthor = EthereumFindAuthor<Aura>;
330}
331
332impl pallet_evm_migration::Config for Runtime {
333 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
334}
335
336pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
337impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
338 fn find_author<'a, I>(digests: I) -> Option<H160>
339 where
340 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
341 {
342 if let Some(author_index) = F::find_author(digests) {
343 let authority_id = Aura::authorities()[author_index as usize].clone();
344 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
345 }
346 None
347 }
348}
349
350impl pallet_ethereum::Config for Runtime {
351 type Event = Event;
352 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
353}
354
355impl pallet_randomness_collective_flip::Config for Runtime {}
356
357impl frame_system::Config for Runtime {
358 /// The data to be stored in an account.
359 type AccountData = pallet_balances::AccountData<Balance>;
360 /// The identifier used to distinguish between accounts.
361 type AccountId = AccountId;
362 /// The basic call filter to use in dispatchable.
363 type BaseCallFilter = Everything;
364 /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
365 type BlockHashCount = BlockHashCount;
366 /// The maximum length of a block (in bytes).
367 type BlockLength = RuntimeBlockLength;
368 /// The index type for blocks.
369 type BlockNumber = BlockNumber;
370 /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
371 type BlockWeights = RuntimeBlockWeights;
372 /// The aggregated dispatch type that is available for extrinsics.
373 type Call = Call;
374 /// The weight of database operations that the runtime can invoke.
375 type DbWeight = RocksDbWeight;
376 /// The ubiquitous event type.
377 type Event = Event;
378 /// The type for hashing blocks and tries.
379 type Hash = Hash;
380 /// The hashing algorithm used.
381 type Hashing = BlakeTwo256;
382 /// The header type.
383 type Header = generic::Header<BlockNumber, BlakeTwo256>;
384 /// The index type for storing how many extrinsics an account has signed.
385 type Index = Index;
386 /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
387 type Lookup = AccountIdLookup<AccountId, ()>;
388 /// What to do if an account is fully reaped from the system.
389 type OnKilledAccount = ();
390 /// What to do if a new account is created.
391 type OnNewAccount = ();
392 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
393 /// The ubiquitous origin type.
394 type Origin = Origin;
395 /// This type is being generated by `construct_runtime!`.
396 type PalletInfo = PalletInfo;
397 /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
398 type SS58Prefix = SS58Prefix;
399 /// Weight information for the extrinsics of this pallet.
400 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
401 /// Version of the runtime.
402 type Version = Version;
403 type MaxConsumers = ConstU32<16>;
404}
405
406parameter_types! {
407 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
408}
409
410impl pallet_timestamp::Config for Runtime {
411 /// A timestamp: milliseconds since the unix epoch.
412 type Moment = u64;
413 type OnTimestampSet = ();
414 type MinimumPeriod = MinimumPeriod;
415 type WeightInfo = ();
416}
417
418parameter_types! {
419 // pub const ExistentialDeposit: u128 = 500;
420 pub const ExistentialDeposit: u128 = 0;
421 pub const MaxLocks: u32 = 50;
422 pub const MaxReserves: u32 = 50;
423}
424
425impl pallet_balances::Config for Runtime {
426 type MaxLocks = MaxLocks;
427 type MaxReserves = MaxReserves;
428 type ReserveIdentifier = [u8; 16];
429 /// The type for recording an account's balance.
430 type Balance = Balance;
431 /// The ubiquitous event type.
432 type Event = Event;
433 type DustRemoval = Treasury;
434 type ExistentialDeposit = ExistentialDeposit;
435 type AccountStore = System;
436 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
437}
438
439pub const fn deposit(items: u32, bytes: u32) -> Balance {
440 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE
441}
442
443/*
444parameter_types! {
445 pub TombstoneDeposit: Balance = deposit(
446 1,
447 sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,
448 );
449 pub DepositPerContract: Balance = TombstoneDeposit::get();
450 pub const DepositPerStorageByte: Balance = deposit(0, 1);
451 pub const DepositPerStorageItem: Balance = deposit(1, 0);
452 pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
453 pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;
454 pub const SignedClaimHandicap: u32 = 2;
455 pub const MaxDepth: u32 = 32;
456 pub const MaxValueSize: u32 = 16 * 1024;
457 pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb
458 // The lazy deletion runs inside on_initialize.
459 pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
460 RuntimeBlockWeights::get().max_block;
461 // The weight needed for decoding the queue should be less or equal than a fifth
462 // of the overall weight dedicated to the lazy deletion.
463 pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
464 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
465 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
466 )) / 5) as u32;
467 pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
468}
469
470impl pallet_contracts::Config for Runtime {
471 type Time = Timestamp;
472 type Randomness = RandomnessCollectiveFlip;
473 type Currency = Balances;
474 type Event = Event;
475 type RentPayment = ();
476 type SignedClaimHandicap = SignedClaimHandicap;
477 type TombstoneDeposit = TombstoneDeposit;
478 type DepositPerContract = DepositPerContract;
479 type DepositPerStorageByte = DepositPerStorageByte;
480 type DepositPerStorageItem = DepositPerStorageItem;
481 type RentFraction = RentFraction;
482 type SurchargeReward = SurchargeReward;
483 type WeightPrice = pallet_transaction_payment::Pallet<Self>;
484 type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
485 type ChainExtension = NFTExtension;
486 type DeletionQueueDepth = DeletionQueueDepth;
487 type DeletionWeightLimit = DeletionWeightLimit;
488 type Schedule = Schedule;
489 type CallStack = [pallet_contracts::Frame<Self>; 31];
490}
491*/
492
493parameter_types! {
494 /// This value increases the priority of `Operational` transactions by adding
495 /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
496 pub const OperationalFeeMultiplier: u8 = 5;
497}
498
499/// Linear implementor of `WeightToFeePolynomial`
500pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
501
502impl<T> WeightToFeePolynomial for LinearFee<T>
503where
504 T: BaseArithmetic + From<u32> + Copy + Unsigned,
505{
506 type Balance = T;
507
508 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
509 smallvec!(WeightToFeeCoefficient {
510 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
511 coeff_frac: Perbill::zero(),
512 negative: false,
513 degree: 1,
514 })
515 }
516}
517
518impl pallet_transaction_payment::Config for Runtime {
519 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
520 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
521 type OperationalFeeMultiplier = OperationalFeeMultiplier;
522 type WeightToFee = LinearFee<Balance>;
523 type FeeMultiplierUpdate = ();
524}
525
526parameter_types! {
527 pub const ProposalBond: Permill = Permill::from_percent(5);
528 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
529 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
530 pub const SpendPeriod: BlockNumber = 5 * MINUTES;
531 pub const Burn: Permill = Permill::from_percent(0);
532 pub const TipCountdown: BlockNumber = 1 * DAYS;
533 pub const TipFindersFee: Percent = Percent::from_percent(20);
534 pub const TipReportDepositBase: Balance = 1 * UNIQUE;
535 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
536 pub const BountyDepositBase: Balance = 1 * UNIQUE;
537 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
538 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
539 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
540 pub const MaximumReasonLength: u32 = 16384;
541 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
542 pub const BountyValueMinimum: Balance = 5 * UNIQUE;
543 pub const MaxApprovals: u32 = 100;
544}
545
546impl pallet_treasury::Config for Runtime {
547 type PalletId = TreasuryModuleId;
548 type Currency = Balances;
549 type ApproveOrigin = EnsureRoot<AccountId>;
550 type RejectOrigin = EnsureRoot<AccountId>;
551 type Event = Event;
552 type OnSlash = ();
553 type ProposalBond = ProposalBond;
554 type ProposalBondMinimum = ProposalBondMinimum;
555 type ProposalBondMaximum = ProposalBondMaximum;
556 type SpendPeriod = SpendPeriod;
557 type Burn = Burn;
558 type BurnDestination = ();
559 type SpendFunds = ();
560 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
561 type MaxApprovals = MaxApprovals;
562}
563
564impl pallet_sudo::Config for Runtime {
565 type Event = Event;
566 type Call = Call;
567}
568
569pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
570
571impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
572 for RelayChainBlockNumberProvider<T>
573{
574 type BlockNumber = BlockNumber;
575
576 fn current_block_number() -> Self::BlockNumber {
577 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
578 .map(|d| d.relay_parent_number)
579 .unwrap_or_default()
580 }
581}
582
583parameter_types! {
584 pub const MinVestedTransfer: Balance = 10 * UNIQUE;
585 pub const MaxVestingSchedules: u32 = 28;
586}
587
588impl orml_vesting::Config for Runtime {
589 type Event = Event;
590 type Currency = pallet_balances::Pallet<Runtime>;
591 type MinVestedTransfer = MinVestedTransfer;
592 type VestedTransferOrigin = EnsureSigned<AccountId>;
593 type WeightInfo = ();
594 type MaxVestingSchedules = MaxVestingSchedules;
595 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
596}
597
598parameter_types! {
599 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
600 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
601}
602
603impl cumulus_pallet_parachain_system::Config for Runtime {
604 type Event = Event;
605 type SelfParaId = parachain_info::Pallet<Self>;
606 type OnSystemEvent = ();
607 // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
608 // MaxDownwardMessageWeight,
609 // XcmExecutor<XcmConfig>,
610 // Call,
611 // >;
612 type OutboundXcmpMessageSource = XcmpQueue;
613 type DmpMessageHandler = DmpQueue;
614 type ReservedDmpWeight = ReservedDmpWeight;
615 type ReservedXcmpWeight = ReservedXcmpWeight;
616 type XcmpMessageHandler = XcmpQueue;
617}
618
619impl parachain_info::Config for Runtime {}
620
621impl cumulus_pallet_aura_ext::Config for Runtime {}
622
623parameter_types! {
624 pub const RelayLocation: MultiLocation = MultiLocation::parent();
625 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
626 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
627 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
628}
629
630/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
631/// when determining ownership of accounts for asset transacting and when attempting to use XCM
632/// `Transact` in order to determine the dispatch Origin.
633pub type LocationToAccountId = (
634 // The parent (Relay-chain) origin converts to the default `AccountId`.
635 ParentIsPreset<AccountId>,
636 // Sibling parachain origins convert to AccountId via the `ParaId::into`.
637 SiblingParachainConvertsVia<Sibling, AccountId>,
638 // Straight up local `AccountId32` origins just alias directly to `AccountId`.
639 AccountId32Aliases<RelayNetwork, AccountId>,
640);
641
642pub struct OnlySelfCurrency;
643impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
644 fn matches_fungible(a: &MultiAsset) -> Option<B> {
645 match (&a.id, &a.fun) {
646 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
647 _ => None,
648 }
649 }
650}
651
652/// Means for transacting assets on this chain.
653pub type LocalAssetTransactor = CurrencyAdapter<
654 // Use this currency:
655 Balances,
656 // Use this currency when it is a fungible asset matching the given location or name:
657 OnlySelfCurrency,
658 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
659 LocationToAccountId,
660 // Our chain's account ID type (we can't get away without mentioning it explicitly):
661 AccountId,
662 // We don't track any teleports.
663 (),
664>;
665
666/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
667/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
668/// biases the kind of local `Origin` it will become.
669pub type XcmOriginToTransactDispatchOrigin = (
670 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
671 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
672 // foreign chains who want to have a local sovereign account on this chain which they control.
673 SovereignSignedViaLocation<LocationToAccountId, Origin>,
674 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
675 // recognised.
676 RelayChainAsNative<RelayOrigin, Origin>,
677 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
678 // recognised.
679 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
680 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
681 // transaction from the Root origin.
682 ParentAsSuperuser<Origin>,
683 // Native signed account converter; this just converts an `AccountId32` origin into a normal
684 // `Origin::Signed` origin of the same 32-byte value.
685 SignedAccountId32AsNative<RelayNetwork, Origin>,
686 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
687 XcmPassthrough<Origin>,
688);
689
690parameter_types! {
691 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
692 pub UnitWeightCost: Weight = 1_000_000;
693 // 1200 UNIQUEs buy 1 second of weight.
694 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
695 pub const MaxInstructions: u32 = 100;
696 pub const MaxAuthorities: u32 = 100_000;
697}
698
699match_types! {
700 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
701 MultiLocation { parents: 1, interior: Here } |
702 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
703 };
704}
705
706pub type Barrier = (
707 TakeWeightCredit,
708 AllowTopLevelPaidExecutionFrom<Everything>,
709 // ^^^ Parent & its unit plurality gets free execution
710);
711
712pub struct UsingOnlySelfCurrencyComponents<
713 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
714 AssetId: Get<MultiLocation>,
715 AccountId,
716 Currency: CurrencyT<AccountId>,
717 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
718>(
719 Weight,
720 Currency::Balance,
721 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
722);
723impl<
724 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
725 AssetId: Get<MultiLocation>,
726 AccountId,
727 Currency: CurrencyT<AccountId>,
728 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
729 > WeightTrader
730 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
731{
732 fn new() -> Self {
733 Self(0, Zero::zero(), PhantomData)
734 }
735
736 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
737 let amount = WeightToFee::weight_to_fee(&weight);
738 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
739
740 // location to this parachain through relay chain
741 let option1: xcm::v1::AssetId = Concrete(MultiLocation {
742 parents: 1,
743 interior: X1(Parachain(ParachainInfo::parachain_id().into())),
744 });
745 // direct location
746 let option2: xcm::v1::AssetId = Concrete(MultiLocation {
747 parents: 0,
748 interior: Here,
749 });
750
751 let required = if payment.fungible.contains_key(&option1) {
752 (option1, u128_amount).into()
753 } else if payment.fungible.contains_key(&option2) {
754 (option2, u128_amount).into()
755 } else {
756 (Concrete(MultiLocation::default()), u128_amount).into()
757 };
758
759 let unused = payment
760 .checked_sub(required)
761 .map_err(|_| XcmError::TooExpensive)?;
762 self.0 = self.0.saturating_add(weight);
763 self.1 = self.1.saturating_add(amount);
764 Ok(unused)
765 }
766
767 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
768 let weight = weight.min(self.0);
769 let amount = WeightToFee::weight_to_fee(&weight);
770 self.0 -= weight;
771 self.1 = self.1.saturating_sub(amount);
772 let amount: u128 = amount.saturated_into();
773 if amount > 0 {
774 Some((AssetId::get(), amount).into())
775 } else {
776 None
777 }
778 }
779}
780impl<
781 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
782 AssetId: Get<MultiLocation>,
783 AccountId,
784 Currency: CurrencyT<AccountId>,
785 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
786 > Drop
787 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
788{
789 fn drop(&mut self) {
790 OnUnbalanced::on_unbalanced(Currency::issue(self.1));
791 }
792}
793
794pub struct XcmConfig;
795impl Config for XcmConfig {
796 type Call = Call;
797 type XcmSender = XcmRouter;
798 // How to withdraw and deposit an asset.
799 type AssetTransactor = LocalAssetTransactor;
800 type OriginConverter = XcmOriginToTransactDispatchOrigin;
801 type IsReserve = NativeAsset;
802 type IsTeleporter = (); // Teleportation is disabled
803 type LocationInverter = LocationInverter<Ancestry>;
804 type Barrier = Barrier;
805 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
806 type Trader =
807 UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
808 type ResponseHandler = (); // Don't handle responses for now.
809 type SubscriptionService = PolkadotXcm;
810
811 type AssetTrap = PolkadotXcm;
812 type AssetClaims = PolkadotXcm;
813}
814
815// parameter_types! {
816// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
817// }
818
819/// No local origins on this chain are allowed to dispatch XCM sends/executions.
820pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
821
822/// The means for routing XCM messages which are not for local execution into the right message
823/// queues.
824pub type XcmRouter = (
825 // Two routers - use UMP to communicate with the relay chain:
826 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
827 // ..and XCMP to communicate with the sibling chains.
828 XcmpQueue,
829);
830
831impl pallet_evm_coder_substrate::Config for Runtime {}
832
833impl pallet_xcm::Config for Runtime {
834 type Event = Event;
835 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
836 type XcmRouter = XcmRouter;
837 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
838 type XcmExecuteFilter = Everything;
839 type XcmExecutor = XcmExecutor<XcmConfig>;
840 type XcmTeleportFilter = Everything;
841 type XcmReserveTransferFilter = Everything;
842 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
843 type LocationInverter = LocationInverter<Ancestry>;
844 type Origin = Origin;
845 type Call = Call;
846 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
847 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
848}
849
850impl cumulus_pallet_xcm::Config for Runtime {
851 type Event = Event;
852 type XcmExecutor = XcmExecutor<XcmConfig>;
853}
854
855impl cumulus_pallet_xcmp_queue::Config for Runtime {
856 type WeightInfo = ();
857 type Event = Event;
858 type XcmExecutor = XcmExecutor<XcmConfig>;
859 type ChannelInfo = ParachainSystem;
860 type VersionWrapper = ();
861 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
862 type ControllerOrigin = EnsureRoot<AccountId>;
863 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
864}
865
866impl cumulus_pallet_dmp_queue::Config for Runtime {
867 type Event = Event;
868 type XcmExecutor = XcmExecutor<XcmConfig>;
869 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
870}
871
872impl pallet_aura::Config for Runtime {
873 type AuthorityId = AuraId;
874 type DisabledValidators = ();
875 type MaxAuthorities = MaxAuthorities;
876}
877
878parameter_types! {
879 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
880 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
881}
882
883impl pallet_common::Config for Runtime {
884 type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
885 type Event = Event;
886 type Currency = Balances;
887 type CollectionCreationPrice = CollectionCreationPrice;
888 type TreasuryAccountId = TreasuryAccountId;
889 type CollectionDispatch = CollectionDispatchT<Self>;
890
891 type EvmTokenAddressMapping = EvmTokenAddressMapping;
892 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
893 type ContractAddress = EvmCollectionHelpersAddress;
894}
895
896impl pallet_structure::Config for Runtime {
897 type Event = Event;
898 type Call = Call;
899 type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
900}
901
902impl pallet_fungible::Config for Runtime {
903 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
904}
905impl pallet_refungible::Config for Runtime {
906 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
907}
908impl pallet_nonfungible::Config for Runtime {
909 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
910}
911
912impl pallet_proxy_rmrk_core::Config for Runtime {
913 type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
914 type Event = Event;
915}
916
917impl pallet_proxy_rmrk_equip::Config for Runtime {
918 type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
919 type Event = Event;
920}
921
922impl pallet_unique::Config for Runtime {
923 type Event = Event;
924 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
925 type CommonWeightInfo = CommonWeights<Self>;
926 type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
927}
928
929parameter_types! {
930 pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
931}
932
933/// Used for the pallet inflation
934impl pallet_inflation::Config for Runtime {
935 type Currency = Balances;
936 type TreasuryAccountId = TreasuryAccountId;
937 type InflationBlockInterval = InflationBlockInterval;
938 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
939}
940
941parameter_types! {
942 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
943 RuntimeBlockWeights::get().max_block;
944 pub const MaxScheduledPerBlock: u32 = 50;
945}
946
947type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
948use frame_support::traits::NamedReservableCurrency;
949
950fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
951 (
952 frame_system::CheckSpecVersion::<Runtime>::new(),
953 frame_system::CheckGenesis::<Runtime>::new(),
954 frame_system::CheckEra::<Runtime>::from(Era::Immortal),
955 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
956 from,
957 )),
958 frame_system::CheckWeight::<Runtime>::new(),
959 // sponsoring transaction logic
960 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
961 )
962}
963
964pub struct SchedulerPaymentExecutor;
965impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
966 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
967where
968 <T as frame_system::Config>::Call: Member
969 + Dispatchable<Origin = Origin, Info = DispatchInfo>
970 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
971 + GetDispatchInfo
972 + From<frame_system::Call<Runtime>>,
973 SelfContainedSignedInfo: Send + Sync + 'static,
974 Call: From<<T as frame_system::Config>::Call>
975 + From<<T as pallet_unique_scheduler::Config>::Call>
976 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
977 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
978{
979 fn dispatch_call(
980 signer: <T as frame_system::Config>::AccountId,
981 call: <T as pallet_unique_scheduler::Config>::Call,
982 ) -> Result<
983 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
984 TransactionValidityError,
985 > {
986 let dispatch_info = call.get_dispatch_info();
987 let extrinsic = fp_self_contained::CheckedExtrinsic::<
988 AccountId,
989 Call,
990 SignedExtraScheduler,
991 SelfContainedSignedInfo,
992 > {
993 signed:
994 CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
995 signer.clone().into(),
996 get_signed_extras(signer.into()),
997 ),
998 function: call.into(),
999 };
1000
1001 extrinsic.apply::<Runtime>(&dispatch_info, 0)
1002 }
1003
1004 fn reserve_balance(
1005 id: [u8; 16],
1006 sponsor: <T as frame_system::Config>::AccountId,
1007 call: <T as pallet_unique_scheduler::Config>::Call,
1008 count: u32,
1009 ) -> Result<(), DispatchError> {
1010 let dispatch_info = call.get_dispatch_info();
1011 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
1012 .saturating_mul(count.into());
1013
1014 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
1015 &id,
1016 &(sponsor.into()),
1017 weight.into(),
1018 )
1019 }
1020
1021 fn pay_for_call(
1022 id: [u8; 16],
1023 sponsor: <T as frame_system::Config>::AccountId,
1024 call: <T as pallet_unique_scheduler::Config>::Call,
1025 ) -> Result<u128, DispatchError> {
1026 let dispatch_info = call.get_dispatch_info();
1027 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
1028 Ok(
1029 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
1030 &id,
1031 &(sponsor.into()),
1032 weight.into(),
1033 ),
1034 )
1035 }
1036
1037 fn cancel_reserve(
1038 id: [u8; 16],
1039 sponsor: <T as frame_system::Config>::AccountId,
1040 ) -> Result<u128, DispatchError> {
1041 Ok(
1042 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
1043 &id,
1044 &(sponsor.into()),
1045 u128::MAX,
1046 ),
1047 )
1048 }
1049}
1050
1051parameter_types! {
1052 pub const NoPreimagePostponement: Option<u32> = Some(10);
1053 pub const Preimage: Option<u32> = Some(10);
1054}
1055
1056/// Used the compare the privilege of an origin inside the scheduler.
1057pub struct OriginPrivilegeCmp;
1058
1059impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
1060 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
1061 Some(Ordering::Equal)
1062 }
1063}
1064
1065impl pallet_unique_scheduler::Config for Runtime {
1066 type Event = Event;
1067 type Origin = Origin;
1068 type Currency = Balances;
1069 type PalletsOrigin = OriginCaller;
1070 type Call = Call;
1071 type MaximumWeight = MaximumSchedulerWeight;
1072 type ScheduleOrigin = EnsureSigned<AccountId>;
1073 type MaxScheduledPerBlock = MaxScheduledPerBlock;
1074 type WeightInfo = ();
1075 type CallExecutor = SchedulerPaymentExecutor;
1076 type OriginPrivilegeCmp = OriginPrivilegeCmp;
1077 type PreimageProvider = ();
1078 type NoPreimagePostponement = NoPreimagePostponement;
1079}
1080
1081type EvmSponsorshipHandler = (
1082 UniqueEthSponsorshipHandler<Runtime>,
1083 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
1084);
1085type SponsorshipHandler = (
1086 UniqueSponsorshipHandler<Runtime>,
1087 //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
1088 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
1089);
1090
1091impl pallet_evm_transaction_payment::Config for Runtime {
1092 type EvmSponsorshipHandler = EvmSponsorshipHandler;
1093 type Currency = Balances;
1094}
1095
1096impl pallet_charge_transaction::Config for Runtime {
1097 type SponsorshipHandler = SponsorshipHandler;
1098}
1099
1100// impl pallet_contract_helpers::Config for Runtime {
1101// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
1102// }
1103
1104parameter_types! {
1105 // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
1106 pub const HelpersContractAddress: H160 = H160([
1107 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
1108 ]);
1109
1110 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
1111 pub const EvmCollectionHelpersAddress: H160 = H160([
1112 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
1113 ]);
1114}
1115
1116impl pallet_evm_contract_helpers::Config for Runtime {
1117 type ContractAddress = HelpersContractAddress;
1118 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
1119}
112060
1121construct_runtime!(61construct_runtime!(quartz);
1122 pub enum Runtime where
1123 Block = Block,
1124 NodeBlock = opaque::Block,
1125 UncheckedExtrinsic = UncheckedExtrinsic
1126 {
1127 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
1128 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
1129
1130 Aura: pallet_aura::{Pallet, Config<T>} = 22,
1131 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
1132
1133 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
1134 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
1135 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
1136 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
1137 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
1138 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
1139 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
1140 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
1141 // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
1142 // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
1143
1144 // XCM helpers.
1145 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
1146 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
1147 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
1148 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
1149
1150 // Unique Pallets
1151 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
1152 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
1153 Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
1154 // free = 63
1155 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
1156 // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
1157 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
1158 Fungible: pallet_fungible::{Pallet, Storage} = 67,
1159 Refungible: pallet_refungible::{Pallet, Storage} = 68,
1160 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
1161 Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
1162 RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
1163 RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
1164
1165 // Frontier
1166 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
1167 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
1168
1169 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
1170 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
1171 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
1172 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
1173 }
1174);
1175
1176pub struct TransactionConverter;
1177
1178impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
1179 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
1180 UncheckedExtrinsic::new_unsigned(
1181 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1182 )
1183 }
1184}
1185
1186impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
1187 fn convert_transaction(
1188 &self,
1189 transaction: pallet_ethereum::Transaction,
1190 ) -> opaque::UncheckedExtrinsic {
1191 let extrinsic = UncheckedExtrinsic::new_unsigned(
1192 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1193 );
1194 let encoded = extrinsic.encode();
1195 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
1196 .expect("Encoded extrinsic is always valid")
1197 }
1198}
1199
1200/// The address format for describing accounts.
1201pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1202/// Block header type as expected by this runtime.
1203pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1204/// Block type as expected by this runtime.
1205pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1206/// A Block signed with a Justification
1207pub type SignedBlock = generic::SignedBlock<Block>;
1208/// BlockId type as expected by this runtime.
1209pub type BlockId = generic::BlockId<Block>;
1210/// The SignedExtension to the basic transaction logic.
1211pub type SignedExtra = (
1212 frame_system::CheckSpecVersion<Runtime>,
1213 // system::CheckTxVersion<Runtime>,
1214 frame_system::CheckGenesis<Runtime>,
1215 frame_system::CheckEra<Runtime>,
1216 frame_system::CheckNonce<Runtime>,
1217 frame_system::CheckWeight<Runtime>,
1218 ChargeTransactionPayment,
1219 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
1220 pallet_ethereum::FakeTransactionFinalizer<Runtime>,
1221);
1222
1223pub type SignedExtraScheduler = (
1224 frame_system::CheckSpecVersion<Runtime>,
1225 frame_system::CheckGenesis<Runtime>,
1226 frame_system::CheckEra<Runtime>,
1227 frame_system::CheckNonce<Runtime>,
1228 frame_system::CheckWeight<Runtime>,
1229 // pallet_charge_transaction::ChargeTransactionPayment<Runtime>,
1230);
1231/// Unchecked extrinsic type as expected by this runtime.
1232pub type UncheckedExtrinsic =
1233 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
1234/// Extrinsic type that has already been checked.
1235pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
1236/// Executive: handles dispatch to the various modules.
1237pub type Executive = frame_executive::Executive<
1238 Runtime,
1239 Block,
1240 frame_system::ChainContext<Runtime>,
1241 Runtime,
1242 AllPalletsReversedWithSystemFirst,
1243>;
1244
1245impl_opaque_keys! {
1246 pub struct SessionKeys {
1247 pub aura: Aura,
1248 }
1249}
1250
1251impl fp_self_contained::SelfContainedCall for Call {
1252 type SignedInfo = H160;
1253
1254 fn is_self_contained(&self) -> bool {
1255 match self {
1256 Call::Ethereum(call) => call.is_self_contained(),
1257 _ => false,
1258 }
1259 }
1260
1261 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
1262 match self {
1263 Call::Ethereum(call) => call.check_self_contained(),
1264 _ => None,
1265 }
1266 }
1267
1268 fn validate_self_contained(
1269 &self,
1270 info: &Self::SignedInfo,
1271 dispatch_info: &DispatchInfoOf<Call>,
1272 len: usize,
1273 ) -> Option<TransactionValidity> {
1274 match self {
1275 Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
1276 _ => None,
1277 }
1278 }
1279
1280 fn pre_dispatch_self_contained(
1281 &self,
1282 info: &Self::SignedInfo,
1283 ) -> Option<Result<(), TransactionValidityError>> {
1284 match self {
1285 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
1286 _ => None,
1287 }
1288 }
1289
1290 fn apply_self_contained(
1291 self,
1292 info: Self::SignedInfo,
1293 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
1294 match self {
1295 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
1296 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
1297 )),
1298 _ => None,
1299 }
1300 }
1301}
1302
1303macro_rules! dispatch_unique_runtime {
1304 ($collection:ident.$method:ident($($name:ident),*)) => {{
1305 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
1306 let dispatch = collection.as_dyn();
1307
1308 Ok::<_, DispatchError>(dispatch.$method($($name),*))
1309 }};
1310}
131162
1312impl_common_runtime_apis! {63impl_common_runtime_apis!();
1313 #![custom_apis]
1314
1315 impl rmrk_rpc::RmrkApi<
1316 Block,
1317 AccountId,
1318 RmrkCollectionInfo<AccountId>,
1319 RmrkInstanceInfo<AccountId>,
1320 RmrkResourceInfo,
1321 RmrkPropertyInfo,
1322 RmrkBaseInfo<AccountId>,
1323 RmrkPartType,
1324 RmrkTheme
1325 > for Runtime {
1326 fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {
1327 pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>()
1328 }
1329
1330 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
1331 pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id)
1332 }
1333
1334 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
1335 pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id)
1336 }
1337
1338 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
1339 pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id)
1340 }
1341
1342 fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
1343 pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id)
1344 }
1345
1346 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
1347 pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys)
1348 }
1349
1350 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
1351 pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys)
1352 }
1353
1354 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
1355 pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id)
1356 }
1357
1358 fn nft_resource_priority(collection_id: RmrkCollectionId, nft_id: RmrkNftId, resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
1359 pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id)
1360 }
1361
1362 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
1363 pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id)
1364 }
1365
1366 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
1367 pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id)
1368 }
1369
1370 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
1371 pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id)
1372 }
1373
1374 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
1375 pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys)
1376 }
1377 }
1378}
1379
1380struct CheckInherents;
1381
1382impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
1383 fn check_inherents(
1384 block: &Block,
1385 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
1386 ) -> sp_inherents::CheckInherentsResult {
1387 let relay_chain_slot = relay_state_proof
1388 .read_slot()
1389 .expect("Could not read the relay chain slot from the proof");
1390
1391 let inherent_data =
1392 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
1393 relay_chain_slot,
1394 sp_std::time::Duration::from_secs(6),
1395 )
1396 .create_inherent_data()
1397 .expect("Could not create the timestamp inherent data");
1398
1399 inherent_data.check_extrinsics(block)
1400 }
1401}
140264
1403cumulus_pallet_parachain_system::register_validate_block!(65cumulus_pallet_parachain_system::register_validate_block!(
1404 Runtime = Runtime,66 Runtime = Runtime,
modifiedruntime/tests/Cargo.tomldiffbeforeafterboth
3version = "0.1.0"3version = "0.1.0"
4edition = "2021"4edition = "2021"
5
6[features]
7default = ['refungible']
8
9refungible = []
510
6[dependencies]11[dependencies]
7unique-runtime-common = { path = '../common' }
8up-data-structs = { default-features = false, path = '../../primitives/data-structs' }12up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
913
10sp-core = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.24' }14sp-core = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.24' }
38] }42] }
39scale-info = "*"43scale-info = "*"
44
45evm-coder = { default-features = false, path = '../../crates/evm-coder' }
46up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
4047
modifiedruntime/tests/src/lib.rsdiffbeforeafterboth
35use parity_scale_codec::{Encode, Decode, MaxEncodedLen};35use parity_scale_codec::{Encode, Decode, MaxEncodedLen};
36use scale_info::TypeInfo;36use scale_info::TypeInfo;
3737
38use unique_runtime_common::{dispatch::CollectionDispatchT, weights::CommonWeights};
39use up_data_structs::mapping::{CrossTokenAddressMapping, EvmTokenAddressMapping};38use up_data_structs::mapping::{CrossTokenAddressMapping, EvmTokenAddressMapping};
39
40#[path = "../../common/dispatch.rs"]
41mod dispatch;
42
43use dispatch::CollectionDispatchT;
44
45#[path = "../../common/weights.rs"]
46mod weights;
47
48use weights::CommonWeights;
4049
41type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;50type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
42type Block = frame_system::mocking::MockBlock<Test>;51type Block = frame_system::mocking::MockBlock<Test>;
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
114 'xcm/std',114 'xcm/std',
115 'xcm-builder/std',115 'xcm-builder/std',
116 'xcm-executor/std',116 'xcm-executor/std',
117 'unique-runtime-common/std',117 'up-common/std',
118118
119 "orml-vesting/std",119 "orml-vesting/std",
120]120]
121limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']121limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
122unique-runtime = []122unique-runtime = []
123
124refungible = []
125scheduler = []
126rmrk = []
123127
124################################################################################128################################################################################
125# Substrate Dependencies129# Substrate Dependencies
397401
398[dependencies]402[dependencies]
399log = { version = "0.4.16", default-features = false }403log = { version = "0.4.16", default-features = false }
400unique-runtime-common = { path = "../common", default-features = false }404up-common = { path = "../../primitives/common", default-features = false }
401scale-info = { version = "2.0.1", default-features = false, features = [405scale-info = { version = "2.0.1", default-features = false, features = [
402 "derive",406 "derive",
403] }407] }
427fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }431fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
428fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }432fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
429fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }433fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
434evm-coder = { default-features = false, path = '../../crates/evm-coder' }
435up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
430436
431################################################################################437################################################################################
432# Build Dependencies438# Build Dependencies
modifiedruntime/unique/src/lib.rsdiffbeforeafterboth
25#[cfg(feature = "std")]25#[cfg(feature = "std")]
26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
2727
28use sp_api::impl_runtime_apis;28use frame_support::parameter_types;
29
29use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};30use sp_version::RuntimeVersion;
30use sp_runtime::DispatchError;
31use fp_self_contained::*;
32// #[cfg(any(feature = "std", test))]
33// pub use sp_runtime::BuildStorage;
34
35use sp_runtime::{31use sp_runtime::create_runtime_str;
36 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
37 traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},
38 transaction_validity::{TransactionSource, TransactionValidity},
39 ApplyExtrinsicResult, RuntimeAppPublic,
40};
4132
42use sp_std::prelude::*;33use up_common::types::*;
4334
44#[cfg(feature = "std")]35#[path = "../../common/mod.rs"]
45use sp_version::NativeVersion;36mod runtime_common;
46use sp_version::RuntimeVersion;37
47pub use pallet_transaction_payment::{38pub use runtime_common::*;
48 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,
49};
50// A few exports that help ease life for downstream crates.
51pub use pallet_balances::Call as BalancesCall;
52pub use pallet_evm::{
53 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,
54 OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
55};
56pub use frame_support::{
57 construct_runtime, match_types,
58 dispatch::DispatchResult,
59 PalletId, parameter_types, StorageValue, ConsensusEngineId,
60 traits::{
61 tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
62 Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
63 OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,
64 },
65 weights::{
66 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
67 DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
68 WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
69 WeightToFee,
70 },
71};
72use pallet_unique_scheduler::DispatchCall;
73use up_data_structs::{
74 CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
75 CollectionStats, RpcCollection,
76 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
77 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
78 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
79 RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
80};
81
82// use pallet_contracts::weights::WeightInfo;
83// #[cfg(any(feature = "std", test))]
84use frame_system::{
85 self as frame_system, EnsureRoot, EnsureSigned,
86 limits::{BlockWeights, BlockLength},
87};
88use sp_arithmetic::{
89 traits::{BaseArithmetic, Unsigned},
90};
91use smallvec::smallvec;
92use codec::{Encode, Decode};
93use fp_rpc::TransactionStatus;
94use sp_runtime::{
95 traits::{
96 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,
97 Saturating, CheckedConversion,
98 },
99 generic::Era,
100 transaction_validity::TransactionValidityError,
101 DispatchErrorWithPostInfo, SaturatedConversion,
102};
103
104// pub use pallet_timestamp::Call as TimestampCall;
105pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
106
107// Polkadot imports
108use pallet_xcm::XcmPassthrough;
109use polkadot_parachain::primitives::Sibling;
110use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
111use xcm_builder::{
112 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
113 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
114 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
115 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
116 ParentIsPreset,
117};
118use xcm_executor::{Config, XcmExecutor, Assets};
119use sp_std::{cmp::Ordering, marker::PhantomData};
120
121use xcm::latest::{
122 // Xcm,
123 AssetId::{Concrete},
124 Fungibility::Fungible as XcmFungible,
125 MultiAsset,
126 Error as XcmError,
127};
128use xcm_executor::traits::{MatchesFungible, WeightTrader};
129
130use unique_runtime_common::{
131 impl_common_runtime_apis,
132 types::*,
133 constants::*,
134 dispatch::{CollectionDispatchT, CollectionDispatch},
135 sponsoring::UniqueSponsorshipHandler,
136 eth_sponsoring::UniqueEthSponsorshipHandler,
137 weights::CommonWeights,
138};
13939
140pub const RUNTIME_NAME: &str = "unique";40pub const RUNTIME_NAME: &str = "unique";
141pub const TOKEN_SYMBOL: &str = "UNQ";41pub const TOKEN_SYMBOL: &str = "UNQ";
142
143type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
144
145impl RuntimeInstance for Runtime {
146 type CrossAccountId = self::CrossAccountId;
147 type TransactionConverter = self::TransactionConverter;
148
149 fn get_transaction_converter() -> TransactionConverter {
150 TransactionConverter
151 }
152}
153
154/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
155/// never know...
156pub type AccountIndex = u32;
157
158/// Balance of an account.
159pub type Balance = u128;
160
161/// Index of a transaction in the chain.
162pub type Index = u32;
163
164/// A hash of some data used by the chain.
165pub type Hash = sp_core::H256;
166
167/// Digest item type.
168pub type DigestItem = generic::DigestItem;
169
170/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
171/// the specifics of the runtime. They can then be made to be agnostic over specific formats
172/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
173/// to even the core data structures.
174pub mod opaque {
175 use sp_std::prelude::*;
176 use sp_runtime::impl_opaque_keys;
177 use super::Aura;
178
179 pub use unique_runtime_common::types::*;
180
181 impl_opaque_keys! {
182 pub struct SessionKeys {
183 pub aura: Aura,
184 }
185 }
186}
18742
188/// This runtime version.43/// This runtime version.
189pub const VERSION: RuntimeVersion = RuntimeVersion {44pub const VERSION: RuntimeVersion = RuntimeVersion {
197 state_version: 0,52 state_version: 0,
198};53};
199
200#[derive(codec::Encode, codec::Decode)]
201pub enum XCMPMessage<XAccountId, XBalance> {
202 /// Transfer tokens to the given account from the Parachain account.
203 TransferToken(XAccountId, XBalance),
204}
205
206/// The version information used to identify this runtime when compiled natively.
207#[cfg(feature = "std")]
208pub fn native_version() -> NativeVersion {
209 NativeVersion {
210 runtime_version: VERSION,
211 can_author_with: Default::default(),
212 }
213}
214
215type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
216
217pub struct DealWithFees;
218impl OnUnbalanced<NegativeImbalance> for DealWithFees {
219 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
220 if let Some(fees) = fees_then_tips.next() {
221 // for fees, 100% to treasury
222 let mut split = fees.ration(100, 0);
223 if let Some(tips) = fees_then_tips.next() {
224 // for tips, if any, 100% to treasury
225 tips.ration_merge_into(100, 0, &mut split);
226 }
227 Treasury::on_unbalanced(split.0);
228 // Author::on_unbalanced(split.1);
229 }
230 }
231}
23254
233parameter_types! {55parameter_types! {
234 pub const BlockHashCount: BlockNumber = 2400;
235 pub RuntimeBlockLength: BlockLength =
236 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
237 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
238 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
239 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
240 .base_block(BlockExecutionWeight::get())
241 .for_class(DispatchClass::all(), |weights| {
242 weights.base_extrinsic = ExtrinsicBaseWeight::get();
243 })
244 .for_class(DispatchClass::Normal, |weights| {
245 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
246 })
247 .for_class(DispatchClass::Operational, |weights| {
248 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
249 // Operational transactions have some extra reserved space, so that they
250 // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
251 weights.reserved = Some(
252 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
253 );
254 })
255 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
256 .build_or_panic();
257 pub const Version: RuntimeVersion = VERSION;56 pub const Version: RuntimeVersion = VERSION;
258 pub const SS58Prefix: u16 = 7391;57 pub const SS58Prefix: u16 = 7391;
259}
260
261parameter_types! {
262 pub const ChainId: u64 = 8880;58 pub const ChainId: u64 = 8880;
263}59}
264
265pub struct FixedFee;
266impl FeeCalculator for FixedFee {
267 fn min_gas_price() -> (U256, u64) {
268 (MIN_GAS_PRICE.into(), 0)
269 }
270}
271
272// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
273// (contract, which only writes a lot of data),
274// approximating on top of our real store write weight
275parameter_types! {
276 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;
277 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
278 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();
279}
280
281/// Limiting EVM execution to 50% of block for substrate users and management tasks
282/// EVM transaction consumes more weight than substrate's, so we can't rely on them being
283/// scheduled fairly
284const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
285parameter_types! {
286 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());
287}
288
289pub enum FixedGasWeightMapping {}
290impl GasWeightMapping for FixedGasWeightMapping {
291 fn gas_to_weight(gas: u64) -> Weight {
292 gas.saturating_mul(WeightPerGas::get())
293 }
294 fn weight_to_gas(weight: Weight) -> u64 {
295 weight / WeightPerGas::get()
296 }
297}
298
299impl pallet_evm::account::Config for Runtime {
300 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
301 type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
302 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
303}
304
305impl pallet_evm::Config for Runtime {
306 type BlockGasLimit = BlockGasLimit;
307 type FeeCalculator = FixedFee;
308 type GasWeightMapping = FixedGasWeightMapping;
309 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
310 type CallOrigin = EnsureAddressTruncated<Self>;
311 type WithdrawOrigin = EnsureAddressTruncated<Self>;
312 type AddressMapping = HashedAddressMapping<Self::Hashing>;
313 type PrecompilesType = ();
314 type PrecompilesValue = ();
315 type Currency = Balances;
316 type Event = Event;
317 type OnMethodCall = (
318 pallet_evm_migration::OnMethodCall<Self>,
319 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
320 CollectionDispatchT<Self>,
321 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
322 );
323 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
324 type ChainId = ChainId;
325 type Runner = pallet_evm::runner::stack::Runner<Self>;
326 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
327 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
328 type FindAuthor = EthereumFindAuthor<Aura>;
329}
330
331impl pallet_evm_migration::Config for Runtime {
332 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
333}
334
335pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
336impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
337 fn find_author<'a, I>(digests: I) -> Option<H160>
338 where
339 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
340 {
341 if let Some(author_index) = F::find_author(digests) {
342 let authority_id = Aura::authorities()[author_index as usize].clone();
343 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
344 }
345 None
346 }
347}
348
349impl pallet_ethereum::Config for Runtime {
350 type Event = Event;
351 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
352}
353
354impl pallet_randomness_collective_flip::Config for Runtime {}
355
356impl frame_system::Config for Runtime {
357 /// The data to be stored in an account.
358 type AccountData = pallet_balances::AccountData<Balance>;
359 /// The identifier used to distinguish between accounts.
360 type AccountId = AccountId;
361 /// The basic call filter to use in dispatchable.
362 type BaseCallFilter = Everything;
363 /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
364 type BlockHashCount = BlockHashCount;
365 /// The maximum length of a block (in bytes).
366 type BlockLength = RuntimeBlockLength;
367 /// The index type for blocks.
368 type BlockNumber = BlockNumber;
369 /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.
370 type BlockWeights = RuntimeBlockWeights;
371 /// The aggregated dispatch type that is available for extrinsics.
372 type Call = Call;
373 /// The weight of database operations that the runtime can invoke.
374 type DbWeight = RocksDbWeight;
375 /// The ubiquitous event type.
376 type Event = Event;
377 /// The type for hashing blocks and tries.
378 type Hash = Hash;
379 /// The hashing algorithm used.
380 type Hashing = BlakeTwo256;
381 /// The header type.
382 type Header = generic::Header<BlockNumber, BlakeTwo256>;
383 /// The index type for storing how many extrinsics an account has signed.
384 type Index = Index;
385 /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
386 type Lookup = AccountIdLookup<AccountId, ()>;
387 /// What to do if an account is fully reaped from the system.
388 type OnKilledAccount = ();
389 /// What to do if a new account is created.
390 type OnNewAccount = ();
391 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
392 /// The ubiquitous origin type.
393 type Origin = Origin;
394 /// This type is being generated by `construct_runtime!`.
395 type PalletInfo = PalletInfo;
396 /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
397 type SS58Prefix = SS58Prefix;
398 /// Weight information for the extrinsics of this pallet.
399 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;
400 /// Version of the runtime.
401 type Version = Version;
402 type MaxConsumers = ConstU32<16>;
403}
404
405parameter_types! {
406 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
407}
408
409impl pallet_timestamp::Config for Runtime {
410 /// A timestamp: milliseconds since the unix epoch.
411 type Moment = u64;
412 type OnTimestampSet = ();
413 type MinimumPeriod = MinimumPeriod;
414 type WeightInfo = ();
415}
416
417parameter_types! {
418 // pub const ExistentialDeposit: u128 = 500;
419 pub const ExistentialDeposit: u128 = 0;
420 pub const MaxLocks: u32 = 50;
421 pub const MaxReserves: u32 = 50;
422}
423
424impl pallet_balances::Config for Runtime {
425 type MaxLocks = MaxLocks;
426 type MaxReserves = MaxReserves;
427 type ReserveIdentifier = [u8; 16];
428 /// The type for recording an account's balance.
429 type Balance = Balance;
430 /// The ubiquitous event type.
431 type Event = Event;
432 type DustRemoval = Treasury;
433 type ExistentialDeposit = ExistentialDeposit;
434 type AccountStore = System;
435 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
436}
437
438pub const fn deposit(items: u32, bytes: u32) -> Balance {
439 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE
440}
441
442/*
443parameter_types! {
444 pub TombstoneDeposit: Balance = deposit(
445 1,
446 sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,
447 );
448 pub DepositPerContract: Balance = TombstoneDeposit::get();
449 pub const DepositPerStorageByte: Balance = deposit(0, 1);
450 pub const DepositPerStorageItem: Balance = deposit(1, 0);
451 pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
452 pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;
453 pub const SignedClaimHandicap: u32 = 2;
454 pub const MaxDepth: u32 = 32;
455 pub const MaxValueSize: u32 = 16 * 1024;
456 pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb
457 // The lazy deletion runs inside on_initialize.
458 pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
459 RuntimeBlockWeights::get().max_block;
460 // The weight needed for decoding the queue should be less or equal than a fifth
461 // of the overall weight dedicated to the lazy deletion.
462 pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
463 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
464 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
465 )) / 5) as u32;
466 pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
467}
468
469impl pallet_contracts::Config for Runtime {
470 type Time = Timestamp;
471 type Randomness = RandomnessCollectiveFlip;
472 type Currency = Balances;
473 type Event = Event;
474 type RentPayment = ();
475 type SignedClaimHandicap = SignedClaimHandicap;
476 type TombstoneDeposit = TombstoneDeposit;
477 type DepositPerContract = DepositPerContract;
478 type DepositPerStorageByte = DepositPerStorageByte;
479 type DepositPerStorageItem = DepositPerStorageItem;
480 type RentFraction = RentFraction;
481 type SurchargeReward = SurchargeReward;
482 type WeightPrice = pallet_transaction_payment::Pallet<Self>;
483 type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
484 type ChainExtension = NFTExtension;
485 type DeletionQueueDepth = DeletionQueueDepth;
486 type DeletionWeightLimit = DeletionWeightLimit;
487 type Schedule = Schedule;
488 type CallStack = [pallet_contracts::Frame<Self>; 31];
489}
490*/
491
492parameter_types! {
493 /// This value increases the priority of `Operational` transactions by adding
494 /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
495 pub const OperationalFeeMultiplier: u8 = 5;
496}
497
498/// Linear implementor of `WeightToFeePolynomial`
499pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);
500
501impl<T> WeightToFeePolynomial for LinearFee<T>
502where
503 T: BaseArithmetic + From<u32> + Copy + Unsigned,
504{
505 type Balance = T;
506
507 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
508 smallvec!(WeightToFeeCoefficient {
509 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),
510 coeff_frac: Perbill::zero(),
511 negative: false,
512 degree: 1,
513 })
514 }
515}
516
517impl pallet_transaction_payment::Config for Runtime {
518 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;
519 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
520 type OperationalFeeMultiplier = OperationalFeeMultiplier;
521 type WeightToFee = LinearFee<Balance>;
522 type FeeMultiplierUpdate = ();
523}
524
525parameter_types! {
526 pub const ProposalBond: Permill = Permill::from_percent(5);
527 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;
528 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;
529 pub const SpendPeriod: BlockNumber = 5 * MINUTES;
530 pub const Burn: Permill = Permill::from_percent(0);
531 pub const TipCountdown: BlockNumber = 1 * DAYS;
532 pub const TipFindersFee: Percent = Percent::from_percent(20);
533 pub const TipReportDepositBase: Balance = 1 * UNIQUE;
534 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;
535 pub const BountyDepositBase: Balance = 1 * UNIQUE;
536 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
537 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");
538 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
539 pub const MaximumReasonLength: u32 = 16384;
540 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
541 pub const BountyValueMinimum: Balance = 5 * UNIQUE;
542 pub const MaxApprovals: u32 = 100;
543}
544
545impl pallet_treasury::Config for Runtime {
546 type PalletId = TreasuryModuleId;
547 type Currency = Balances;
548 type ApproveOrigin = EnsureRoot<AccountId>;
549 type RejectOrigin = EnsureRoot<AccountId>;
550 type Event = Event;
551 type OnSlash = ();
552 type ProposalBond = ProposalBond;
553 type ProposalBondMinimum = ProposalBondMinimum;
554 type ProposalBondMaximum = ProposalBondMaximum;
555 type SpendPeriod = SpendPeriod;
556 type Burn = Burn;
557 type BurnDestination = ();
558 type SpendFunds = ();
559 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
560 type MaxApprovals = MaxApprovals;
561}
562
563impl pallet_sudo::Config for Runtime {
564 type Event = Event;
565 type Call = Call;
566}
567
568pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
569
570impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
571 for RelayChainBlockNumberProvider<T>
572{
573 type BlockNumber = BlockNumber;
574
575 fn current_block_number() -> Self::BlockNumber {
576 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
577 .map(|d| d.relay_parent_number)
578 .unwrap_or_default()
579 }
580}
581
582parameter_types! {
583 pub const MinVestedTransfer: Balance = 10 * UNIQUE;
584 pub const MaxVestingSchedules: u32 = 28;
585}
586
587impl orml_vesting::Config for Runtime {
588 type Event = Event;
589 type Currency = pallet_balances::Pallet<Runtime>;
590 type MinVestedTransfer = MinVestedTransfer;
591 type VestedTransferOrigin = EnsureSigned<AccountId>;
592 type WeightInfo = ();
593 type MaxVestingSchedules = MaxVestingSchedules;
594 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
595}
596
597parameter_types! {
598 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
599 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
600}
601
602impl cumulus_pallet_parachain_system::Config for Runtime {
603 type Event = Event;
604 type SelfParaId = parachain_info::Pallet<Self>;
605 type OnSystemEvent = ();
606 // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
607 // MaxDownwardMessageWeight,
608 // XcmExecutor<XcmConfig>,
609 // Call,
610 // >;
611 type OutboundXcmpMessageSource = XcmpQueue;
612 type DmpMessageHandler = DmpQueue;
613 type ReservedDmpWeight = ReservedDmpWeight;
614 type ReservedXcmpWeight = ReservedXcmpWeight;
615 type XcmpMessageHandler = XcmpQueue;
616}
617
618impl parachain_info::Config for Runtime {}
619
620impl cumulus_pallet_aura_ext::Config for Runtime {}
621
622parameter_types! {
623 pub const RelayLocation: MultiLocation = MultiLocation::parent();
624 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
625 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
626 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
627}
628
629/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
630/// when determining ownership of accounts for asset transacting and when attempting to use XCM
631/// `Transact` in order to determine the dispatch Origin.
632pub type LocationToAccountId = (
633 // The parent (Relay-chain) origin converts to the default `AccountId`.
634 ParentIsPreset<AccountId>,
635 // Sibling parachain origins convert to AccountId via the `ParaId::into`.
636 SiblingParachainConvertsVia<Sibling, AccountId>,
637 // Straight up local `AccountId32` origins just alias directly to `AccountId`.
638 AccountId32Aliases<RelayNetwork, AccountId>,
639);
640
641pub struct OnlySelfCurrency;
642impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
643 fn matches_fungible(a: &MultiAsset) -> Option<B> {
644 match (&a.id, &a.fun) {
645 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
646 _ => None,
647 }
648 }
649}
650
651/// Means for transacting assets on this chain.
652pub type LocalAssetTransactor = CurrencyAdapter<
653 // Use this currency:
654 Balances,
655 // Use this currency when it is a fungible asset matching the given location or name:
656 OnlySelfCurrency,
657 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
658 LocationToAccountId,
659 // Our chain's account ID type (we can't get away without mentioning it explicitly):
660 AccountId,
661 // We don't track any teleports.
662 (),
663>;
664
665/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
666/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
667/// biases the kind of local `Origin` it will become.
668pub type XcmOriginToTransactDispatchOrigin = (
669 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
670 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
671 // foreign chains who want to have a local sovereign account on this chain which they control.
672 SovereignSignedViaLocation<LocationToAccountId, Origin>,
673 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
674 // recognised.
675 RelayChainAsNative<RelayOrigin, Origin>,
676 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
677 // recognised.
678 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
679 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
680 // transaction from the Root origin.
681 ParentAsSuperuser<Origin>,
682 // Native signed account converter; this just converts an `AccountId32` origin into a normal
683 // `Origin::Signed` origin of the same 32-byte value.
684 SignedAccountId32AsNative<RelayNetwork, Origin>,
685 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
686 XcmPassthrough<Origin>,
687);
688
689parameter_types! {
690 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
691 pub UnitWeightCost: Weight = 1_000_000;
692 // 1200 UNIQUEs buy 1 second of weight.
693 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);
694 pub const MaxInstructions: u32 = 100;
695 pub const MaxAuthorities: u32 = 100_000;
696}
697
698match_types! {
699 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
700 MultiLocation { parents: 1, interior: Here } |
701 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
702 };
703}
704
705pub type Barrier = (
706 TakeWeightCredit,
707 AllowTopLevelPaidExecutionFrom<Everything>,
708 // ^^^ Parent & its unit plurality gets free execution
709);
710
711pub struct UsingOnlySelfCurrencyComponents<
712 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
713 AssetId: Get<MultiLocation>,
714 AccountId,
715 Currency: CurrencyT<AccountId>,
716 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
717>(
718 Weight,
719 Currency::Balance,
720 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
721);
722impl<
723 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
724 AssetId: Get<MultiLocation>,
725 AccountId,
726 Currency: CurrencyT<AccountId>,
727 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
728 > WeightTrader
729 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
730{
731 fn new() -> Self {
732 Self(0, Zero::zero(), PhantomData)
733 }
734
735 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
736 let amount = WeightToFee::weight_to_fee(&weight);
737 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
738
739 // location to this parachain through relay chain
740 let option1: xcm::v1::AssetId = Concrete(MultiLocation {
741 parents: 1,
742 interior: X1(Parachain(ParachainInfo::parachain_id().into())),
743 });
744 // direct location
745 let option2: xcm::v1::AssetId = Concrete(MultiLocation {
746 parents: 0,
747 interior: Here,
748 });
749
750 let required = if payment.fungible.contains_key(&option1) {
751 (option1, u128_amount).into()
752 } else if payment.fungible.contains_key(&option2) {
753 (option2, u128_amount).into()
754 } else {
755 (Concrete(MultiLocation::default()), u128_amount).into()
756 };
757
758 let unused = payment
759 .checked_sub(required)
760 .map_err(|_| XcmError::TooExpensive)?;
761 self.0 = self.0.saturating_add(weight);
762 self.1 = self.1.saturating_add(amount);
763 Ok(unused)
764 }
765
766 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
767 let weight = weight.min(self.0);
768 let amount = WeightToFee::weight_to_fee(&weight);
769 self.0 -= weight;
770 self.1 = self.1.saturating_sub(amount);
771 let amount: u128 = amount.saturated_into();
772 if amount > 0 {
773 Some((AssetId::get(), amount).into())
774 } else {
775 None
776 }
777 }
778}
779impl<
780 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
781 AssetId: Get<MultiLocation>,
782 AccountId,
783 Currency: CurrencyT<AccountId>,
784 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
785 > Drop
786 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
787{
788 fn drop(&mut self) {
789 OnUnbalanced::on_unbalanced(Currency::issue(self.1));
790 }
791}
792
793pub struct XcmConfig;
794impl Config for XcmConfig {
795 type Call = Call;
796 type XcmSender = XcmRouter;
797 // How to withdraw and deposit an asset.
798 type AssetTransactor = LocalAssetTransactor;
799 type OriginConverter = XcmOriginToTransactDispatchOrigin;
800 type IsReserve = NativeAsset;
801 type IsTeleporter = (); // Teleportation is disabled
802 type LocationInverter = LocationInverter<Ancestry>;
803 type Barrier = Barrier;
804 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
805 type Trader =
806 UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
807 type ResponseHandler = (); // Don't handle responses for now.
808 type SubscriptionService = PolkadotXcm;
809
810 type AssetTrap = PolkadotXcm;
811 type AssetClaims = PolkadotXcm;
812}
813
814// parameter_types! {
815// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
816// }
817
818/// No local origins on this chain are allowed to dispatch XCM sends/executions.
819pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
820
821/// The means for routing XCM messages which are not for local execution into the right message
822/// queues.
823pub type XcmRouter = (
824 // Two routers - use UMP to communicate with the relay chain:
825 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,
826 // ..and XCMP to communicate with the sibling chains.
827 XcmpQueue,
828);
829
830impl pallet_evm_coder_substrate::Config for Runtime {}
831
832impl pallet_xcm::Config for Runtime {
833 type Event = Event;
834 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
835 type XcmRouter = XcmRouter;
836 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
837 type XcmExecuteFilter = Everything;
838 type XcmExecutor = XcmExecutor<XcmConfig>;
839 type XcmTeleportFilter = Everything;
840 type XcmReserveTransferFilter = Everything;
841 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
842 type LocationInverter = LocationInverter<Ancestry>;
843 type Origin = Origin;
844 type Call = Call;
845 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
846 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
847}
848
849impl cumulus_pallet_xcm::Config for Runtime {
850 type Event = Event;
851 type XcmExecutor = XcmExecutor<XcmConfig>;
852}
853
854impl cumulus_pallet_xcmp_queue::Config for Runtime {
855 type WeightInfo = ();
856 type Event = Event;
857 type XcmExecutor = XcmExecutor<XcmConfig>;
858 type ChannelInfo = ParachainSystem;
859 type VersionWrapper = ();
860 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
861 type ControllerOrigin = EnsureRoot<AccountId>;
862 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
863}
864
865impl cumulus_pallet_dmp_queue::Config for Runtime {
866 type Event = Event;
867 type XcmExecutor = XcmExecutor<XcmConfig>;
868 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
869}
870
871impl pallet_aura::Config for Runtime {
872 type AuthorityId = AuraId;
873 type DisabledValidators = ();
874 type MaxAuthorities = MaxAuthorities;
875}
876
877parameter_types! {
878 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
879 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
880}
881
882impl pallet_common::Config for Runtime {
883 type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
884 type Event = Event;
885 type Currency = Balances;
886 type CollectionCreationPrice = CollectionCreationPrice;
887 type TreasuryAccountId = TreasuryAccountId;
888 type CollectionDispatch = CollectionDispatchT<Self>;
889
890 type EvmTokenAddressMapping = EvmTokenAddressMapping;
891 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
892 type ContractAddress = EvmCollectionHelpersAddress;
893}
894
895impl pallet_structure::Config for Runtime {
896 type Event = Event;
897 type Call = Call;
898 type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
899}
900
901impl pallet_fungible::Config for Runtime {
902 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
903}
904impl pallet_refungible::Config for Runtime {
905 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
906}
907impl pallet_nonfungible::Config for Runtime {
908 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
909}
910
911impl pallet_unique::Config for Runtime {
912 type Event = Event;
913 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
914 type CommonWeightInfo = CommonWeights<Self>;
915 type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
916}
917
918parameter_types! {
919 pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied
920}
921
922/// Used for the pallet inflation
923impl pallet_inflation::Config for Runtime {
924 type Currency = Balances;
925 type TreasuryAccountId = TreasuryAccountId;
926 type InflationBlockInterval = InflationBlockInterval;
927 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
928}
929
930parameter_types! {
931 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
932 RuntimeBlockWeights::get().max_block;
933 pub const MaxScheduledPerBlock: u32 = 50;
934}
935
936type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
937use frame_support::traits::NamedReservableCurrency;
938
939fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
940 (
941 frame_system::CheckSpecVersion::<Runtime>::new(),
942 frame_system::CheckGenesis::<Runtime>::new(),
943 frame_system::CheckEra::<Runtime>::from(Era::Immortal),
944 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
945 from,
946 )),
947 frame_system::CheckWeight::<Runtime>::new(),
948 // sponsoring transaction logic
949 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
950 )
951}
952
953pub struct SchedulerPaymentExecutor;
954impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
955 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
956where
957 <T as frame_system::Config>::Call: Member
958 + Dispatchable<Origin = Origin, Info = DispatchInfo>
959 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
960 + GetDispatchInfo
961 + From<frame_system::Call<Runtime>>,
962 SelfContainedSignedInfo: Send + Sync + 'static,
963 Call: From<<T as frame_system::Config>::Call>
964 + From<<T as pallet_unique_scheduler::Config>::Call>
965 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
966 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
967{
968 fn dispatch_call(
969 signer: <T as frame_system::Config>::AccountId,
970 call: <T as pallet_unique_scheduler::Config>::Call,
971 ) -> Result<
972 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
973 TransactionValidityError,
974 > {
975 let dispatch_info = call.get_dispatch_info();
976 let extrinsic = fp_self_contained::CheckedExtrinsic::<
977 AccountId,
978 Call,
979 SignedExtraScheduler,
980 SelfContainedSignedInfo,
981 > {
982 signed:
983 CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
984 signer.clone().into(),
985 get_signed_extras(signer.into()),
986 ),
987 function: call.into(),
988 };
989
990 extrinsic.apply::<Runtime>(&dispatch_info, 0)
991 }
992
993 fn reserve_balance(
994 id: [u8; 16],
995 sponsor: <T as frame_system::Config>::AccountId,
996 call: <T as pallet_unique_scheduler::Config>::Call,
997 count: u32,
998 ) -> Result<(), DispatchError> {
999 let dispatch_info = call.get_dispatch_info();
1000 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
1001 .saturating_mul(count.into());
1002
1003 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
1004 &id,
1005 &(sponsor.into()),
1006 weight,
1007 )
1008 }
1009
1010 fn pay_for_call(
1011 id: [u8; 16],
1012 sponsor: <T as frame_system::Config>::AccountId,
1013 call: <T as pallet_unique_scheduler::Config>::Call,
1014 ) -> Result<u128, DispatchError> {
1015 let dispatch_info = call.get_dispatch_info();
1016 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
1017 Ok(
1018 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
1019 &id,
1020 &(sponsor.into()),
1021 weight,
1022 ),
1023 )
1024 }
1025
1026 fn cancel_reserve(
1027 id: [u8; 16],
1028 sponsor: <T as frame_system::Config>::AccountId,
1029 ) -> Result<u128, DispatchError> {
1030 Ok(
1031 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
1032 &id,
1033 &(sponsor.into()),
1034 u128::MAX,
1035 ),
1036 )
1037 }
1038}
1039
1040parameter_types! {
1041 pub const NoPreimagePostponement: Option<u32> = Some(10);
1042 pub const Preimage: Option<u32> = Some(10);
1043}
1044
1045/// Used the compare the privilege of an origin inside the scheduler.
1046pub struct OriginPrivilegeCmp;
1047
1048impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
1049 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
1050 Some(Ordering::Equal)
1051 }
1052}
1053
1054impl pallet_unique_scheduler::Config for Runtime {
1055 type Event = Event;
1056 type Origin = Origin;
1057 type Currency = Balances;
1058 type PalletsOrigin = OriginCaller;
1059 type Call = Call;
1060 type MaximumWeight = MaximumSchedulerWeight;
1061 type ScheduleOrigin = EnsureSigned<AccountId>;
1062 type MaxScheduledPerBlock = MaxScheduledPerBlock;
1063 type WeightInfo = ();
1064 type CallExecutor = SchedulerPaymentExecutor;
1065 type OriginPrivilegeCmp = OriginPrivilegeCmp;
1066 type PreimageProvider = ();
1067 type NoPreimagePostponement = NoPreimagePostponement;
1068}
1069
1070type EvmSponsorshipHandler = (
1071 UniqueEthSponsorshipHandler<Runtime>,
1072 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
1073);
1074type SponsorshipHandler = (
1075 UniqueSponsorshipHandler<Runtime>,
1076 //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
1077 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
1078);
1079
1080impl pallet_evm_transaction_payment::Config for Runtime {
1081 type EvmSponsorshipHandler = EvmSponsorshipHandler;
1082 type Currency = Balances;
1083}
1084
1085impl pallet_charge_transaction::Config for Runtime {
1086 type SponsorshipHandler = SponsorshipHandler;
1087}
1088
1089// impl pallet_contract_helpers::Config for Runtime {
1090// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
1091// }
1092
1093parameter_types! {
1094 // 0x842899ECF380553E8a4de75bF534cdf6fBF64049
1095 pub const HelpersContractAddress: H160 = H160([
1096 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
1097 ]);
1098
1099 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
1100 pub const EvmCollectionHelpersAddress: H160 = H160([
1101 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
1102 ]);
1103}
1104
1105impl pallet_evm_contract_helpers::Config for Runtime {
1106 type ContractAddress = HelpersContractAddress;
1107 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
1108}
110960
1110construct_runtime!(61construct_runtime!(unique);
1111 pub enum Runtime where
1112 Block = Block,
1113 NodeBlock = opaque::Block,
1114 UncheckedExtrinsic = UncheckedExtrinsic
1115 {
1116 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
1117 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
1118
1119 Aura: pallet_aura::{Pallet, Config<T>} = 22,
1120 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
1121
1122 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
1123 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
1124 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
1125 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
1126 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
1127 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
1128 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
1129 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
1130 // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
1131 // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
1132
1133 // XCM helpers.
1134 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
1135 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
1136 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
1137 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
1138
1139 // Unique Pallets
1140 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
1141 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
1142 Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
1143 // free = 63
1144 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,
1145 // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
1146 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,
1147 Fungible: pallet_fungible::{Pallet, Storage} = 67,
1148 Refungible: pallet_refungible::{Pallet, Storage} = 68,
1149 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
1150 Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
1151
1152 // Frontier
1153 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
1154 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
1155
1156 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
1157 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
1158 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
1159 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
1160 }
1161);
1162
1163pub struct TransactionConverter;
1164
1165impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
1166 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
1167 UncheckedExtrinsic::new_unsigned(
1168 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1169 )
1170 }
1171}
1172
1173impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
1174 fn convert_transaction(
1175 &self,
1176 transaction: pallet_ethereum::Transaction,
1177 ) -> opaque::UncheckedExtrinsic {
1178 let extrinsic = UncheckedExtrinsic::new_unsigned(
1179 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
1180 );
1181 let encoded = extrinsic.encode();
1182 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
1183 .expect("Encoded extrinsic is always valid")
1184 }
1185}
1186
1187/// The address format for describing accounts.
1188pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1189/// Block header type as expected by this runtime.
1190pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1191/// Block type as expected by this runtime.
1192pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1193/// A Block signed with a Justification
1194pub type SignedBlock = generic::SignedBlock<Block>;
1195/// BlockId type as expected by this runtime.
1196pub type BlockId = generic::BlockId<Block>;
1197/// The SignedExtension to the basic transaction logic.
1198pub type SignedExtra = (
1199 frame_system::CheckSpecVersion<Runtime>,
1200 // system::CheckTxVersion<Runtime>,
1201 frame_system::CheckGenesis<Runtime>,
1202 frame_system::CheckEra<Runtime>,
1203 frame_system::CheckNonce<Runtime>,
1204 frame_system::CheckWeight<Runtime>,
1205 pallet_charge_transaction::ChargeTransactionPayment<Runtime>,
1206 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
1207 pallet_ethereum::FakeTransactionFinalizer<Runtime>,
1208);
1209pub type SignedExtraScheduler = (
1210 frame_system::CheckSpecVersion<Runtime>,
1211 frame_system::CheckGenesis<Runtime>,
1212 frame_system::CheckEra<Runtime>,
1213 frame_system::CheckNonce<Runtime>,
1214 frame_system::CheckWeight<Runtime>,
1215 // pallet_charge_transaction::ChargeTransactionPayment<Runtime>,
1216);
1217/// Unchecked extrinsic type as expected by this runtime.
1218pub type UncheckedExtrinsic =
1219 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
1220/// Extrinsic type that has already been checked.
1221pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
1222/// Executive: handles dispatch to the various modules.
1223pub type Executive = frame_executive::Executive<
1224 Runtime,
1225 Block,
1226 frame_system::ChainContext<Runtime>,
1227 Runtime,
1228 AllPalletsReversedWithSystemFirst,
1229>;
1230
1231impl_opaque_keys! {
1232 pub struct SessionKeys {
1233 pub aura: Aura,
1234 }
1235}
1236
1237impl fp_self_contained::SelfContainedCall for Call {
1238 type SignedInfo = H160;
1239
1240 fn is_self_contained(&self) -> bool {
1241 match self {
1242 Call::Ethereum(call) => call.is_self_contained(),
1243 _ => false,
1244 }
1245 }
1246
1247 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
1248 match self {
1249 Call::Ethereum(call) => call.check_self_contained(),
1250 _ => None,
1251 }
1252 }
1253
1254 fn validate_self_contained(
1255 &self,
1256 info: &Self::SignedInfo,
1257 dispatch_info: &DispatchInfoOf<Call>,
1258 len: usize,
1259 ) -> Option<TransactionValidity> {
1260 match self {
1261 Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
1262 _ => None,
1263 }
1264 }
1265
1266 fn pre_dispatch_self_contained(
1267 &self,
1268 info: &Self::SignedInfo,
1269 ) -> Option<Result<(), TransactionValidityError>> {
1270 match self {
1271 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
1272 _ => None,
1273 }
1274 }
1275
1276 fn apply_self_contained(
1277 self,
1278 info: Self::SignedInfo,
1279 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
1280 match self {
1281 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
1282 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
1283 )),
1284 _ => None,
1285 }
1286 }
1287}
1288
1289macro_rules! dispatch_unique_runtime {
1290 ($collection:ident.$method:ident($($name:ident),*)) => {{
1291 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
1292 let dispatch = collection.as_dyn();
1293
1294 Ok::<_, DispatchError>(dispatch.$method($($name),*))
1295 }};
1296}
129762
1298impl_common_runtime_apis! {63impl_common_runtime_apis!();
1299 #![custom_apis]
1300
1301 impl rmrk_rpc::RmrkApi<
1302 Block,
1303 AccountId,
1304 RmrkCollectionInfo<AccountId>,
1305 RmrkInstanceInfo<AccountId>,
1306 RmrkResourceInfo,
1307 RmrkPropertyInfo,
1308 RmrkBaseInfo<AccountId>,
1309 RmrkPartType,
1310 RmrkTheme
1311 > for Runtime {
1312 fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {
1313 Ok(Default::default())
1314 }
1315
1316 fn collection_by_id(_collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
1317 Ok(Default::default())
1318 }
1319
1320 fn nft_by_id(_collection_id: RmrkCollectionId, _nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
1321 Ok(Default::default())
1322 }
1323
1324 fn account_tokens(_account_id: AccountId, _collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
1325 Ok(Default::default())
1326 }
1327
1328 fn nft_children(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
1329 Ok(Default::default())
1330 }
1331
1332 fn collection_properties(_collection_id: RmrkCollectionId, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
1333 Ok(Default::default())
1334 }
1335
1336 fn nft_properties(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
1337 Ok(Default::default())
1338 }
1339
1340 fn nft_resources(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
1341 Ok(Default::default())
1342 }
1343
1344 fn nft_resource_priority(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId, _resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {
1345 Ok(Default::default())
1346 }
1347
1348 fn base(_base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
1349 Ok(Default::default())
1350 }
1351
1352 fn base_parts(_base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
1353 Ok(Default::default())
1354 }
1355
1356 fn theme_names(_base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
1357 Ok(Default::default())
1358 }
1359
1360 fn theme(_base_id: RmrkBaseId, _theme_name: RmrkThemeName, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
1361 Ok(Default::default())
1362 }
1363 }
1364}
1365
1366struct CheckInherents;
1367
1368impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
1369 fn check_inherents(
1370 block: &Block,
1371 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
1372 ) -> sp_inherents::CheckInherentsResult {
1373 let relay_chain_slot = relay_state_proof
1374 .read_slot()
1375 .expect("Could not read the relay chain slot from the proof");
1376
1377 let inherent_data =
1378 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
1379 relay_chain_slot,
1380 sp_std::time::Duration::from_secs(6),
1381 )
1382 .create_inherent_data()
1383 .expect("Could not create the timestamp inherent data");
1384
1385 inherent_data.check_extrinsics(block)
1386 }
1387}
138864
1389cumulus_pallet_parachain_system::register_validate_block!(65cumulus_pallet_parachain_system::register_validate_block!(
1390 Runtime = Runtime,66 Runtime = Runtime,
modifiedtests/package.jsondiffbeforeafterboth
8 "@polkadot/typegen": "8.7.2-15",8 "@polkadot/typegen": "8.7.2-15",
9 "@types/chai": "^4.3.1",9 "@types/chai": "^4.3.1",
10 "@types/chai-as-promised": "^7.1.5",10 "@types/chai-as-promised": "^7.1.5",
11 "@types/chai-like": "^1.1.1",
11 "@types/mocha": "^9.1.1",12 "@types/mocha": "^9.1.1",
12 "@types/node": "^17.0.35",13 "@types/node": "^17.0.35",
13 "@typescript-eslint/eslint-plugin": "^5.26.0",14 "@typescript-eslint/eslint-plugin": "^5.26.0",
96 "@polkadot/util-crypto": "9.4.1",97 "@polkadot/util-crypto": "9.4.1",
97 "bignumber.js": "^9.0.2",98 "bignumber.js": "^9.0.2",
98 "chai-as-promised": "^7.1.1",99 "chai-as-promised": "^7.1.1",
100 "chai-like": "^1.1.1",
99 "find-process": "^1.4.7",101 "find-process": "^1.4.7",
100 "solc": "0.8.14-fixed",102 "solc": "0.8.14-fixed",
101 "web3": "^1.7.3"103 "web3": "^1.7.3"
modifiedtests/src/approve.test.tsdiffbeforeafterboth
32 getCreatedCollectionCount,32 getCreatedCollectionCount,
33 transferFromExpectSuccess,33 transferFromExpectSuccess,
34 transferFromExpectFail,34 transferFromExpectFail,
35 requirePallets,
36 Pallets,
35} from './util/helpers';37} from './util/helpers';
3638
37chai.use(chaiAsPromised);39chai.use(chaiAsPromised);
49 });51 });
50 });52 });
53
54 it('[nft] Execute the extrinsic and check approvedList', async () => {
55 const nftCollectionId = await createCollectionExpectSuccess();
56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
58 });
59
60 it('[fungible] Execute the extrinsic and check approvedList', async () => {
61 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
62 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
63 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
64 });
65
66 it('[refungible] Execute the extrinsic and check approvedList', async function() {
67 await requirePallets(this, [Pallets.ReFungible]);
68
69 const reFungibleCollectionId =
70 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
71 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
72 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
73 });
74
75 it('[nft] Remove approval by using 0 amount', async () => {
76 const nftCollectionId = await createCollectionExpectSuccess();
77 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
78 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);
79 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);
80 });
5181
52 it('Execute the extrinsic and check approvedList', async () => {82 it('[fungible] Remove approval by using 0 amount', async () => {
53 const nftCollectionId = await createCollectionExpectSuccess();
54 // nft
55 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
56 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
57 // fungible
58 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});83 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
59 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');84 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
60 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);85 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
61 // reFungible
62 const reFungibleCollectionId =
63 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
64 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
65 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);86 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
66 });87 });
6788
68 it('Remove approval by using 0 amount', async () => {89 it('[refungible] Remove approval by using 0 amount', async function() {
69 const nftCollectionId = await createCollectionExpectSuccess();
70 // nft
71 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
72 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);90 await requirePallets(this, [Pallets.ReFungible]);
73 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);91
74 // fungible
75 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
76 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
77 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
78 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
79 // reFungible
80 const reFungibleCollectionId =92 const reFungibleCollectionId =
81 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});93 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
82 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');94 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
117 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);129 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
118 });130 });
119131
120 it('ReFungible up to an approved amount', async () => {132 it('ReFungible up to an approved amount', async function() {
133 await requirePallets(this, [Pallets.ReFungible]);
134
121 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});135 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
122 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);136 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
151 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');165 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');
152 });166 });
153167
154 it('ReFungible up to an approved amount', async () => {168 it('ReFungible up to an approved amount', async function() {
169 await requirePallets(this, [Pallets.ReFungible]);
170
155 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});171 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
156 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);172 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
188 await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);204 await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);
189 });205 });
190206
191 it('ReFungible up to an approved amount', async () => {207 it('ReFungible up to an approved amount', async function() {
208 await requirePallets(this, [Pallets.ReFungible]);
209
192 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});210 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
193 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);211 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
250 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);268 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);
251 });269 });
252270
253 it('ReFungible', async () => {271 it('ReFungible', async function() {
272 await requirePallets(this, [Pallets.ReFungible]);
273
254 const reFungibleCollectionId =274 const reFungibleCollectionId =
255 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});275 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
285 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);305 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);
286 });306 });
287307
288 it('ReFungible', async () => {308 it('ReFungible', async function() {
309 await requirePallets(this, [Pallets.ReFungible]);
310
289 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});311 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
290 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');312 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
325 await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');347 await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');
326 });348 });
327349
328 it('ReFungible up to an approved amount', async () => {350 it('ReFungible up to an approved amount', async function() {
351 await requirePallets(this, [Pallets.ReFungible]);
352
329 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});353 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
330 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});354 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
422 });446 });
423 });447 });
424448
425 it('Approve for a collection that does not exist', async () => {449 it('[nft] Approve for a collection that does not exist', async () => {
426 await usingApi(async (api: ApiPromise) => {450 await usingApi(async (api: ApiPromise) => {
427 // nft
428 const nftCollectionCount = await getCreatedCollectionCount(api);451 const nftCollectionCount = await getCreatedCollectionCount(api);
429 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);452 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
430 // fungible
431 const fungibleCollectionCount = await getCreatedCollectionCount(api);
432 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
433 // reFungible
434 const reFungibleCollectionCount = await getCreatedCollectionCount(api);
435 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
436 });453 });
437 });454 });
455
456 it('[fungible] Approve for a collection that does not exist', async () => {
457 await usingApi(async (api: ApiPromise) => {
458 const fungibleCollectionCount = await getCreatedCollectionCount(api);
459 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
460 });
461 });
462
463 it('[refungible] Approve for a collection that does not exist', async function() {
464 await requirePallets(this, [Pallets.ReFungible]);
465
466 await usingApi(async (api: ApiPromise) => {
467 const reFungibleCollectionCount = await getCreatedCollectionCount(api);
468 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
469 });
470 });
471
472 it('[nft] Approve for a collection that was destroyed', async () => {
473 const nftCollectionId = await createCollectionExpectSuccess();
474 await destroyCollectionExpectSuccess(nftCollectionId);
475 await approveExpectFail(nftCollectionId, 1, alice, bob);
476 });
438477
439 it('Approve for a collection that was destroyed', async () => {478 it('Approve for a collection that was destroyed', async () => {
440 // nft
441 const nftCollectionId = await createCollectionExpectSuccess();
442 await destroyCollectionExpectSuccess(nftCollectionId);
443 await approveExpectFail(nftCollectionId, 1, alice, bob);
444 // fungible
445 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});479 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
446 await destroyCollectionExpectSuccess(fungibleCollectionId);480 await destroyCollectionExpectSuccess(fungibleCollectionId);
447 await approveExpectFail(fungibleCollectionId, 0, alice, bob);481 await approveExpectFail(fungibleCollectionId, 0, alice, bob);
448 // reFungible
449 const reFungibleCollectionId =
450 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
451 await destroyCollectionExpectSuccess(reFungibleCollectionId);
452 await approveExpectFail(reFungibleCollectionId, 1, alice, bob);
453 });482 });
483
484 it('[refungible] Approve for a collection that was destroyed', async function() {
485 await requirePallets(this, [Pallets.ReFungible]);
486
487 const reFungibleCollectionId =
488 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
489 await destroyCollectionExpectSuccess(reFungibleCollectionId);
490 await approveExpectFail(reFungibleCollectionId, 1, alice, bob);
491 });
492
493 it('[nft] Approve transfer of a token that does not exist', async () => {
494 const nftCollectionId = await createCollectionExpectSuccess();
495 await approveExpectFail(nftCollectionId, 2, alice, bob);
496 });
454497
455 it('Approve transfer of a token that does not exist', async () => {498 it('[refungible] Approve transfer of a token that does not exist', async function() {
456 // nft
457 const nftCollectionId = await createCollectionExpectSuccess();
458 await approveExpectFail(nftCollectionId, 2, alice, bob);499 await requirePallets(this, [Pallets.ReFungible]);
459 // reFungible500
460 const reFungibleCollectionId =501 const reFungibleCollectionId =
461 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});502 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
462 await approveExpectFail(reFungibleCollectionId, 2, alice, bob);503 await approveExpectFail(reFungibleCollectionId, 2, alice, bob);
463 });504 });
505
506 it('[nft] Approve using the address that does not own the approved token', async () => {
507 const nftCollectionId = await createCollectionExpectSuccess();
508 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
509 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);
510 });
511
512 it('[fungible] Approve using the address that does not own the approved token', async () => {
513 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
514 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
515 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);
516 });
464517
465 it('Approve using the address that does not own the approved token', async () => {518 it('[refungible] Approve using the address that does not own the approved token', async function() {
466 const nftCollectionId = await createCollectionExpectSuccess();
467 // nft
468 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
469 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);
470 // fungible
471 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});519 await requirePallets(this, [Pallets.ReFungible]);
472 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');520
473 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);
474 // reFungible
475 const reFungibleCollectionId =521 const reFungibleCollectionId =
476 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});522 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
477 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');523 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
478 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);524 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);
479 });525 });
480526
481 it('should fail if approved more ReFungibles than owned', async () => {527 it('should fail if approved more ReFungibles than owned', async function() {
528 await requirePallets(this, [Pallets.ReFungible]);
529
482 const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});530 const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
483 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');531 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
25 getBalance,25 getBalance,
26 setCollectionLimitsExpectSuccess,26 setCollectionLimitsExpectSuccess,
27 isTokenExists,27 isTokenExists,
28 requirePallets,
29 Pallets,
28} from './util/helpers';30} from './util/helpers';
2931
30import chai from 'chai';32import chai from 'chai';
80 });82 });
81 });83 });
8284
83 it('Burn item in ReFungible collection', async () => {85 it('Burn item in ReFungible collection', async function() {
86 await requirePallets(this, [Pallets.ReFungible]);
87
84 const createMode = 'ReFungible';88 const createMode = 'ReFungible';
85 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});89 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
99 });103 });
100 });104 });
101105
102 it('Burn owned portion of item in ReFungible collection', async () => {106 it('Burn owned portion of item in ReFungible collection', async function() {
107 await requirePallets(this, [Pallets.ReFungible]);
108
103 const createMode = 'ReFungible';109 const createMode = 'ReFungible';
104 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});110 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
189 });195 });
190196
191 // TODO: burnFrom197 // TODO: burnFrom
192 it('Burn item in ReFungible collection', async () => {198 it('Burn item in ReFungible collection', async function() {
199 await requirePallets(this, [Pallets.ReFungible]);
200
193 const createMode = 'ReFungible';201 const createMode = 'ReFungible';
194 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});202 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
33 addCollectionAdminExpectSuccess,33 addCollectionAdminExpectSuccess,
34 getCreatedCollectionCount,34 getCreatedCollectionCount,
35 UNIQUE,35 UNIQUE,
36 requirePallets,
37 Pallets,
36} from './util/helpers';38} from './util/helpers';
37import {IKeyringPair} from '@polkadot/types/types';39import {IKeyringPair} from '@polkadot/types/types';
3840
124 });126 });
125 });127 });
126128
127 it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => {129 it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {
130 await requirePallets(this, [Pallets.ReFungible]);
131
128 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});132 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
129 await setCollectionSponsorExpectSuccess(collectionId, bob.address);133 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
252 });256 });
253 });257 });
254258
255 it('ReFungible: Sponsoring is rate limited', async () => {259 it('ReFungible: Sponsoring is rate limited', async function() {
260 await requirePallets(this, [Pallets.ReFungible]);
261
256 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});262 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
257 await setCollectionSponsorExpectSuccess(collectionId, bob.address);263 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
1616
17import {expect} from 'chai';17import {expect} from 'chai';
18import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';18import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
19import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess} from './util/helpers';19import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess, requirePallets, Pallets} from './util/helpers';
2020
21describe('integration test: ext. createCollection():', () => {21describe('integration test: ext. createCollection():', () => {
22 it('Create new NFT collection', async () => {22 it('Create new NFT collection', async () => {
34 it('Create new Fungible collection', async () => {34 it('Create new Fungible collection', async () => {
35 await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});35 await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
36 });36 });
37 it('Create new ReFungible collection', async () => {37 it('Create new ReFungible collection', async function() {
38 await requirePallets(this, [Pallets.ReFungible]);
39
38 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});40 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
39 });41 });
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
29 itApi,29 itApi,
30 normalizeAccountId,30 normalizeAccountId,
31 getCreateItemResult,31 getCreateItemResult,
32 requirePallets,
33 Pallets,
32} from './util/helpers';34} from './util/helpers';
3335
34const expect = chai.expect;36const expect = chai.expect;
79 }81 }
8082
81 });83 });
82 it('Create new item in ReFungible collection', async () => {84 it('Create new item in ReFungible collection', async function() {
85 await requirePallets(this, [Pallets.ReFungible]);
86
83 const createMode = 'ReFungible';87 const createMode = 'ReFungible';
84 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});88 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
96 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);100 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
97 await createItemExpectSuccess(bob, newCollectionID, createMode);101 await createItemExpectSuccess(bob, newCollectionID, createMode);
98 });102 });
99 it('Create new item in ReFungible collection with collection admin permissions', async () => {103 it('Create new item in ReFungible collection with collection admin permissions', async function() {
104 await requirePallets(this, [Pallets.ReFungible]);
105
100 const createMode = 'ReFungible';106 const createMode = 'ReFungible';
101 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});107 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
175 });181 });
176 });182 });
177183
178 it('Check total pieces of ReFungible token', async () => {184 it('Check total pieces of ReFungible token', async function() {
185 await requirePallets(this, [Pallets.ReFungible]);
186
179 await usingApi(async api => {187 await usingApi(async api => {
180 const createMode = 'ReFungible';188 const createMode = 'ReFungible';
219 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});227 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
220 await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;228 await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
221 });229 });
222 it('Regular user cannot create new item in ReFungible collection', async () => {230 it('Regular user cannot create new item in ReFungible collection', async function() {
231 await requirePallets(this, [Pallets.ReFungible]);
232
223 const createMode = 'ReFungible';233 const createMode = 'ReFungible';
224 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});234 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
296 });306 });
297 });307 });
298308
299 it('Check total pieces for invalid Refungible token', async () => {309 it('Check total pieces for invalid Refungible token', async function() {
310 await requirePallets(this, [Pallets.ReFungible]);
311
300 await usingApi(async api => {312 await usingApi(async api => {
301 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});313 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
33 createCollectionWithPropsExpectSuccess,33 createCollectionWithPropsExpectSuccess,
34 createMultipleItemsWithPropsExpectSuccess,34 createMultipleItemsWithPropsExpectSuccess,
35 getTokenProperties,35 getTokenProperties,
36 requirePallets,
37 Pallets,
38 checkPalletsPresence,
36} from './util/helpers';39} from './util/helpers';
3740
38chai.use(chaiAsPromised);41chai.use(chaiAsPromised);
91 });94 });
92 });95 });
9396
94 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {97 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async function() {
98 await requirePallets(this, [Pallets.ReFungible]);
99
95 await usingApi(async (api, privateKeyWrapper) => {100 await usingApi(async (api, privateKeyWrapper) => {
96 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});101 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
272 });277 });
273 });278 });
274279
275 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {280 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async function() {
281 await requirePallets(this, [Pallets.ReFungible]);
282
276 await usingApi(async (api: ApiPromise) => {283 await usingApi(async (api: ApiPromise) => {
277 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});284 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
335 });342 });
336 });343 });
337344
338 it('Regular user cannot create items in active ReFungible collection', async () => {345 it('Regular user cannot create items in active ReFungible collection', async function() {
346 await requirePallets(this, [Pallets.ReFungible]);
347
339 await usingApi(async (api: ApiPromise) => {348 await usingApi(async (api: ApiPromise) => {
340 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});349 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
358 });367 });
359 });368 });
369
370 it('Create NFTs that has reached the maximum data limit', async function() {
371 await usingApi(async (api, privateKeyWrapper) => {
372 const collectionId = await createCollectionWithPropsExpectSuccess({
373 propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}],
374 });
375 const alice = privateKeyWrapper('//Alice');
376 const args = [
377 {NFT: {properties: [{key: 'key', value: 'A'.repeat(32769)}]}},
378 {NFT: {properties: [{key: 'key', value: 'B'.repeat(32769)}]}},
379 {NFT: {properties: [{key: 'key', value: 'C'.repeat(32769)}]}},
380 ];
381 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
382 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
383 });
384 });
360385
361 it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {386 it('Create Refungible tokens that has reached the maximum data limit', async function() {
387 await requirePallets(this, [Pallets.ReFungible]);
388
362 await usingApi(async (api, privateKeyWrapper) => {389 await usingApi(async api => {
363 // NFT
364 const collectionId = await createCollectionWithPropsExpectSuccess({
365 propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}],
366 });
367 const alice = privateKeyWrapper('//Alice');
368 const args = [
369 {NFT: {properties: [{key: 'key', value: 'A'.repeat(32769)}]}},
370 {NFT: {properties: [{key: 'key', value: 'B'.repeat(32769)}]}},
371 {NFT: {properties: [{key: 'key', value: 'C'.repeat(32769)}]}},
372 ];
373 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
374 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
375
376 // ReFungible
377 const collectionIdReFungible =390 const collectionIdReFungible =
378 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});391 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
379 {392 {
403 await usingApi(async (api: ApiPromise) => {416 await usingApi(async (api: ApiPromise) => {
404 const collectionId = await createCollectionExpectSuccess();417 const collectionId = await createCollectionExpectSuccess();
418
419 const types = ['NFT', 'Fungible'];
420
421 if (await checkPalletsPresence([Pallets.ReFungible])) {
422 types.push('ReFungible');
423 }
424
405 const createMultipleItemsTx = api.tx.unique425 const createMultipleItemsTx = api.tx.unique
406 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);426 .createMultipleItems(collectionId, normalizeAccountId(alice.address), types);
407 await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/nonfungible\.NotNonfungibleDataUsedToMintFungibleCollectionToken/);427 await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/nonfungible\.NotNonfungibleDataUsedToMintFungibleCollectionToken/);
408 // garbage collection :-D // lol428 // garbage collection :-D // lol
409 await destroyCollectionExpectSuccess(collectionId);429 await destroyCollectionExpectSuccess(collectionId);
modifiedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
1616
17import {expect} from 'chai';17import {expect} from 'chai';
18import usingApi, {executeTransaction} from './substrate/substrate-api';18import usingApi, {executeTransaction} from './substrate/substrate-api';
19import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId, getTokenProperties} from './util/helpers';19import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId, getTokenProperties, requirePallets, Pallets} from './util/helpers';
2020
21describe.only('Integration Test: createMultipleItemsEx', () => {21describe('Integration Test: createMultipleItemsEx', () => {
22 it('can initialize multiple NFT with different owners', async () => {22 it('can initialize multiple NFT with different owners', async () => {
23 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});23 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
24 await usingApi(async (api, privateKeyWrapper) => {24 await usingApi(async (api, privateKeyWrapper) => {
146 });146 });
147 });147 });
148148
149 it('can initialize an RFT with multiple owners', async () => {149 it('can initialize an RFT with multiple owners', async function() {
150 await requirePallets(this, [Pallets.ReFungible]);
151
150 await usingApi(async (api, privateKeyWrapper) => {152 await usingApi(async (api, privateKeyWrapper) => {
151 const alice = privateKeyWrapper('//Alice');153 const alice = privateKeyWrapper('//Alice');
178 });180 });
179 });181 });
180182
181 it('can initialize multiple RFTs with the same owner', async () => {183 it('can initialize multiple RFTs with the same owner', async function() {
184 await requirePallets(this, [Pallets.ReFungible]);
185
182 await usingApi(async (api, privateKeyWrapper) => {186 await usingApi(async (api, privateKeyWrapper) => {
183 const alice = privateKeyWrapper('//Alice');187 const alice = privateKeyWrapper('//Alice');
389 });393 });
390 });394 });
391
392 it('fails when trying to set multiple owners when creating multiple refungibles', async () => {
393 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
394
395 await usingApi(async (api, privateKeyWrapper) => {
396 const alice = privateKeyWrapper('//Alice');
397 const bob = privateKeyWrapper('//Bob');
398 // Polkadot requires map, and yet requires keys to be JSON encoded
399 const users = new Map();
400 users.set(JSON.stringify({substrate: alice.address}), 1);
401 users.set(JSON.stringify({substrate: bob.address}), 1);
402
403 // TODO: better error message?
404 await expect(executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
405 RefungibleMultipleItems: [
406 {users},
407 {users},
408 ],
409 }))).to.be.rejectedWith(/^refungible\.NotRefungibleDataUsedToMintFungibleCollectionToken$/);
410 });
411 });
412});395});
413396
modifiedtests/src/destroyCollection.test.tsdiffbeforeafterboth
25 addCollectionAdminExpectSuccess,25 addCollectionAdminExpectSuccess,
26 getCreatedCollectionCount,26 getCreatedCollectionCount,
27 createItemExpectSuccess,27 createItemExpectSuccess,
28 requirePallets,
29 Pallets,
28} from './util/helpers';30} from './util/helpers';
2931
30chai.use(chaiAsPromised);32chai.use(chaiAsPromised);
38 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});40 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
39 await destroyCollectionExpectSuccess(collectionId);41 await destroyCollectionExpectSuccess(collectionId);
40 });42 });
41 it('ReFungible collection can be destroyed', async () => {43 it('ReFungible collection can be destroyed', async function() {
44 await requirePallets(this, [Pallets.ReFungible]);
45
42 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});46 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
43 await destroyCollectionExpectSuccess(collectionId);47 await destroyCollectionExpectSuccess(collectionId);
modifiedtests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth
48 string memory name,48 string memory name,
49 string memory description,49 string memory description,
50 string memory tokenPrefix50 string memory tokenPrefix
51 ) external view returns (address);51 ) external returns (address);
5252
53 // Selector: createERC721MetadataCompatibleRFTCollection(string,string,string,string) a559638853 // Selector: createERC721MetadataCompatibleRFTCollection(string,string,string,string) a5596388
54 function createERC721MetadataCompatibleRFTCollection(54 function createERC721MetadataCompatibleRFTCollection(
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
22 );22 );
23}23}
24
25// Selector: 6cf113cd
26interface Collection is Dummy, ERC165 {
27 // Set collection property.
28 //
29 // @param key Property key.
30 // @param value Propery value.
31 //
32 // Selector: setCollectionProperty(string,bytes) 2f073f66
33 function setCollectionProperty(string memory key, bytes memory value)
34 external;
35
36 // Delete collection property.
37 //
38 // @param key Property key.
39 //
40 // Selector: deleteCollectionProperty(string) 7b7debce
41 function deleteCollectionProperty(string memory key) external;
42
43 // Get collection property.
44 //
45 // @dev Throws error if key not found.
46 //
47 // @param key Property key.
48 // @return bytes The property corresponding to the key.
49 //
50 // Selector: collectionProperty(string) cf24fd6d
51 function collectionProperty(string memory key)
52 external
53 view
54 returns (bytes memory);
55
56 // Set the sponsor of the collection.
57 //
58 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
59 //
60 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
61 //
62 // Selector: setCollectionSponsor(address) 7623402e
63 function setCollectionSponsor(address sponsor) external;
64
65 // Collection sponsorship confirmation.
66 //
67 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
68 //
69 // Selector: confirmCollectionSponsorship() 3c50e97a
70 function confirmCollectionSponsorship() external;
71
72 // Set limits for the collection.
73 // @dev Throws error if limit not found.
74 // @param limit Name of the limit. Valid names:
75 // "accountTokenOwnershipLimit",
76 // "sponsoredDataSize",
77 // "sponsoredDataRateLimit",
78 // "tokenLimit",
79 // "sponsorTransferTimeout",
80 // "sponsorApproveTimeout"
81 // @param value Value of the limit.
82 //
83 // Selector: setCollectionLimit(string,uint32) 6a3841db
84 function setCollectionLimit(string memory limit, uint32 value) external;
85
86 // Set limits for the collection.
87 // @dev Throws error if limit not found.
88 // @param limit Name of the limit. Valid names:
89 // "ownerCanTransfer",
90 // "ownerCanDestroy",
91 // "transfersEnabled"
92 // @param value Value of the limit.
93 //
94 // Selector: setCollectionLimit(string,bool) 993b7fba
95 function setCollectionLimit(string memory limit, bool value) external;
96
97 // Get contract address.
98 //
99 // Selector: contractAddress() f6b4dfb4
100 function contractAddress() external view returns (address);
101
102 // Add collection admin by substrate address.
103 // @param new_admin Substrate administrator address.
104 //
105 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
106 function addCollectionAdminSubstrate(uint256 newAdmin) external;
107
108 // Remove collection admin by substrate address.
109 // @param admin Substrate administrator address.
110 //
111 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
112 function removeCollectionAdminSubstrate(uint256 admin) external;
113
114 // Add collection admin.
115 // @param new_admin Address of the added administrator.
116 //
117 // Selector: addCollectionAdmin(address) 92e462c7
118 function addCollectionAdmin(address newAdmin) external;
119
120 // Remove collection admin.
121 //
122 // @param new_admin Address of the removed administrator.
123 //
124 // Selector: removeCollectionAdmin(address) fafd7b42
125 function removeCollectionAdmin(address admin) external;
126
127 // Toggle accessibility of collection nesting.
128 //
129 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
130 //
131 // Selector: setCollectionNesting(bool) 112d4586
132 function setCollectionNesting(bool enable) external;
133
134 // Toggle accessibility of collection nesting.
135 //
136 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
137 // @param collections Addresses of collections that will be available for nesting.
138 //
139 // Selector: setCollectionNesting(bool,address[]) 64872396
140 function setCollectionNesting(bool enable, address[] memory collections)
141 external;
142
143 // Set the collection access method.
144 // @param mode Access mode
145 // 0 for Normal
146 // 1 for AllowList
147 //
148 // Selector: setCollectionAccess(uint8) 41835d4c
149 function setCollectionAccess(uint8 mode) external;
150
151 // Add the user to the allowed list.
152 //
153 // @param user Address of a trusted user.
154 //
155 // Selector: addToCollectionAllowList(address) 67844fe6
156 function addToCollectionAllowList(address user) external;
157
158 // Remove the user from the allowed list.
159 //
160 // @param user Address of a removed user.
161 //
162 // Selector: removeFromCollectionAllowList(address) 85c51acb
163 function removeFromCollectionAllowList(address user) external;
164
165 // Switch permission for minting.
166 //
167 // @param mode Enable if "true".
168 //
169 // Selector: setCollectionMintMode(bool) 00018e84
170 function setCollectionMintMode(bool mode) external;
171
172 // Check that account is the owner or admin of the collection
173 //
174 // @param user account to verify
175 // @return "true" if account is the owner or admin
176 //
177 // Selector: verifyOwnerOrAdmin(address) c2282493
178 function verifyOwnerOrAdmin(address user) external view returns (bool);
179
180 // Returns collection type
181 //
182 // @return `Fungible` or `NFT` or `ReFungible`
183 //
184 // Selector: uniqueCollectionType() d34b55b8
185 function uniqueCollectionType() external returns (string memory);
186}
24187
25// Selector: 79cc6790188// Selector: 79cc6790
26interface ERC20UniqueExtensions is Dummy, ERC165 {189interface ERC20UniqueExtensions is Dummy, ERC165 {
27 // Selector: burnFrom(address,uint256) 79cc6790190 // Selector: burnFrom(address,uint256) 79cc6790
28 function burnFrom(address from, uint256 amount) external returns (bool);191 function burnFrom(address from, uint256 amount) external returns (bool);
29}192}
30
31// Selector: 7d9262e6
32interface Collection is Dummy, ERC165 {
33 // Set collection property.
34 //
35 // @param key Property key.
36 // @param value Propery value.
37 //
38 // Selector: setCollectionProperty(string,bytes) 2f073f66
39 function setCollectionProperty(string memory key, bytes memory value)
40 external;
41
42 // Delete collection property.
43 //
44 // @param key Property key.
45 //
46 // Selector: deleteCollectionProperty(string) 7b7debce
47 function deleteCollectionProperty(string memory key) external;
48
49 // Get collection property.
50 //
51 // @dev Throws error if key not found.
52 //
53 // @param key Property key.
54 // @return bytes The property corresponding to the key.
55 //
56 // Selector: collectionProperty(string) cf24fd6d
57 function collectionProperty(string memory key)
58 external
59 view
60 returns (bytes memory);
61
62 // Set the sponsor of the collection.
63 //
64 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
65 //
66 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
67 //
68 // Selector: setCollectionSponsor(address) 7623402e
69 function setCollectionSponsor(address sponsor) external;
70
71 // Collection sponsorship confirmation.
72 //
73 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
74 //
75 // Selector: confirmCollectionSponsorship() 3c50e97a
76 function confirmCollectionSponsorship() external;
77
78 // Set limits for the collection.
79 // @dev Throws error if limit not found.
80 // @param limit Name of the limit. Valid names:
81 // "accountTokenOwnershipLimit",
82 // "sponsoredDataSize",
83 // "sponsoredDataRateLimit",
84 // "tokenLimit",
85 // "sponsorTransferTimeout",
86 // "sponsorApproveTimeout"
87 // @param value Value of the limit.
88 //
89 // Selector: setCollectionLimit(string,uint32) 6a3841db
90 function setCollectionLimit(string memory limit, uint32 value) external;
91
92 // Set limits for the collection.
93 // @dev Throws error if limit not found.
94 // @param limit Name of the limit. Valid names:
95 // "ownerCanTransfer",
96 // "ownerCanDestroy",
97 // "transfersEnabled"
98 // @param value Value of the limit.
99 //
100 // Selector: setCollectionLimit(string,bool) 993b7fba
101 function setCollectionLimit(string memory limit, bool value) external;
102
103 // Get contract address.
104 //
105 // Selector: contractAddress() f6b4dfb4
106 function contractAddress() external view returns (address);
107
108 // Add collection admin by substrate address.
109 // @param new_admin Substrate administrator address.
110 //
111 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
112 function addCollectionAdminSubstrate(uint256 newAdmin) external;
113
114 // Remove collection admin by substrate address.
115 // @param admin Substrate administrator address.
116 //
117 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
118 function removeCollectionAdminSubstrate(uint256 admin) external;
119
120 // Add collection admin.
121 // @param new_admin Address of the added administrator.
122 //
123 // Selector: addCollectionAdmin(address) 92e462c7
124 function addCollectionAdmin(address newAdmin) external;
125
126 // Remove collection admin.
127 //
128 // @param new_admin Address of the removed administrator.
129 //
130 // Selector: removeCollectionAdmin(address) fafd7b42
131 function removeCollectionAdmin(address admin) external;
132
133 // Toggle accessibility of collection nesting.
134 //
135 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
136 //
137 // Selector: setCollectionNesting(bool) 112d4586
138 function setCollectionNesting(bool enable) external;
139
140 // Toggle accessibility of collection nesting.
141 //
142 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
143 // @param collections Addresses of collections that will be available for nesting.
144 //
145 // Selector: setCollectionNesting(bool,address[]) 64872396
146 function setCollectionNesting(bool enable, address[] memory collections)
147 external;
148
149 // Set the collection access method.
150 // @param mode Access mode
151 // 0 for Normal
152 // 1 for AllowList
153 //
154 // Selector: setCollectionAccess(uint8) 41835d4c
155 function setCollectionAccess(uint8 mode) external;
156
157 // Add the user to the allowed list.
158 //
159 // @param user Address of a trusted user.
160 //
161 // Selector: addToCollectionAllowList(address) 67844fe6
162 function addToCollectionAllowList(address user) external;
163
164 // Remove the user from the allowed list.
165 //
166 // @param user Address of a removed user.
167 //
168 // Selector: removeFromCollectionAllowList(address) 85c51acb
169 function removeFromCollectionAllowList(address user) external;
170
171 // Switch permission for minting.
172 //
173 // @param mode Enable if "true".
174 //
175 // Selector: setCollectionMintMode(bool) 00018e84
176 function setCollectionMintMode(bool mode) external;
177}
178193
179// Selector: 942e8b22194// Selector: 942e8b22
180interface ERC20 is Dummy, ERC165, ERC20Events {195interface ERC20 is Dummy, ERC165, ERC20Events {
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
250 function finishMinting() external returns (bool);250 function finishMinting() external returns (bool);
251}251}
252
253// Selector: 6cf113cd
254interface Collection is Dummy, ERC165 {
255 // Set collection property.
256 //
257 // @param key Property key.
258 // @param value Propery value.
259 //
260 // Selector: setCollectionProperty(string,bytes) 2f073f66
261 function setCollectionProperty(string memory key, bytes memory value)
262 external;
263
264 // Delete collection property.
265 //
266 // @param key Property key.
267 //
268 // Selector: deleteCollectionProperty(string) 7b7debce
269 function deleteCollectionProperty(string memory key) external;
270
271 // Get collection property.
272 //
273 // @dev Throws error if key not found.
274 //
275 // @param key Property key.
276 // @return bytes The property corresponding to the key.
277 //
278 // Selector: collectionProperty(string) cf24fd6d
279 function collectionProperty(string memory key)
280 external
281 view
282 returns (bytes memory);
283
284 // Set the sponsor of the collection.
285 //
286 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
287 //
288 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
289 //
290 // Selector: setCollectionSponsor(address) 7623402e
291 function setCollectionSponsor(address sponsor) external;
292
293 // Collection sponsorship confirmation.
294 //
295 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
296 //
297 // Selector: confirmCollectionSponsorship() 3c50e97a
298 function confirmCollectionSponsorship() external;
299
300 // Set limits for the collection.
301 // @dev Throws error if limit not found.
302 // @param limit Name of the limit. Valid names:
303 // "accountTokenOwnershipLimit",
304 // "sponsoredDataSize",
305 // "sponsoredDataRateLimit",
306 // "tokenLimit",
307 // "sponsorTransferTimeout",
308 // "sponsorApproveTimeout"
309 // @param value Value of the limit.
310 //
311 // Selector: setCollectionLimit(string,uint32) 6a3841db
312 function setCollectionLimit(string memory limit, uint32 value) external;
313
314 // Set limits for the collection.
315 // @dev Throws error if limit not found.
316 // @param limit Name of the limit. Valid names:
317 // "ownerCanTransfer",
318 // "ownerCanDestroy",
319 // "transfersEnabled"
320 // @param value Value of the limit.
321 //
322 // Selector: setCollectionLimit(string,bool) 993b7fba
323 function setCollectionLimit(string memory limit, bool value) external;
324
325 // Get contract address.
326 //
327 // Selector: contractAddress() f6b4dfb4
328 function contractAddress() external view returns (address);
329
330 // Add collection admin by substrate address.
331 // @param new_admin Substrate administrator address.
332 //
333 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
334 function addCollectionAdminSubstrate(uint256 newAdmin) external;
335
336 // Remove collection admin by substrate address.
337 // @param admin Substrate administrator address.
338 //
339 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
340 function removeCollectionAdminSubstrate(uint256 admin) external;
341
342 // Add collection admin.
343 // @param new_admin Address of the added administrator.
344 //
345 // Selector: addCollectionAdmin(address) 92e462c7
346 function addCollectionAdmin(address newAdmin) external;
347
348 // Remove collection admin.
349 //
350 // @param new_admin Address of the removed administrator.
351 //
352 // Selector: removeCollectionAdmin(address) fafd7b42
353 function removeCollectionAdmin(address admin) external;
354
355 // Toggle accessibility of collection nesting.
356 //
357 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
358 //
359 // Selector: setCollectionNesting(bool) 112d4586
360 function setCollectionNesting(bool enable) external;
361
362 // Toggle accessibility of collection nesting.
363 //
364 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
365 // @param collections Addresses of collections that will be available for nesting.
366 //
367 // Selector: setCollectionNesting(bool,address[]) 64872396
368 function setCollectionNesting(bool enable, address[] memory collections)
369 external;
370
371 // Set the collection access method.
372 // @param mode Access mode
373 // 0 for Normal
374 // 1 for AllowList
375 //
376 // Selector: setCollectionAccess(uint8) 41835d4c
377 function setCollectionAccess(uint8 mode) external;
378
379 // Add the user to the allowed list.
380 //
381 // @param user Address of a trusted user.
382 //
383 // Selector: addToCollectionAllowList(address) 67844fe6
384 function addToCollectionAllowList(address user) external;
385
386 // Remove the user from the allowed list.
387 //
388 // @param user Address of a removed user.
389 //
390 // Selector: removeFromCollectionAllowList(address) 85c51acb
391 function removeFromCollectionAllowList(address user) external;
392
393 // Switch permission for minting.
394 //
395 // @param mode Enable if "true".
396 //
397 // Selector: setCollectionMintMode(bool) 00018e84
398 function setCollectionMintMode(bool mode) external;
399
400 // Check that account is the owner or admin of the collection
401 //
402 // @param user account to verify
403 // @return "true" if account is the owner or admin
404 //
405 // Selector: verifyOwnerOrAdmin(address) c2282493
406 function verifyOwnerOrAdmin(address user) external view returns (bool);
407
408 // Returns collection type
409 //
410 // @return `Fungible` or `NFT` or `ReFungible`
411 //
412 // Selector: uniqueCollectionType() d34b55b8
413 function uniqueCollectionType() external returns (string memory);
414}
252415
253// Selector: 780e9d63416// Selector: 780e9d63
254interface ERC721Enumerable is Dummy, ERC165 {417interface ERC721Enumerable is Dummy, ERC165 {
276 function totalSupply() external view returns (uint256);439 function totalSupply() external view returns (uint256);
277}440}
278
279// Selector: 7d9262e6
280interface Collection is Dummy, ERC165 {
281 // Set collection property.
282 //
283 // @param key Property key.
284 // @param value Propery value.
285 //
286 // Selector: setCollectionProperty(string,bytes) 2f073f66
287 function setCollectionProperty(string memory key, bytes memory value)
288 external;
289
290 // Delete collection property.
291 //
292 // @param key Property key.
293 //
294 // Selector: deleteCollectionProperty(string) 7b7debce
295 function deleteCollectionProperty(string memory key) external;
296
297 // Get collection property.
298 //
299 // @dev Throws error if key not found.
300 //
301 // @param key Property key.
302 // @return bytes The property corresponding to the key.
303 //
304 // Selector: collectionProperty(string) cf24fd6d
305 function collectionProperty(string memory key)
306 external
307 view
308 returns (bytes memory);
309
310 // Set the sponsor of the collection.
311 //
312 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
313 //
314 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
315 //
316 // Selector: setCollectionSponsor(address) 7623402e
317 function setCollectionSponsor(address sponsor) external;
318
319 // Collection sponsorship confirmation.
320 //
321 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
322 //
323 // Selector: confirmCollectionSponsorship() 3c50e97a
324 function confirmCollectionSponsorship() external;
325
326 // Set limits for the collection.
327 // @dev Throws error if limit not found.
328 // @param limit Name of the limit. Valid names:
329 // "accountTokenOwnershipLimit",
330 // "sponsoredDataSize",
331 // "sponsoredDataRateLimit",
332 // "tokenLimit",
333 // "sponsorTransferTimeout",
334 // "sponsorApproveTimeout"
335 // @param value Value of the limit.
336 //
337 // Selector: setCollectionLimit(string,uint32) 6a3841db
338 function setCollectionLimit(string memory limit, uint32 value) external;
339
340 // Set limits for the collection.
341 // @dev Throws error if limit not found.
342 // @param limit Name of the limit. Valid names:
343 // "ownerCanTransfer",
344 // "ownerCanDestroy",
345 // "transfersEnabled"
346 // @param value Value of the limit.
347 //
348 // Selector: setCollectionLimit(string,bool) 993b7fba
349 function setCollectionLimit(string memory limit, bool value) external;
350
351 // Get contract address.
352 //
353 // Selector: contractAddress() f6b4dfb4
354 function contractAddress() external view returns (address);
355
356 // Add collection admin by substrate address.
357 // @param new_admin Substrate administrator address.
358 //
359 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
360 function addCollectionAdminSubstrate(uint256 newAdmin) external;
361
362 // Remove collection admin by substrate address.
363 // @param admin Substrate administrator address.
364 //
365 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
366 function removeCollectionAdminSubstrate(uint256 admin) external;
367
368 // Add collection admin.
369 // @param new_admin Address of the added administrator.
370 //
371 // Selector: addCollectionAdmin(address) 92e462c7
372 function addCollectionAdmin(address newAdmin) external;
373
374 // Remove collection admin.
375 //
376 // @param new_admin Address of the removed administrator.
377 //
378 // Selector: removeCollectionAdmin(address) fafd7b42
379 function removeCollectionAdmin(address admin) external;
380
381 // Toggle accessibility of collection nesting.
382 //
383 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
384 //
385 // Selector: setCollectionNesting(bool) 112d4586
386 function setCollectionNesting(bool enable) external;
387
388 // Toggle accessibility of collection nesting.
389 //
390 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
391 // @param collections Addresses of collections that will be available for nesting.
392 //
393 // Selector: setCollectionNesting(bool,address[]) 64872396
394 function setCollectionNesting(bool enable, address[] memory collections)
395 external;
396
397 // Set the collection access method.
398 // @param mode Access mode
399 // 0 for Normal
400 // 1 for AllowList
401 //
402 // Selector: setCollectionAccess(uint8) 41835d4c
403 function setCollectionAccess(uint8 mode) external;
404
405 // Add the user to the allowed list.
406 //
407 // @param user Address of a trusted user.
408 //
409 // Selector: addToCollectionAllowList(address) 67844fe6
410 function addToCollectionAllowList(address user) external;
411
412 // Remove the user from the allowed list.
413 //
414 // @param user Address of a removed user.
415 //
416 // Selector: removeFromCollectionAllowList(address) 85c51acb
417 function removeFromCollectionAllowList(address user) external;
418
419 // Switch permission for minting.
420 //
421 // @param mode Enable if "true".
422 //
423 // Selector: setCollectionMintMode(bool) 00018e84
424 function setCollectionMintMode(bool mode) external;
425}
426441
427// Selector: d74d154f442// Selector: d74d154f
428interface ERC721UniqueExtensions is Dummy, ERC165 {443interface ERC721UniqueExtensions is Dummy, ERC165 {
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
248 function finishMinting() external returns (bool);248 function finishMinting() external returns (bool);
249}249}
250
251// Selector: 6cf113cd
252interface Collection is Dummy, ERC165 {
253 // Set collection property.
254 //
255 // @param key Property key.
256 // @param value Propery value.
257 //
258 // Selector: setCollectionProperty(string,bytes) 2f073f66
259 function setCollectionProperty(string memory key, bytes memory value)
260 external;
261
262 // Delete collection property.
263 //
264 // @param key Property key.
265 //
266 // Selector: deleteCollectionProperty(string) 7b7debce
267 function deleteCollectionProperty(string memory key) external;
268
269 // Get collection property.
270 //
271 // @dev Throws error if key not found.
272 //
273 // @param key Property key.
274 // @return bytes The property corresponding to the key.
275 //
276 // Selector: collectionProperty(string) cf24fd6d
277 function collectionProperty(string memory key)
278 external
279 view
280 returns (bytes memory);
281
282 // Set the sponsor of the collection.
283 //
284 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
285 //
286 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
287 //
288 // Selector: setCollectionSponsor(address) 7623402e
289 function setCollectionSponsor(address sponsor) external;
290
291 // Collection sponsorship confirmation.
292 //
293 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
294 //
295 // Selector: confirmCollectionSponsorship() 3c50e97a
296 function confirmCollectionSponsorship() external;
297
298 // Set limits for the collection.
299 // @dev Throws error if limit not found.
300 // @param limit Name of the limit. Valid names:
301 // "accountTokenOwnershipLimit",
302 // "sponsoredDataSize",
303 // "sponsoredDataRateLimit",
304 // "tokenLimit",
305 // "sponsorTransferTimeout",
306 // "sponsorApproveTimeout"
307 // @param value Value of the limit.
308 //
309 // Selector: setCollectionLimit(string,uint32) 6a3841db
310 function setCollectionLimit(string memory limit, uint32 value) external;
311
312 // Set limits for the collection.
313 // @dev Throws error if limit not found.
314 // @param limit Name of the limit. Valid names:
315 // "ownerCanTransfer",
316 // "ownerCanDestroy",
317 // "transfersEnabled"
318 // @param value Value of the limit.
319 //
320 // Selector: setCollectionLimit(string,bool) 993b7fba
321 function setCollectionLimit(string memory limit, bool value) external;
322
323 // Get contract address.
324 //
325 // Selector: contractAddress() f6b4dfb4
326 function contractAddress() external view returns (address);
327
328 // Add collection admin by substrate address.
329 // @param new_admin Substrate administrator address.
330 //
331 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
332 function addCollectionAdminSubstrate(uint256 newAdmin) external;
333
334 // Remove collection admin by substrate address.
335 // @param admin Substrate administrator address.
336 //
337 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
338 function removeCollectionAdminSubstrate(uint256 admin) external;
339
340 // Add collection admin.
341 // @param new_admin Address of the added administrator.
342 //
343 // Selector: addCollectionAdmin(address) 92e462c7
344 function addCollectionAdmin(address newAdmin) external;
345
346 // Remove collection admin.
347 //
348 // @param new_admin Address of the removed administrator.
349 //
350 // Selector: removeCollectionAdmin(address) fafd7b42
351 function removeCollectionAdmin(address admin) external;
352
353 // Toggle accessibility of collection nesting.
354 //
355 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
356 //
357 // Selector: setCollectionNesting(bool) 112d4586
358 function setCollectionNesting(bool enable) external;
359
360 // Toggle accessibility of collection nesting.
361 //
362 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
363 // @param collections Addresses of collections that will be available for nesting.
364 //
365 // Selector: setCollectionNesting(bool,address[]) 64872396
366 function setCollectionNesting(bool enable, address[] memory collections)
367 external;
368
369 // Set the collection access method.
370 // @param mode Access mode
371 // 0 for Normal
372 // 1 for AllowList
373 //
374 // Selector: setCollectionAccess(uint8) 41835d4c
375 function setCollectionAccess(uint8 mode) external;
376
377 // Add the user to the allowed list.
378 //
379 // @param user Address of a trusted user.
380 //
381 // Selector: addToCollectionAllowList(address) 67844fe6
382 function addToCollectionAllowList(address user) external;
383
384 // Remove the user from the allowed list.
385 //
386 // @param user Address of a removed user.
387 //
388 // Selector: removeFromCollectionAllowList(address) 85c51acb
389 function removeFromCollectionAllowList(address user) external;
390
391 // Switch permission for minting.
392 //
393 // @param mode Enable if "true".
394 //
395 // Selector: setCollectionMintMode(bool) 00018e84
396 function setCollectionMintMode(bool mode) external;
397
398 // Check that account is the owner or admin of the collection
399 //
400 // @param user account to verify
401 // @return "true" if account is the owner or admin
402 //
403 // Selector: verifyOwnerOrAdmin(address) c2282493
404 function verifyOwnerOrAdmin(address user) external view returns (bool);
405
406 // Returns collection type
407 //
408 // @return `Fungible` or `NFT` or `ReFungible`
409 //
410 // Selector: uniqueCollectionType() d34b55b8
411 function uniqueCollectionType() external returns (string memory);
412}
250413
251// Selector: 780e9d63414// Selector: 780e9d63
252interface ERC721Enumerable is Dummy, ERC165 {415interface ERC721Enumerable is Dummy, ERC165 {
274 function totalSupply() external view returns (uint256);437 function totalSupply() external view returns (uint256);
275}438}
276439
277// Selector: 7d9262e6440// Selector: 7c3bef89
278interface Collection is Dummy, ERC165 {
279 // Set collection property.
280 //
281 // @param key Property key.
282 // @param value Propery value.
283 //
284 // Selector: setCollectionProperty(string,bytes) 2f073f66
285 function setCollectionProperty(string memory key, bytes memory value)
286 external;
287
288 // Delete collection property.
289 //
290 // @param key Property key.
291 //
292 // Selector: deleteCollectionProperty(string) 7b7debce
293 function deleteCollectionProperty(string memory key) external;
294
295 // Get collection property.
296 //
297 // @dev Throws error if key not found.
298 //
299 // @param key Property key.
300 // @return bytes The property corresponding to the key.
301 //
302 // Selector: collectionProperty(string) cf24fd6d
303 function collectionProperty(string memory key)
304 external
305 view
306 returns (bytes memory);
307
308 // Set the sponsor of the collection.
309 //
310 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
311 //
312 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
313 //
314 // Selector: setCollectionSponsor(address) 7623402e
315 function setCollectionSponsor(address sponsor) external;
316
317 // Collection sponsorship confirmation.
318 //
319 // @dev After setting the sponsor for the collection, it must be confirmed with this function.
320 //
321 // Selector: confirmCollectionSponsorship() 3c50e97a
322 function confirmCollectionSponsorship() external;
323
324 // Set limits for the collection.
325 // @dev Throws error if limit not found.
326 // @param limit Name of the limit. Valid names:
327 // "accountTokenOwnershipLimit",
328 // "sponsoredDataSize",
329 // "sponsoredDataRateLimit",
330 // "tokenLimit",
331 // "sponsorTransferTimeout",
332 // "sponsorApproveTimeout"
333 // @param value Value of the limit.
334 //
335 // Selector: setCollectionLimit(string,uint32) 6a3841db
336 function setCollectionLimit(string memory limit, uint32 value) external;
337
338 // Set limits for the collection.
339 // @dev Throws error if limit not found.
340 // @param limit Name of the limit. Valid names:
341 // "ownerCanTransfer",
342 // "ownerCanDestroy",
343 // "transfersEnabled"
344 // @param value Value of the limit.
345 //
346 // Selector: setCollectionLimit(string,bool) 993b7fba
347 function setCollectionLimit(string memory limit, bool value) external;
348
349 // Get contract address.
350 //
351 // Selector: contractAddress() f6b4dfb4
352 function contractAddress() external view returns (address);
353
354 // Add collection admin by substrate address.
355 // @param new_admin Substrate administrator address.
356 //
357 // Selector: addCollectionAdminSubstrate(uint256) 5730062b
358 function addCollectionAdminSubstrate(uint256 newAdmin) external;
359
360 // Remove collection admin by substrate address.
361 // @param admin Substrate administrator address.
362 //
363 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
364 function removeCollectionAdminSubstrate(uint256 admin) external;
365
366 // Add collection admin.
367 // @param new_admin Address of the added administrator.
368 //
369 // Selector: addCollectionAdmin(address) 92e462c7
370 function addCollectionAdmin(address newAdmin) external;
371
372 // Remove collection admin.
373 //
374 // @param new_admin Address of the removed administrator.
375 //
376 // Selector: removeCollectionAdmin(address) fafd7b42
377 function removeCollectionAdmin(address admin) external;
378
379 // Toggle accessibility of collection nesting.
380 //
381 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
382 //
383 // Selector: setCollectionNesting(bool) 112d4586
384 function setCollectionNesting(bool enable) external;
385
386 // Toggle accessibility of collection nesting.
387 //
388 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'
389 // @param collections Addresses of collections that will be available for nesting.
390 //
391 // Selector: setCollectionNesting(bool,address[]) 64872396
392 function setCollectionNesting(bool enable, address[] memory collections)
393 external;
394
395 // Set the collection access method.
396 // @param mode Access mode
397 // 0 for Normal
398 // 1 for AllowList
399 //
400 // Selector: setCollectionAccess(uint8) 41835d4c
401 function setCollectionAccess(uint8 mode) external;
402
403 // Add the user to the allowed list.
404 //
405 // @param user Address of a trusted user.
406 //
407 // Selector: addToCollectionAllowList(address) 67844fe6
408 function addToCollectionAllowList(address user) external;
409
410 // Remove the user from the allowed list.
411 //
412 // @param user Address of a removed user.
413 //
414 // Selector: removeFromCollectionAllowList(address) 85c51acb
415 function removeFromCollectionAllowList(address user) external;
416
417 // Switch permission for minting.
418 //
419 // @param mode Enable if "true".
420 //
421 // Selector: setCollectionMintMode(bool) 00018e84
422 function setCollectionMintMode(bool mode) external;
423}
424
425// Selector: d74d154f
426interface ERC721UniqueExtensions is Dummy, ERC165 {441interface ERC721UniqueExtensions is Dummy, ERC165 {
427 // @notice Transfer ownership of an RFT442 // @notice Transfer ownership of an RFT
428 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`443 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`
474 external489 external
475 returns (bool);490 returns (bool);
491
492 // Returns EVM address for refungible token
493 //
494 // @param token ID of the token
495 //
496 // Selector: tokenContractAddress(uint256) ab76fac6
497 function tokenContractAddress(uint256 token)
498 external
499 view
500 returns (address);
476}501}
477502
478interface UniqueRefungible is503interface UniqueRefungible is
modifiedtests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth
22 );22 );
23}23}
24
25// Selector: 042f1106
26interface ERC1633UniqueExtensions is Dummy, ERC165 {
27 // Selector: setParentNFT(address,uint256) 042f1106
28 function setParentNFT(address collection, uint256 nftId)
29 external
30 returns (bool);
31}
32
33// Selector: 5755c3f2
34interface ERC1633 is Dummy, ERC165 {
35 // Selector: parentToken() 80a54001
36 function parentToken() external view returns (address);
37
38 // Selector: parentTokenId() d7f083f3
39 function parentTokenId() external view returns (uint256);
40}
2441
25// Selector: 942e8b2242// Selector: 942e8b22
26interface ERC20 is Dummy, ERC165, ERC20Events {43interface ERC20 is Dummy, ERC165, ERC20Events {
115 Dummy,132 Dummy,
116 ERC165,133 ERC165,
117 ERC20,134 ERC20,
118 ERC20UniqueExtensions135 ERC20UniqueExtensions,
136 ERC1633,
137 ERC1633UniqueExtensions
119{}138{}
120139
modifiedtests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth
60 .to.be.eq(newAdmin.address.toLocaleLowerCase());60 .to.be.eq(newAdmin.address.toLocaleLowerCase());
61 });61 });
62
63 itWeb3('Verify owner or admin', async ({api, web3, privateKeyWrapper}) => {
64 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
65 const collectionHelper = evmCollectionHelpers(web3, owner);
66
67 const result = await collectionHelper.methods
68 .createNonfungibleCollection('A', 'B', 'C')
69 .send();
70 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
71
72 const newAdmin = createEthAccount(web3);
73 const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
74 expect(await collectionEvm.methods.verifyOwnerOrAdmin(newAdmin).call()).to.be.false;
75 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
76 expect(await collectionEvm.methods.verifyOwnerOrAdmin(newAdmin).call()).to.be.true;
77 });
6278
63 itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {79 itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {
64 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);80 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
modifiedtests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth
61 ],61 ],
62 "name": "createRefungibleCollection",62 "name": "createRefungibleCollection",
63 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],63 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
64 "stateMutability": "view",64 "stateMutability": "nonpayable",
65 "type": "function"65 "type": "function"
66 },66 },
67 {67 {
modifiedtests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth
1616
17import {evmToAddress} from '@polkadot/util-crypto';17import {evmToAddress} from '@polkadot/util-crypto';
18import {expect} from 'chai';18import {expect} from 'chai';
19import {getCreatedCollectionCount, getDetailedCollectionInfo} from '../util/helpers';19import {getCreatedCollectionCount, getDetailedCollectionInfo, requirePallets, Pallets} from '../util/helpers';
20import {20import {
21 evmCollectionHelpers,21 evmCollectionHelpers,
22 collectionIdToAddress,22 collectionIdToAddress,
28} from './util/helpers';28} from './util/helpers';
2929
30describe('Create RFT collection from EVM', () => {30describe('Create RFT collection from EVM', () => {
31 before(async function() {
32 await requirePallets(this, [Pallets.ReFungible]);
33 });
34
31 itWeb3('Create collection', async ({api, web3, privateKeyWrapper}) => {35 itWeb3('Create collection', async ({api, web3, privateKeyWrapper}) => {
32 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);36 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
146});150});
147151
148describe('(!negative tests!) Create RFT collection from EVM', () => {152describe('(!negative tests!) Create RFT collection from EVM', () => {
153 before(async function() {
154 await requirePallets(this, [Pallets.ReFungible]);
155 });
156
149 itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3, privateKeyWrapper}) => {157 itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3, privateKeyWrapper}) => {
150 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);158 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
addedtests/src/eth/fractionalizer/Fractionalizer.bindiffbeforeafterboth

no changes

addedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth

no changes

addedtests/src/eth/fractionalizer/FractionalizerAbi.jsondiffbeforeafterboth

no changes

addedtests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/eth/fungibleAbi.jsondiffbeforeafterboth
301 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],301 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
302 "stateMutability": "nonpayable",302 "stateMutability": "nonpayable",
303 "type": "function"303 "type": "function"
304 }304 },
305 {
306 "inputs": [],
307 "name": "uniqueCollectionType",
308 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
309 "stateMutability": "nonpayable",
310 "type": "function"
311 },
312 {
313 "inputs": [
314 { "internalType": "address", "name": "user", "type": "address" }
315 ],
316 "name": "verifyOwnerOrAdmin",
317 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
318 "stateMutability": "view",
319 "type": "function"
320 }
305]321]
306322
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
526 "outputs": [],526 "outputs": [],
527 "stateMutability": "nonpayable",527 "stateMutability": "nonpayable",
528 "type": "function"528 "type": "function"
529 }529 },
530 {
531 "inputs": [],
532 "name": "uniqueCollectionType",
533 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
534 "stateMutability": "nonpayable",
535 "type": "function"
536 },
537 {
538 "inputs": [
539 { "internalType": "address", "name": "user", "type": "address" }
540 ],
541 "name": "verifyOwnerOrAdmin",
542 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
543 "stateMutability": "view",
544 "type": "function"
545 }
530]546]
531547
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {createCollectionExpectSuccess, UNIQUE} from '../util/helpers';17import {createCollectionExpectSuccess, UNIQUE, requirePallets, Pallets} from '../util/helpers';
18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress} from './util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress, uniqueRefungibleToken} from './util/helpers';
19import reFungibleTokenAbi from './reFungibleTokenAbi.json';
20import {expect} from 'chai';19import {expect} from 'chai';
2120
22describe('Refungible: Information getting', () => {21describe('Refungible: Information getting', () => {
22 before(async function() {
23 await requirePallets(this, [Pallets.ReFungible]);
24 });
25
23 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {26 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
24 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);27 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
84 await contract.methods.mint(caller, tokenId).send();87 await contract.methods.mint(caller, tokenId).send();
8588
86 const tokenAddress = tokenIdToAddress(collectionId, tokenId);89 const tokenAddress = tokenIdToAddress(collectionId, tokenId);
87 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});90 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
8891
89 await tokenContract.methods.repartition(2).send();92 await tokenContract.methods.repartition(2).send();
90 await tokenContract.methods.transfer(receiver, 1).send();93 await tokenContract.methods.transfer(receiver, 1).send();
108 await contract.methods.mint(caller, tokenId).send();111 await contract.methods.mint(caller, tokenId).send();
109112
110 const tokenAddress = tokenIdToAddress(collectionId, tokenId);113 const tokenAddress = tokenIdToAddress(collectionId, tokenId);
111 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});114 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
112115
113 await tokenContract.methods.repartition(2).send();116 await tokenContract.methods.repartition(2).send();
114 await tokenContract.methods.transfer(receiver, 1).send();117 await tokenContract.methods.transfer(receiver, 1).send();
120});123});
121124
122describe('Refungible: Plain calls', () => {125describe('Refungible: Plain calls', () => {
126 before(async function() {
127 await requirePallets(this, [Pallets.ReFungible]);
128 });
129
123 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {130 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);131 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
250 await contract.methods.mint(caller, tokenId).send();257 await contract.methods.mint(caller, tokenId).send();
251258
252 const address = tokenIdToAddress(collectionId, tokenId);259 const address = tokenIdToAddress(collectionId, tokenId);
253 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});260 const tokenContract = uniqueRefungibleToken(web3, address, caller);
254 await tokenContract.methods.repartition(15).send();261 await tokenContract.methods.repartition(15).send();
255262
256 {263 {
345 await contract.methods.mint(caller, tokenId).send();352 await contract.methods.mint(caller, tokenId).send();
346353
347 const tokenAddress = tokenIdToAddress(collectionId, tokenId);354 const tokenAddress = tokenIdToAddress(collectionId, tokenId);
348 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});355 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
349356
350 await tokenContract.methods.repartition(2).send();357 await tokenContract.methods.repartition(2).send();
351 await tokenContract.methods.transfer(receiver, 1).send();358 await tokenContract.methods.transfer(receiver, 1).send();
377 await contract.methods.mint(caller, tokenId).send();384 await contract.methods.mint(caller, tokenId).send();
378385
379 const tokenAddress = tokenIdToAddress(collectionId, tokenId);386 const tokenAddress = tokenIdToAddress(collectionId, tokenId);
380 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});387 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
381388
382 await tokenContract.methods.repartition(2).send();389 await tokenContract.methods.repartition(2).send();
383 390
399});406});
400407
401describe('RFT: Fees', () => {408describe('RFT: Fees', () => {
409 before(async function() {
410 await requirePallets(this, [Pallets.ReFungible]);
411 });
412
402 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {413 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
403 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
435});446});
436447
437describe('Common metadata', () => {448describe('Common metadata', () => {
449 before(async function() {
450 await requirePallets(this, [Pallets.ReFungible]);
451 });
452
438 itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {453 itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {
439 const collection = await createCollectionExpectSuccess({454 const collection = await createCollectionExpectSuccess({
modifiedtests/src/eth/reFungibleAbi.jsondiffbeforeafterboth
480 "stateMutability": "view",480 "stateMutability": "view",
481 "type": "function"481 "type": "function"
482 },482 },
483 {
484 "inputs": [
485 { "internalType": "uint256", "name": "token", "type": "uint256" }
486 ],
487 "name": "tokenContractAddress",
488 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
489 "stateMutability": "view",
490 "type": "function"
491 },
483 {492 {
484 "inputs": [493 "inputs": [
485 { "internalType": "address", "name": "owner", "type": "address" },494 { "internalType": "address", "name": "owner", "type": "address" },
526 "outputs": [],535 "outputs": [],
527 "stateMutability": "nonpayable",536 "stateMutability": "nonpayable",
528 "type": "function"537 "type": "function"
529 }538 },
539 {
540 "inputs": [],
541 "name": "uniqueCollectionType",
542 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
543 "stateMutability": "nonpayable",
544 "type": "function"
545 },
546 {
547 "inputs": [
548 { "internalType": "address", "name": "user", "type": "address" }
549 ],
550 "name": "verifyOwnerOrAdmin",
551 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
552 "stateMutability": "view",
553 "type": "function"
554 }
530]555]
531556
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';
18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';18import {collectionIdFromAddress, collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';
19import reFungibleTokenAbi from './reFungibleTokenAbi.json';
2019
21import chai from 'chai';20import chai from 'chai';
22import chaiAsPromised from 'chai-as-promised';21import chaiAsPromised from 'chai-as-promised';
23chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
24const expect = chai.expect;23const expect = chai.expect;
2524
26describe('Refungible token: Information getting', () => {25describe('Refungible token: Information getting', () => {
26 before(async function() {
27 await requirePallets(this, [Pallets.ReFungible]);
28 });
29
27 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {30 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
28 const alice = privateKeyWrapper('//Alice');31 const alice = privateKeyWrapper('//Alice');
2932
34 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;37 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;
3538
36 const address = tokenIdToAddress(collectionId, tokenId);39 const address = tokenIdToAddress(collectionId, tokenId);
37 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});40 const contract = uniqueRefungibleToken(web3, address, caller);
38 const totalSupply = await contract.methods.totalSupply().call();41 const totalSupply = await contract.methods.totalSupply().call();
3942
40 expect(totalSupply).to.equal('200');43 expect(totalSupply).to.equal('200');
50 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;53 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;
5154
52 const address = tokenIdToAddress(collectionId, tokenId);55 const address = tokenIdToAddress(collectionId, tokenId);
53 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});56 const contract = uniqueRefungibleToken(web3, address, caller);
54 const balance = await contract.methods.balanceOf(caller).call();57 const balance = await contract.methods.balanceOf(caller).call();
5558
56 expect(balance).to.equal('200');59 expect(balance).to.equal('200');
66 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;69 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;
6770
68 const address = tokenIdToAddress(collectionId, tokenId);71 const address = tokenIdToAddress(collectionId, tokenId);
69 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});72 const contract = uniqueRefungibleToken(web3, address, caller);
70 const decimals = await contract.methods.decimals().call();73 const decimals = await contract.methods.decimals().call();
7174
72 expect(decimals).to.equal('0');75 expect(decimals).to.equal('0');
7578
76// FIXME: Need erc721 for ReFubgible.79// FIXME: Need erc721 for ReFubgible.
77describe('Check ERC721 token URI for ReFungible', () => {80describe('Check ERC721 token URI for ReFungible', () => {
81 before(async function() {
82 await requirePallets(this, [Pallets.ReFungible]);
83 });
84
78 itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {85 itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {
79 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);86 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
80 const helper = evmCollectionHelpers(web3, owner);87 const helper = evmCollectionHelpers(web3, owner);
81 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();88 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();
82 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);89 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
83 const receiver = createEthAccount(web3);90 const receiver = createEthAccount(web3);
84 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});91 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
85 92
86 const nextTokenId = await contract.methods.nextTokenId().call();93 const nextTokenId = await contract.methods.nextTokenId().call();
87 expect(nextTokenId).to.be.equal('1');94 expect(nextTokenId).to.be.equal('1');
88 result = await contract.methods.mint(95 result = await contract.methods.mint(
115 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);122 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
116 const receiver = createEthAccount(web3);123 const receiver = createEthAccount(web3);
117 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});124 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
118 125
119 const nextTokenId = await contract.methods.nextTokenId().call();126 const nextTokenId = await contract.methods.nextTokenId().call();
120 expect(nextTokenId).to.be.equal('1');127 expect(nextTokenId).to.be.equal('1');
121 result = await contract.methods.mint(128 result = await contract.methods.mint(
122 receiver,129 receiver,
123 nextTokenId,130 nextTokenId,
124 ).send();131 ).send();
125 132
126 // Set URL133 // Set URL
127 await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();134 await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();
128 135
129 const events = normalizeEvents(result.events);136 const events = normalizeEvents(result.events);
130 const address = collectionIdToAddress(collectionId);137 const address = collectionIdToAddress(collectionId);
131138
151 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);158 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
152 const receiver = createEthAccount(web3);159 const receiver = createEthAccount(web3);
153 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});160 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
154 161
155 const nextTokenId = await contract.methods.nextTokenId().call();162 const nextTokenId = await contract.methods.nextTokenId().call();
156 expect(nextTokenId).to.be.equal('1');163 expect(nextTokenId).to.be.equal('1');
157 result = await contract.methods.mint(164 result = await contract.methods.mint(
158 receiver,165 receiver,
159 nextTokenId,166 nextTokenId,
160 ).send();167 ).send();
161 168
162 const events = normalizeEvents(result.events);169 const events = normalizeEvents(result.events);
163 const address = collectionIdToAddress(collectionId);170 const address = collectionIdToAddress(collectionId);
164171
184 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);191 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
185 const receiver = createEthAccount(web3);192 const receiver = createEthAccount(web3);
186 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});193 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
187 194
188 const nextTokenId = await contract.methods.nextTokenId().call();195 const nextTokenId = await contract.methods.nextTokenId().call();
189 expect(nextTokenId).to.be.equal('1');196 expect(nextTokenId).to.be.equal('1');
190 result = await contract.methods.mint(197 result = await contract.methods.mint(
191 receiver,198 receiver,
192 nextTokenId,199 nextTokenId,
193 ).send();200 ).send();
194 201
195 // Set suffix202 // Set suffix
196 const suffix = '/some/suffix';203 const suffix = '/some/suffix';
197 await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();204 await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();
216});223});
217224
218describe('Refungible: Plain calls', () => {225describe('Refungible: Plain calls', () => {
226 before(async function() {
227 await requirePallets(this, [Pallets.ReFungible]);
228 });
229
219 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {230 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {
220 const alice = privateKeyWrapper('//Alice');231 const alice = privateKeyWrapper('//Alice');
221232
229240
230 const spender = createEthAccount(web3);241 const spender = createEthAccount(web3);
231242
232 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});243 const contract = uniqueRefungibleToken(web3, address, owner);
233244
234 {245 {
235 const result = await contract.methods.approve(spender, 100).send({from: owner});246 const result = await contract.methods.approve(spender, 100).send({from: owner});
270 const receiver = createEthAccount(web3);281 const receiver = createEthAccount(web3);
271282
272 const address = tokenIdToAddress(collectionId, tokenId);283 const address = tokenIdToAddress(collectionId, tokenId);
273 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});284 const contract = uniqueRefungibleToken(web3, address, owner);
274285
275 await contract.methods.approve(spender, 100).send();286 await contract.methods.approve(spender, 100).send();
276287
324 await transferBalanceToEth(api, alice, receiver);335 await transferBalanceToEth(api, alice, receiver);
325336
326 const address = tokenIdToAddress(collectionId, tokenId);337 const address = tokenIdToAddress(collectionId, tokenId);
327 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});338 const contract = uniqueRefungibleToken(web3, address, owner);
328339
329 {340 {
330 const result = await contract.methods.transfer(receiver, 50).send({from: owner});341 const result = await contract.methods.transfer(receiver, 50).send({from: owner});
367 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;378 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;
368379
369 const address = tokenIdToAddress(collectionId, tokenId);380 const address = tokenIdToAddress(collectionId, tokenId);
370 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});381 const contract = uniqueRefungibleToken(web3, address, owner);
371382
372 await contract.methods.repartition(200).send({from: owner});383 await contract.methods.repartition(200).send({from: owner});
373 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);384 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);
374 await contract.methods.transfer(receiver, 110).send({from: owner});385 await contract.methods.transfer(receiver, 110).send({from: owner});
375 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);386 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);
376 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);387 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);
377 388
378 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;389 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;
379390
380 await contract.methods.transfer(receiver, 90).send({from: owner});391 await contract.methods.transfer(receiver, 90).send({from: owner});
397 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;408 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;
398409
399 const address = tokenIdToAddress(collectionId, tokenId);410 const address = tokenIdToAddress(collectionId, tokenId);
400 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});411 const contract = uniqueRefungibleToken(web3, address, owner);
401412
402 const result = await contract.methods.repartition(200).send();413 const result = await contract.methods.repartition(200).send();
403 const events = normalizeEvents(result.events);414 const events = normalizeEvents(result.events);
426 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;437 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;
427438
428 const address = tokenIdToAddress(collectionId, tokenId);439 const address = tokenIdToAddress(collectionId, tokenId);
429 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});440 const contract = uniqueRefungibleToken(web3, address, owner);
430441
431 const result = await contract.methods.repartition(50).send();442 const result = await contract.methods.repartition(50).send();
432 const events = normalizeEvents(result.events);443 const events = normalizeEvents(result.events);
456467
457 const address = tokenIdToAddress(collectionId, tokenId);468 const address = tokenIdToAddress(collectionId, tokenId);
458469
459 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});470 const tokenContract = uniqueRefungibleToken(web3, address, caller);
460 await tokenContract.methods.repartition(2).send();471 await tokenContract.methods.repartition(2).send();
461 await tokenContract.methods.transfer(receiver, 1).send();472 await tokenContract.methods.transfer(receiver, 1).send();
462473
463 const events = await recordEvents(contract, async () => 474 const events = await recordEvents(contract, async () =>
464 await tokenContract.methods.burnFrom(caller, 1).send());475 await tokenContract.methods.burnFrom(caller, 1).send());
465 expect(events).to.deep.equal([476 expect(events).to.deep.equal([
466 {477 {
477});488});
478489
479describe('Refungible: Fees', () => {490describe('Refungible: Fees', () => {
491 before(async function() {
492 await requirePallets(this, [Pallets.ReFungible]);
493 });
494
480 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {495 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
481 const alice = privateKeyWrapper('//Alice');496 const alice = privateKeyWrapper('//Alice');
482497
488 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;503 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;
489504
490 const address = tokenIdToAddress(collectionId, tokenId);505 const address = tokenIdToAddress(collectionId, tokenId);
491 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});506 const contract = uniqueRefungibleToken(web3, address, owner);
492507
493 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));508 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));
494 expect(cost < BigInt(0.2 * Number(UNIQUE)));509 expect(cost < BigInt(0.2 * Number(UNIQUE)));
505 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;520 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;
506521
507 const address = tokenIdToAddress(collectionId, tokenId);522 const address = tokenIdToAddress(collectionId, tokenId);
508 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});523 const contract = uniqueRefungibleToken(web3, address, owner);
509524
510 await contract.methods.approve(spender, 100).send({from: owner});525 await contract.methods.approve(spender, 100).send({from: owner});
511526
524 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;539 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;
525540
526 const address = tokenIdToAddress(collectionId, tokenId);541 const address = tokenIdToAddress(collectionId, tokenId);
527 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});542 const contract = uniqueRefungibleToken(web3, address, owner);
528543
529 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));544 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));
530 expect(cost < BigInt(0.2 * Number(UNIQUE)));545 expect(cost < BigInt(0.2 * Number(UNIQUE)));
531 });546 });
532});547});
533548
534describe('Refungible: Substrate calls', () => {549describe('Refungible: Substrate calls', () => {
550 before(async function() {
551 await requirePallets(this, [Pallets.ReFungible]);
552 });
553
535 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {554 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {
536 const alice = privateKeyWrapper('//Alice');555 const alice = privateKeyWrapper('//Alice');
537556
542 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;561 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;
543562
544 const address = tokenIdToAddress(collectionId, tokenId);563 const address = tokenIdToAddress(collectionId, tokenId);
545 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);564 const contract = uniqueRefungibleToken(web3, address);
546565
547 const events = await recordEvents(contract, async () => {566 const events = await recordEvents(contract, async () => {
548 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;567 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;
573 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;592 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;
574593
575 const address = tokenIdToAddress(collectionId, tokenId);594 const address = tokenIdToAddress(collectionId, tokenId);
576 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);595 const contract = uniqueRefungibleToken(web3, address);
577596
578 const events = await recordEvents(contract, async () => {597 const events = await recordEvents(contract, async () => {
579 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;598 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;
611 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;630 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;
612631
613 const address = tokenIdToAddress(collectionId, tokenId);632 const address = tokenIdToAddress(collectionId, tokenId);
614 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);633 const contract = uniqueRefungibleToken(web3, address);
615634
616 const events = await recordEvents(contract, async () => {635 const events = await recordEvents(contract, async () => {
617 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;636 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;
628 },647 },
629 },648 },
630 ]);649 ]);
650 });
651});
652
653describe('ERC 1633 implementation', () => {
654 itWeb3('Parent NFT token address and id', async ({api, web3, privateKeyWrapper}) => {
655 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
656
657 const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
658 const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
659 const nftTokenId = await nftContract.methods.nextTokenId().call();
660 await nftContract.methods.mint(owner, nftTokenId).send();
661 const nftCollectionId = collectionIdFromAddress(nftCollectionAddress);
662
663 const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);
664 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
665 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();
666 await refungibleContract.methods.mint(owner, refungibleTokenId).send();
667
668 const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);
669 const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
670 await refungibleTokenContract.methods.setParentNFT(nftCollectionAddress, nftTokenId).send();
671
672 const tokenAddress = await refungibleTokenContract.methods.parentToken().call();
673 const tokenId = await refungibleTokenContract.methods.parentTokenId().call();
674 const nftTokenAddress = tokenIdToAddress(nftCollectionId, nftTokenId);
675 expect(tokenAddress).to.be.equal(nftTokenAddress);
676 expect(tokenId).to.be.equal(nftTokenId);
677 });
678
679 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {
680 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
681
682 const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);
683 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
684 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();
685 await refungibleContract.methods.mint(owner, refungibleTokenId).send();
686
687 const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);
688 const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
689
690 const tokenAddress = await refungibleTokenContract.methods.parentToken().call();
691 const tokenId = await refungibleTokenContract.methods.parentTokenId().call();
692 expect(tokenAddress).to.be.equal(rftTokenAddress);
693 expect(tokenId).to.be.equal(refungibleTokenId);
631 });694 });
632});695});
633696
modifiedtests/src/eth/reFungibleTokenAbi.jsondiffbeforeafterboth
102 "stateMutability": "view",102 "stateMutability": "view",
103 "type": "function"103 "type": "function"
104 },104 },
105 {
106 "inputs": [],
107 "name": "parentToken",
108 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
109 "stateMutability": "view",
110 "type": "function"
111 },
112 {
113 "inputs": [],
114 "name": "parentTokenId",
115 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
116 "stateMutability": "view",
117 "type": "function"
118 },
105 {119 {
106 "inputs": [120 "inputs": [
107 { "internalType": "uint256", "name": "amount", "type": "uint256" }121 { "internalType": "uint256", "name": "amount", "type": "uint256" }
111 "stateMutability": "nonpayable",125 "stateMutability": "nonpayable",
112 "type": "function"126 "type": "function"
113 },127 },
128 {
129 "inputs": [
130 { "internalType": "address", "name": "collection", "type": "address" },
131 { "internalType": "uint256", "name": "nftId", "type": "uint256" }
132 ],
133 "name": "setParentNFT",
134 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
135 "stateMutability": "nonpayable",
136 "type": "function"
137 },
114 {138 {
115 "inputs": [139 "inputs": [
116 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }140 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
modifiedtests/src/eth/scheduling.test.tsdiffbeforeafterboth
1616
17import {expect} from 'chai';17import {expect} from 'chai';
18import {createEthAccountWithBalance, deployFlipper, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from './util/helpers';18import {createEthAccountWithBalance, deployFlipper, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from './util/helpers';
19import {scheduleExpectSuccess, waitNewBlocks} from '../util/helpers';19import {scheduleExpectSuccess, waitNewBlocks, requirePallets, Pallets} from '../util/helpers';
2020
21describe('Scheduing EVM smart contracts', () => {21describe('Scheduing EVM smart contracts', () => {
22 before(async function() {
23 await requirePallets(this, [Pallets.Scheduler]);
24 });
25
22 itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3, privateKeyWrapper}) => {26 itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3, privateKeyWrapper}) => {
23 const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);27 const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
32import fungibleAbi from '../fungibleAbi.json';32import fungibleAbi from '../fungibleAbi.json';
33import nonFungibleAbi from '../nonFungibleAbi.json';33import nonFungibleAbi from '../nonFungibleAbi.json';
34import refungibleAbi from '../reFungibleAbi.json';34import refungibleAbi from '../reFungibleAbi.json';
35import refungibleTokenAbi from '../reFungibleTokenAbi.json';
35import contractHelpersAbi from './contractHelpersAbi.json';36import contractHelpersAbi from './contractHelpersAbi.json';
3637
37export const GAS_ARGS = {gas: 2500000};38export const GAS_ARGS = {gas: 2500000};
102 return Web3.utils.toChecksumAddress('0x' + buf.toString('hex'));103 return Web3.utils.toChecksumAddress('0x' + buf.toString('hex'));
103}104}
105
106export function tokenIdFromAddress(address: string) {
107 if (!address.startsWith('0x'))
108 throw 'address not starts with "0x"';
109 if (address.length > 42)
110 throw 'address length is more than 20 bytes';
111 return {
112 collectionId: Number('0x' + address.substring(address.length - 16, address.length - 8)),
113 tokenId: Number('0x' + address.substring(address.length - 8)),
114 };
115}
116
104export function tokenIdToCross(collection: number, token: number): CrossAccountId {117export function tokenIdToCross(collection: number, token: number): CrossAccountId {
105 return {118 return {
128 expect(result.success).to.be.true;141 expect(result.success).to.be.true;
129}142}
143
144export async function createRefungibleCollection(api: ApiPromise, web3: Web3, owner: string) {
145 const collectionHelper = evmCollectionHelpers(web3, owner);
146 const result = await collectionHelper.methods
147 .createRefungibleCollection('A', 'B', 'C')
148 .send();
149 return await getCollectionAddressFromResult(api, result);
150}
151
152
153export async function createNonfungibleCollection(api: ApiPromise, web3: Web3, owner: string) {
154 const collectionHelper = evmCollectionHelpers(web3, owner);
155 const result = await collectionHelper.methods
156 .createNonfungibleCollection('A', 'B', 'C')
157 .send();
158 return await getCollectionAddressFromResult(api, result);
159}
160
161export function uniqueNFT(web3: Web3, address: string, owner: string) {
162 return new web3.eth.Contract(nonFungibleAbi as any, address, {
163 from: owner,
164 ...GAS_ARGS,
165 });
166}
167
168export function uniqueRefungible(web3: Web3, collectionAddress: string, owner: string) {
169 return new web3.eth.Contract(refungibleAbi as any, collectionAddress, {
170 from: owner,
171 ...GAS_ARGS,
172 });
173}
174
175export function uniqueRefungibleToken(web3: Web3, tokenAddress: string, owner: string | undefined = undefined) {
176 return new web3.eth.Contract(refungibleTokenAbi as any, tokenAddress, {
177 from: owner,
178 ...GAS_ARGS,
179 });
180}
130181
131export async function itWeb3(name: string, cb: (apis: { web3: Web3, api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any, opts: { only?: boolean, skip?: boolean } = {}) {182export async function itWeb3(name: string, cb: (apis: { web3: Web3, api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any, opts: { only?: boolean, skip?: boolean } = {}) {
132 let i: any = it;183 let i: any = it;
199 return Web3.utils.toChecksumAddress(subToEthLowercase(eth));250 return Web3.utils.toChecksumAddress(subToEthLowercase(eth));
200}251}
252
253export interface CompiledContract {
254 abi: any,
255 object: string,
256}
201257
202export function compileContract(name: string, src: string) {258export function compileContract(name: string, src: string) : CompiledContract {
203 const out = JSON.parse(solc.compile(JSON.stringify({259 const out = JSON.parse(solc.compile(JSON.stringify({
204 language: 'Solidity',260 language: 'Solidity',
205 sources: {261 sources: {
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {default as usingApi} from './substrate/substrate-api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import {18import {U128_MAX} from './util/helpers';
20 getBalance,
21 createMultipleItemsExpectSuccess,
22 isTokenExists,
23 getLastTokenId,
24 getAllowance,
25 approve,
26 transferFrom,
27 createCollection,
28 transfer,
29 burnItem,
30 normalizeAccountId,
31 CrossAccountId,
32 createFungibleItemExpectSuccess,
33 U128_MAX,
34 burnFromExpectSuccess,
35} from './util/helpers';
3619
20import {usingPlaygrounds} from './util/playgrounds';
21
37import chai from 'chai';22import chai from 'chai';
38import chaiAsPromised from 'chai-as-promised';23import chaiAsPromised from 'chai-as-promised';
39chai.use(chaiAsPromised);24chai.use(chaiAsPromised);
4429
45describe('integration test: Fungible functionality:', () => {30describe('integration test: Fungible functionality:', () => {
46 before(async () => {31 before(async () => {
47 await usingApi(async (api, privateKeyWrapper) => {32 await usingPlaygrounds(async (helper, privateKey) => {
48 alice = privateKeyWrapper('//Alice');33 alice = privateKey('//Alice');
49 bob = privateKeyWrapper('//Bob');34 bob = privateKey('//Bob');
50 });35 });
51 });36 });
5237
53 it('Create fungible collection and token', async () => {38 it('Create fungible collection and token', async () => {
54 await usingApi(async api => {39 await usingPlaygrounds(async helper => {
55 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});40 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
56 expect(createCollectionResult.success).to.be.true;41 const defaultTokenId = await collection.getLastTokenId();
57 const collectionId = createCollectionResult.collectionId;
58 const defaultTokenId = await getLastTokenId(api, collectionId);42 expect(defaultTokenId).to.be.equal(0);
43
59 const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);44 await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
60 const aliceBalance = await getBalance(api, collectionId, alice, aliceTokenId); 45 const aliceBalance = await collection.getBalance({Substrate: alice.address});
61 const itemCountAfter = await getLastTokenId(api, collectionId);46 const itemCountAfter = await collection.getLastTokenId();
62 47
63 // What to expect
64 // tslint:disable-next-line:no-unused-expression
65 expect(itemCountAfter).to.be.equal(defaultTokenId);48 expect(itemCountAfter).to.be.equal(defaultTokenId);
66 expect(aliceBalance).to.be.equal(U128_MAX);49 expect(aliceBalance).to.be.equal(U128_MAX);
67 });50 });
68 });51 });
69 52
70 it('RPC method tokenOnewrs for fungible collection and token', async () => {53 it('RPC method tokenOnewrs for fungible collection and token', async () => {
71 await usingApi(async (api, privateKeyWrapper) => {54 await usingPlaygrounds(async (helper, privateKey) => {
72 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};55 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
73 const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));56 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
57
58 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
59
60 await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
61
62 await collection.transfer(alice, {Substrate: bob.address}, 1000n);
63 await collection.transfer(alice, ethAcc, 900n);
74 64
75 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});
76 const collectionId = createCollectionResult.collectionId;
77 const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);
78
79 await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
80 await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
81
82 for (let i = 0; i < 7; i++) {65 for (let i = 0; i < 7; i++) {
83 await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);66 await collection.transfer(alice, facelessCrowd[i], 1n);
84 } 67 }
85
86 const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
87 const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
88 const aliceID = normalizeAccountId(alice);
89 const bobId = normalizeAccountId(bob);
9068
69 const owners = await collection.getTop10Owners();
70
91 // What to expect71 // What to expect
92 // tslint:disable-next-line:no-unused-expression72 expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
93 expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
94 expect(owners.length == 10).to.be.true;73 expect(owners.length).to.be.equal(10);
95 74
96 const eleven = privateKeyWrapper('11');75 const eleven = privateKey('//ALice+11');
97 expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;76 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
98 expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);77 expect((await collection.getTop10Owners()).length).to.be.equal(10);
99 });78 });
100 });79 });
101 80
102 it('Transfer token', async () => {81 it('Transfer token', async () => {
103 await usingApi(async api => {82 await usingPlaygrounds(async helper => {
104 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};83 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
105 const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;84 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
106 const tokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: 500n}, alice.address);85 await collection.mint(alice, {Substrate: alice.address}, 500n);
10786
108 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(500n);87 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
109 expect(await transfer(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;88 expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
110 expect(await transfer(api, collectionId, tokenId, alice, ethAcc, 140n)).to.be.true;89 expect(await collection.transfer(alice, ethAcc, 140n)).to.be.true;
11190
112 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(300n);91 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(300n);
113 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(60n);92 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(60n);
114 expect(await getBalance(api, collectionId, ethAcc, tokenId)).to.be.equal(140n);93 expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
94
115 await expect(transfer(api, collectionId, tokenId, alice, bob, 350n)).to.eventually.be.rejected;95 await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
116 });96 });
117 });97 });
11898
119 it('Tokens multiple creation', async () => {99 it('Tokens multiple creation', async () => {
120 await usingApi(async api => {100 await usingPlaygrounds(async helper => {
121 const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;101 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
122 102
123 const args = [103 await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [
124 {Fungible: {Value: 500n}},104 {value: 500n},
125 {Fungible: {Value: 400n}},105 {value: 400n},
126 {Fungible: {Value: 300n}},106 {value: 300n},
127 ];107 ]);
128 108
129 await createMultipleItemsExpectSuccess(alice, collectionId, args);109 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
130 expect(await getBalance(api, collectionId, alice, 0)).to.be.equal(1200n);
131 }); 110 });
132 });111 });
133112
134 it('Burn some tokens ', async () => {113 it('Burn some tokens ', async () => {
135 await usingApi(async api => { 114 await usingPlaygrounds(async helper => {
136 const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;115 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
137 const tokenId = (await createFungibleItemExpectSuccess(alice, collectionId, {Value: 500n}, alice.address));116 await collection.mint(alice, {Substrate: alice.address}, 500n);
117
138 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;118 expect(await collection.isTokenExists(0)).to.be.true;
139 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(500n);119 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
140 expect(await burnItem(api, alice, collectionId, tokenId, 499n)).to.be.true;120 expect(await collection.burnTokens(alice, 499n)).to.be.true;
141 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;121 expect(await collection.isTokenExists(0)).to.be.true;
142 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(1n);122 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
143 });123 });
144 });124 });
145 125
146 it('Burn all tokens ', async () => {126 it('Burn all tokens ', async () => {
147 await usingApi(async api => { 127 await usingPlaygrounds(async helper => {
148 const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;128 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
149 const tokenId = (await createFungibleItemExpectSuccess(alice, collectionId, {Value: 500n}, alice.address));129 await collection.mint(alice, {Substrate: alice.address}, 500n);
130
150 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;131 expect(await collection.isTokenExists(0)).to.be.true;
151 expect(await burnItem(api, alice, collectionId, tokenId, 500n)).to.be.true;132 expect(await collection.burnTokens(alice, 500n)).to.be.true;
152 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;133 expect(await collection.isTokenExists(0)).to.be.true;
153 134
154 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(0n);135 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
155 expect((await api.rpc.unique.totalPieces(collectionId, tokenId)).value.toBigInt()).to.be.equal(0n);136 expect(await collection.getTotalPieces()).to.be.equal(0n);
156 });137 });
157 });138 });
158139
159 it('Set allowance for token', async () => {140 it('Set allowance for token', async () => {
160 await usingApi(async api => {141 await usingPlaygrounds(async helper => {
161 const collectionId = (await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}})).collectionId;142 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
162 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};143 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
144 await collection.mint(alice, {Substrate: alice.address}, 100n);
145
146 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
163 147
164 const tokenId = (await createFungibleItemExpectSuccess(alice, collectionId, {Value: 100n}, alice.address));148 expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
149 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
165 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);150 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
166151
167 expect(await approve(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;152 expect(await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
168 expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(60n);
169 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(0n);
170
171 expect(await transferFrom(api, collectionId, tokenId, bob, alice, bob, 20n)).to.be.true;
172 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(80n);153 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(80n);
173 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(20n);154 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(20n);
174 expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(40n);155 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
175 156
176 await burnFromExpectSuccess(bob, alice, collectionId, tokenId, 10n);157 await collection.burnTokensFrom(bob, {Substrate: alice.address}, 10n);
177 158
178 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(70n);159 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(70n);
179 expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(30n);160 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
180 expect(await transferFrom(api, collectionId, tokenId, bob, alice, ethAcc, 10n)).to.be.true;161 expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
181 expect(await getBalance(api, collectionId, ethAcc, tokenId)).to.be.equal(10n);162 expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
182 });163 });
183 });164 });
184});165});
modifiedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth
266 * 266 *
267 * Currently used to store RMRK data.267 * Currently used to store RMRK data.
268 **/268 **/
269 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]>;269 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]>;
270 /**270 /**
271 * Used to enumerate token's children.271 * Used to enumerate token's children.
272 **/272 **/
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
2521export interface UpDataStructsPropertyScope extends Enum {2521export interface UpDataStructsPropertyScope extends Enum {
2522 readonly isNone: boolean;2522 readonly isNone: boolean;
2523 readonly isRmrk: boolean;2523 readonly isRmrk: boolean;
2524 readonly isEth: boolean;
2524 readonly type: 'None' | 'Rmrk';2525 readonly type: 'None' | 'Rmrk' | 'Eth';
2525}2526}
25262527
2527/** @name UpDataStructsRpcCollection */2528/** @name UpDataStructsRpcCollection */
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
2978 * Lookup397: up_data_structs::PropertyScope2978 * Lookup397: up_data_structs::PropertyScope
2979 **/2979 **/
2980 UpDataStructsPropertyScope: {2980 UpDataStructsPropertyScope: {
2981 _enum: ['None', 'Rmrk']2981 _enum: ['None', 'Rmrk', 'Eth']
2982 },2982 },
2983 /**2983 /**
2984 * Lookup399: pallet_nonfungible::pallet::Error<T>2984 * Lookup399: pallet_nonfungible::pallet::Error<T>
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
3126 export interface UpDataStructsPropertyScope extends Enum {3126 export interface UpDataStructsPropertyScope extends Enum {
3127 readonly isNone: boolean;3127 readonly isNone: boolean;
3128 readonly isRmrk: boolean;3128 readonly isRmrk: boolean;
3129 readonly isEth: boolean;
3129 readonly type: 'None' | 'Rmrk';3130 readonly type: 'None' | 'Rmrk' | 'Eth';
3130 }3131 }
31313132
3132 /** @name PalletNonfungibleError (399) */3133 /** @name PalletNonfungibleError (399) */
modifiedtests/src/limits.test.tsdiffbeforeafterboth
27 transferExpectSuccess,27 transferExpectSuccess,
28 getFreeBalance,28 getFreeBalance,
29 waitNewBlocks, burnItemExpectSuccess,29 waitNewBlocks, burnItemExpectSuccess,
30 requirePallets,
31 Pallets,
30} from './util/helpers';32} from './util/helpers';
31import {expect} from 'chai';33import {expect} from 'chai';
3234
67describe('Number of tokens per address (ReFungible)', () => {69describe('Number of tokens per address (ReFungible)', () => {
68 let alice: IKeyringPair;70 let alice: IKeyringPair;
6971
70 before(async () => {72 before(async function() {
73 await requirePallets(this, [Pallets.ReFungible]);
74
71 await usingApi(async (api, privateKeyWrapper) => {75 await usingApi(async (api, privateKeyWrapper) => {
72 alice = privateKeyWrapper('//Alice');76 alice = privateKeyWrapper('//Alice');
367 let bob: IKeyringPair;371 let bob: IKeyringPair;
368 let charlie: IKeyringPair;372 let charlie: IKeyringPair;
369373
370 before(async () => {374 before(async function() {
375 await requirePallets(this, [Pallets.ReFungible]);
376
371 await usingApi(async (api, privateKeyWrapper) => {377 await usingApi(async (api, privateKeyWrapper) => {
372 alice = privateKeyWrapper('//Alice');378 alice = privateKeyWrapper('//Alice');
modifiedtests/src/nesting/nest.test.tsdiffbeforeafterboth
17 transferExpectSuccess,17 transferExpectSuccess,
18 transferFromExpectSuccess,18 transferFromExpectSuccess,
19 setCollectionLimitsExpectSuccess,19 setCollectionLimitsExpectSuccess,
20 requirePallets,
21 Pallets,
20} from '../util/helpers';22} from '../util/helpers';
21import {IKeyringPair} from '@polkadot/types/types';23import {IKeyringPair} from '@polkadot/types/types';
2224
311313
312 // ---------- Re-Fungible ----------314 // ---------- Re-Fungible ----------
313315
314 it('ReFungible: allows an Owner to nest/unnest their token', async () => {316 it('ReFungible: allows an Owner to nest/unnest their token', async function() {
317 await requirePallets(this, [Pallets.ReFungible]);
318
315 await usingApi(async api => {319 await usingApi(async api => {
316 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});320 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
333 });337 });
334 });338 });
335339
336 it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async () => {340 it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async function() {
341 await requirePallets(this, [Pallets.ReFungible]);
342
337 await usingApi(async api => {343 await usingApi(async api => {
338 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});344 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
715721
716 // ---------- Re-Fungible ----------722 // ---------- Re-Fungible ----------
717723
718 it('ReFungible: disallows to nest token if nesting is disabled', async () => {724 it('ReFungible: disallows to nest token if nesting is disabled', async function() {
725 await requirePallets(this, [Pallets.ReFungible]);
726
719 await usingApi(async api => {727 await usingApi(async api => {
720 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});728 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
745 });753 });
746 });754 });
747755
748 it('ReFungible: disallows a non-Owner to nest someone else\'s token', async () => {756 it('ReFungible: disallows a non-Owner to nest someone else\'s token', async function() {
757 await requirePallets(this, [Pallets.ReFungible]);
758
749 await usingApi(async api => {759 await usingApi(async api => {
750 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});760 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
773 });783 });
774 });784 });
775785
776 it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {786 it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async function() {
787 await requirePallets(this, [Pallets.ReFungible]);
788
777 await usingApi(async api => {789 await usingApi(async api => {
778 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});790 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
800 });812 });
801 });813 });
802814
803 it('ReFungible: disallows to nest token to an unlisted collection', async () => {815 it('ReFungible: disallows to nest token to an unlisted collection', async function() {
816 await requirePallets(this, [Pallets.ReFungible]);
817
804 await usingApi(async api => {818 await usingApi(async api => {
805 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});819 const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
modifiedtests/src/nesting/properties.test.tsdiffbeforeafterboth
8 createItemExpectSuccess,8 createItemExpectSuccess,
9 getCreateCollectionResult,9 getCreateCollectionResult,
10 transferExpectSuccess,10 transferExpectSuccess,
11 requirePallets,
12 Pallets,
11} from '../util/helpers';13} from '../util/helpers';
12import {IKeyringPair} from '@polkadot/types/types';14import {IKeyringPair} from '@polkadot/types/types';
13import {tokenIdToAddress} from '../eth/util/helpers';15import {tokenIdToAddress} from '../eth/util/helpers';
64 await testMakeSureSuppliesRequired({type: 'NFT'});66 await testMakeSureSuppliesRequired({type: 'NFT'});
65 });67 });
6668
67 it('Makes sure collectionById supplies required fields for ReFungible', async () => {69 it('Makes sure collectionById supplies required fields for ReFungible', async function() {
70 await requirePallets(this, [Pallets.ReFungible]);
71
68 await testMakeSureSuppliesRequired({type: 'ReFungible'});72 await testMakeSureSuppliesRequired({type: 'ReFungible'});
69 });73 });
120 it('Sets properties for a NFT collection', async () => {124 it('Sets properties for a NFT collection', async () => {
121 await testSetsPropertiesForCollection('NFT');125 await testSetsPropertiesForCollection('NFT');
122 });126 });
123 it('Sets properties for a ReFungible collection', async () => {127 it('Sets properties for a ReFungible collection', async function() {
128 await requirePallets(this, [Pallets.ReFungible]);
129
124 await testSetsPropertiesForCollection('ReFungible');130 await testSetsPropertiesForCollection('ReFungible');
125 });131 });
178 it('Check valid names for NFT collection properties keys', async () => {184 it('Check valid names for NFT collection properties keys', async () => {
179 await testCheckValidNames('NFT');185 await testCheckValidNames('NFT');
180 });186 });
181 it('Check valid names for ReFungible collection properties keys', async () => {187 it('Check valid names for ReFungible collection properties keys', async function() {
188 await requirePallets(this, [Pallets.ReFungible]);
189
182 await testCheckValidNames('ReFungible');190 await testCheckValidNames('ReFungible');
183 });191 });
209 it('Changes properties of a NFT collection', async () => {217 it('Changes properties of a NFT collection', async () => {
210 await testChangesProperties({type: 'NFT'});218 await testChangesProperties({type: 'NFT'});
211 });219 });
212 it('Changes properties of a ReFungible collection', async () => {220 it('Changes properties of a ReFungible collection', async function() {
221 await requirePallets(this, [Pallets.ReFungible]);
222
213 await testChangesProperties({type: 'ReFungible'});223 await testChangesProperties({type: 'ReFungible'});
214 });224 });
238 it('Deletes properties of a NFT collection', async () => {248 it('Deletes properties of a NFT collection', async () => {
239 await testDeleteProperties({type: 'NFT'});249 await testDeleteProperties({type: 'NFT'});
240 });250 });
241 it('Deletes properties of a ReFungible collection', async () => {251 it('Deletes properties of a ReFungible collection', async function() {
252 await requirePallets(this, [Pallets.ReFungible]);
253
242 await testDeleteProperties({type: 'ReFungible'});254 await testDeleteProperties({type: 'ReFungible'});
243 });255 });
269 it('Fails to set properties in a NFT collection if not its onwer/administrator', async () => {281 it('Fails to set properties in a NFT collection if not its onwer/administrator', async () => {
270 await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'NFT'});282 await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'NFT'});
271 });283 });
272 it('Fails to set properties in a ReFungible collection if not its onwer/administrator', async () => {284 it('Fails to set properties in a ReFungible collection if not its onwer/administrator', async function() {
285 await requirePallets(this, [Pallets.ReFungible]);
286
273 await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'ReFungible'});287 await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'ReFungible'});
274 });288 });
307 it('Fails to set properties that exceed the limits (NFT)', async () => {321 it('Fails to set properties that exceed the limits (NFT)', async () => {
308 await testFailsSetPropertiesThatExeedLimits({type: 'NFT'});322 await testFailsSetPropertiesThatExeedLimits({type: 'NFT'});
309 });323 });
310 it('Fails to set properties that exceed the limits (ReFungible)', async () => {324 it('Fails to set properties that exceed the limits (ReFungible)', async function() {
325 await requirePallets(this, [Pallets.ReFungible]);
326
311 await testFailsSetPropertiesThatExeedLimits({type: 'ReFungible'});327 await testFailsSetPropertiesThatExeedLimits({type: 'ReFungible'});
312 });328 });
337 it('Fails to set more properties than it is allowed (NFT)', async () => {353 it('Fails to set more properties than it is allowed (NFT)', async () => {
338 await testFailsSetMorePropertiesThanAllowed({type: 'NFT'});354 await testFailsSetMorePropertiesThanAllowed({type: 'NFT'});
339 });355 });
340 it('Fails to set more properties than it is allowed (ReFungible)', async () => {356 it('Fails to set more properties than it is allowed (ReFungible)', async function() {
357 await requirePallets(this, [Pallets.ReFungible]);
358
341 await testFailsSetMorePropertiesThanAllowed({type: 'ReFungible'});359 await testFailsSetMorePropertiesThanAllowed({type: 'ReFungible'});
342 });360 });
392 it('Fails to set properties with invalid names (NFT)', async () => {410 it('Fails to set properties with invalid names (NFT)', async () => {
393 await testFailsSetPropertiesWithInvalidNames({type: 'NFT'});411 await testFailsSetPropertiesWithInvalidNames({type: 'NFT'});
394 });412 });
395 it('Fails to set properties with invalid names (ReFungible)', async () => {413 it('Fails to set properties with invalid names (ReFungible)', async function() {
414 await requirePallets(this, [Pallets.ReFungible]);
415
396 await testFailsSetPropertiesWithInvalidNames({type: 'ReFungible'});416 await testFailsSetPropertiesWithInvalidNames({type: 'ReFungible'});
397 });417 });
443 it('Sets access rights to properties of a collection (NFT)', async () => {463 it('Sets access rights to properties of a collection (NFT)', async () => {
444 await testSetsAccessRightsToProperties({type: 'NFT'});464 await testSetsAccessRightsToProperties({type: 'NFT'});
445 });465 });
446 it('Sets access rights to properties of a collection (ReFungible)', async () => {466 it('Sets access rights to properties of a collection (ReFungible)', async function() {
467 await requirePallets(this, [Pallets.ReFungible]);
468
447 await testSetsAccessRightsToProperties({type: 'ReFungible'});469 await testSetsAccessRightsToProperties({type: 'ReFungible'});
448 });470 });
472 it('Changes access rights to properties of a NFT collection', async () => {494 it('Changes access rights to properties of a NFT collection', async () => {
473 await testChangesAccessRightsToProperty({type: 'NFT'});495 await testChangesAccessRightsToProperty({type: 'NFT'});
474 });496 });
475 it('Changes access rights to properties of a ReFungible collection', async () => {497 it('Changes access rights to properties of a ReFungible collection', async function() {
498 await requirePallets(this, [Pallets.ReFungible]);
499
476 await testChangesAccessRightsToProperty({type: 'ReFungible'});500 await testChangesAccessRightsToProperty({type: 'ReFungible'});
477 });501 });
502 it('Prevents from setting access rights to properties of a NFT collection if not an onwer/admin', async () => {526 it('Prevents from setting access rights to properties of a NFT collection if not an onwer/admin', async () => {
503 await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'NFT'});527 await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'NFT'});
504 });528 });
505 it('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', async () => {529 it('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', async function() {
530 await requirePallets(this, [Pallets.ReFungible]);
531
506 await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'ReFungible'});532 await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'ReFungible'});
507 });533 });
531 it('Prevents from adding too many possible properties (NFT)', async () => {557 it('Prevents from adding too many possible properties (NFT)', async () => {
532 await testPreventFromAddingTooManyPossibleProperties({type: 'NFT'});558 await testPreventFromAddingTooManyPossibleProperties({type: 'NFT'});
533 });559 });
534 it('Prevents from adding too many possible properties (ReFungible)', async () => {560 it('Prevents from adding too many possible properties (ReFungible)', async function() {
561 await requirePallets(this, [Pallets.ReFungible]);
562
535 await testPreventFromAddingTooManyPossibleProperties({type: 'ReFungible'});563 await testPreventFromAddingTooManyPossibleProperties({type: 'ReFungible'});
536 });564 });
560 it('Prevents access rights to be modified if constant (NFT)', async () => {588 it('Prevents access rights to be modified if constant (NFT)', async () => {
561 await testPreventAccessRightsModifiedIfConstant({type: 'NFT'});589 await testPreventAccessRightsModifiedIfConstant({type: 'NFT'});
562 });590 });
563 it('Prevents access rights to be modified if constant (ReFungible)', async () => {591 it('Prevents access rights to be modified if constant (ReFungible)', async function() {
592 await requirePallets(this, [Pallets.ReFungible]);
593
564 await testPreventAccessRightsModifiedIfConstant({type: 'ReFungible'});594 await testPreventAccessRightsModifiedIfConstant({type: 'ReFungible'});
565 });595 });
608 it('Prevents adding properties with invalid names (NFT)', async () => {638 it('Prevents adding properties with invalid names (NFT)', async () => {
609 await testPreventsAddingPropertiesWithInvalidNames({type: 'NFT'});639 await testPreventsAddingPropertiesWithInvalidNames({type: 'NFT'});
610 });640 });
611 it('Prevents adding properties with invalid names (ReFungible)', async () => {641 it('Prevents adding properties with invalid names (ReFungible)', async function() {
642 await requirePallets(this, [Pallets.ReFungible]);
643
612 await testPreventsAddingPropertiesWithInvalidNames({type: 'ReFungible'});644 await testPreventsAddingPropertiesWithInvalidNames({type: 'ReFungible'});
613 });645 });
651 it('Reads yet empty properties of a token (NFT)', async () => {683 it('Reads yet empty properties of a token (NFT)', async () => {
652 await testReadsYetEmptyProperties({type: 'NFT'});684 await testReadsYetEmptyProperties({type: 'NFT'});
653 });685 });
654 it('Reads yet empty properties of a token (ReFungible)', async () => {686 it('Reads yet empty properties of a token (ReFungible)', async function() {
687 await requirePallets(this, [Pallets.ReFungible]);
688
655 await testReadsYetEmptyProperties({type: 'ReFungible'});689 await testReadsYetEmptyProperties({type: 'ReFungible'});
656 });690 });
696 it('Assigns properties to a token according to permissions (NFT)', async () => {730 it('Assigns properties to a token according to permissions (NFT)', async () => {
697 await testAssignPropertiesAccordingToPermissions({type: 'NFT'}, 1);731 await testAssignPropertiesAccordingToPermissions({type: 'NFT'}, 1);
698 });732 });
699 it('Assigns properties to a token according to permissions (ReFungible)', async () => {733 it('Assigns properties to a token according to permissions (ReFungible)', async function() {
734 await requirePallets(this, [Pallets.ReFungible]);
735
700 await testAssignPropertiesAccordingToPermissions({type: 'ReFungible'}, 100);736 await testAssignPropertiesAccordingToPermissions({type: 'ReFungible'}, 100);
701 });737 });
749 it('Changes properties of a token according to permissions (NFT)', async () => {785 it('Changes properties of a token according to permissions (NFT)', async () => {
750 await testChangesPropertiesAccordingPermission({type: 'NFT'}, 1);786 await testChangesPropertiesAccordingPermission({type: 'NFT'}, 1);
751 });787 });
752 it('Changes properties of a token according to permissions (ReFungible)', async () => {788 it('Changes properties of a token according to permissions (ReFungible)', async function() {
789 await requirePallets(this, [Pallets.ReFungible]);
790
753 await testChangesPropertiesAccordingPermission({type: 'ReFungible'}, 100);791 await testChangesPropertiesAccordingPermission({type: 'ReFungible'}, 100);
754 });792 });
802 it('Deletes properties of a token according to permissions (NFT)', async () => {840 it('Deletes properties of a token according to permissions (NFT)', async () => {
803 await testDeletePropertiesAccordingPermission({type: 'NFT'}, 1);841 await testDeletePropertiesAccordingPermission({type: 'NFT'}, 1);
804 });842 });
805 it('Deletes properties of a token according to permissions (ReFungible)', async () => {843 it('Deletes properties of a token according to permissions (ReFungible)', async function() {
844 await requirePallets(this, [Pallets.ReFungible]);
845
806 await testDeletePropertiesAccordingPermission({type: 'ReFungible'}, 100);846 await testDeletePropertiesAccordingPermission({type: 'ReFungible'}, 100);
807 });847 });
1029 it('Forbids changing/deleting properties of a token if the user is outside of permissions (NFT)', async () => {1069 it('Forbids changing/deleting properties of a token if the user is outside of permissions (NFT)', async () => {
1030 await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'NFT'}, 1);1070 await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'NFT'}, 1);
1031 });1071 });
1032 it('Forbids changing/deleting properties of a token if the user is outside of permissions (ReFungible)', async () => {1072 it('Forbids changing/deleting properties of a token if the user is outside of permissions (ReFungible)', async function() {
1073 await requirePallets(this, [Pallets.ReFungible]);
1074
1033 await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'ReFungible'}, 100);1075 await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'ReFungible'}, 100);
1034 });1076 });
1062 it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (NFT)', async () => {1104 it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (NFT)', async () => {
1063 await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'NFT'}, 1);1105 await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'NFT'}, 1);
1064 });1106 });
1065 it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (ReFungible)', async () => {1107 it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (ReFungible)', async function() {
1108 await requirePallets(this, [Pallets.ReFungible]);
1109
1066 await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'ReFungible'}, 100);1110 await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'ReFungible'}, 100);
1067 });1111 });
1096 it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (NFT)', async () => {1140 it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (NFT)', async () => {
1097 await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'NFT'}, 1);1141 await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'NFT'}, 1);
1098 });1142 });
1099 it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (ReFungible)', async () => {1143 it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (ReFungible)', async function() {
1144 await requirePallets(this, [Pallets.ReFungible]);
1145
1100 await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'ReFungible'}, 100);1146 await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'ReFungible'}, 100);
1101 });1147 });
1140 it('Forbids adding too many properties to a token (NFT)', async () => {1186 it('Forbids adding too many properties to a token (NFT)', async () => {
1141 await testForbidsAddingTooManyProperties({type: 'NFT'}, 1);1187 await testForbidsAddingTooManyProperties({type: 'NFT'}, 1);
1142 });1188 });
1143 it('Forbids adding too many properties to a token (ReFungible)', async () => {1189 it('Forbids adding too many properties to a token (ReFungible)', async function() {
1190 await requirePallets(this, [Pallets.ReFungible]);
1191
1144 await testForbidsAddingTooManyProperties({type: 'ReFungible'}, 100);1192 await testForbidsAddingTooManyProperties({type: 'ReFungible'}, 100);
1145 });1193 });
1149 let collection: number;1197 let collection: number;
1150 let token: number;1198 let token: number;
11511199
1152 before(async () => {1200 before(async function() {
1201 await requirePallets(this, [Pallets.ReFungible]);
1202
1153 await usingApi(async (api, privateKeyWrapper) => {1203 await usingApi(async (api, privateKeyWrapper) => {
1154 alice = privateKeyWrapper('//Alice');1204 alice = privateKeyWrapper('//Alice');
modifiedtests/src/nesting/rules-smoke.test.tsdiffbeforeafterboth
1import {expect} from 'chai';1import {expect} from 'chai';
2import {tokenIdToAddress} from '../eth/util/helpers';2import {tokenIdToAddress} from '../eth/util/helpers';
3import usingApi, {executeTransaction} from '../substrate/substrate-api';3import usingApi, {executeTransaction} from '../substrate/substrate-api';
4import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, CrossAccountId, getCreateCollectionResult} from '../util/helpers';4import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, CrossAccountId, getCreateCollectionResult, requirePallets, Pallets} from '../util/helpers';
5import {IKeyringPair} from '@polkadot/types/types';5import {IKeyringPair} from '@polkadot/types/types';
66
7describe('nesting check', () => {7describe('nesting check', () => {
47 });47 });
48 });48 });
4949
50 it('called for refungible', async () => {50 it('called for refungible', async function() {
51 await requirePallets(this, [Pallets.ReFungible]);
52
51 await usingApi(async api => {53 await usingApi(async api => {
52 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});54 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
modifiedtests/src/nesting/unnest.test.tsdiffbeforeafterboth
10 setCollectionPermissionsExpectSuccess,10 setCollectionPermissionsExpectSuccess,
11 transferExpectSuccess,11 transferExpectSuccess,
12 transferFromExpectSuccess,12 transferFromExpectSuccess,
13 requirePallets,
14 Pallets,
13} from '../util/helpers';15} from '../util/helpers';
14import {IKeyringPair} from '@polkadot/types/types';16import {IKeyringPair} from '@polkadot/types/types';
1517
80 });82 });
81 });83 });
8284
83 it('ReFungible: allows the owner to successfully unnest a token', async () => {85 it('ReFungible: allows the owner to successfully unnest a token', async function() {
86 await requirePallets(this, [Pallets.ReFungible]);
87
84 await usingApi(async api => {88 await usingApi(async api => {
85 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});89 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
modifiedtests/src/nextSponsoring.test.tsdiffbeforeafterboth
27 transferExpectSuccess,27 transferExpectSuccess,
28 normalizeAccountId,28 normalizeAccountId,
29 getNextSponsored,29 getNextSponsored,
30 requirePallets,
31 Pallets,
30} from './util/helpers';32} from './util/helpers';
3133
32chai.use(chaiAsPromised);34chai.use(chaiAsPromised);
89 });91 });
90 });92 });
9193
92 it('ReFungible', async () => {94 it('ReFungible', async function() {
95 await requirePallets(this, [Pallets.ReFungible]);
96
93 await usingApi(async (api: ApiPromise) => {97 await usingApi(async (api: ApiPromise) => {
9498
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
49 'inflation',49 'inflation',
50 'unique',50 'unique',
51 'nonfungible',51 'nonfungible',
52 'refungible',
53 'scheduler',
54 'charging',52 'charging',
55];53];
5654
66 await usingApi(async api => {64 await usingApi(async api => {
67 const chain = await api.rpc.system.chain();65 const chain = await api.rpc.system.chain();
66
67 const refungible = 'refungible';
68 const scheduler = 'scheduler';
69 const rmrkPallets = ['rmrkcore', 'rmrkequip'];
6870
69 if (!chain.eq('UNIQUE')) {71 if (chain.eq('OPAL by UNIQUE')) {
70 requiredPallets.push(...['rmrkcore', 'rmrkequip']);72 requiredPallets.push(refungible, scheduler, ...rmrkPallets);
71 }73 } else if (chain.eq('QUARTZ by UNIQUE')) {
74 // Insert Quartz additional pallets here
75 } else if (chain.eq('UNIQUE')) {
76 // Insert Unique additional pallets here
77 }
72 });78 });
73 });79 });
7480
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18
19import { usingPlaygrounds } from './util/playgrounds';
19import {20import {
20 createCollectionExpectSuccess,21 getModuleNames,
21 getBalance,22 Pallets,
22 createMultipleItemsExpectSuccess,23 requirePallets,
23 isTokenExists,
24 getLastTokenId,
25 getAllowance,
26 approve,
27 transferFrom,
28 createCollection,
29 createRefungibleToken,
30 transfer,
31 burnItem,
32 repartitionRFT,
33 createCollectionWithPropsExpectSuccess,
34 getDetailedCollectionInfo,
35 normalizeAccountId,
36 CrossAccountId,
37 getCreateItemsResult,
38 getDestroyItemsResult,
39} from './util/helpers';24} from './util/helpers';
4025
41import chai from 'chai';26import chai from 'chai';
46let alice: IKeyringPair;31let alice: IKeyringPair;
47let bob: IKeyringPair;32let bob: IKeyringPair;
4833
49describe('integration test: Refungible functionality:', () => {34describe('integration test: Refungible functionality:', async () => {
50 before(async () => {35 before(async function() {
51 await usingApi(async (api, privateKeyWrapper) => {36 await requirePallets(this, [Pallets.ReFungible]);
37
38 await usingPlaygrounds(async (helper, privateKey) => {
52 alice = privateKeyWrapper('//Alice');39 alice = privateKey('//Alice');
53 bob = privateKeyWrapper('//Bob');40 bob = privateKey('//Bob');
41 if (!getModuleNames(helper.api!).includes(Pallets.ReFungible)) this.skip();
54 });42 });
55 });43 });
5644
57 it('Create refungible collection and token', async () => {45 it('Create refungible collection and token', async () => {
58 await usingApi(async api => {46 await usingPlaygrounds(async helper => {
59 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});47 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
48
60 expect(createCollectionResult.success).to.be.true;49 const itemCountBefore = await collection.getLastTokenId();
61 const collectionId = createCollectionResult.collectionId;50 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
62 51
63 const itemCountBefore = await getLastTokenId(api, collectionId);52 const itemCountAfter = await collection.getLastTokenId();
64 const result = await createRefungibleToken(api, alice, collectionId, 100n);
65 53
66 const itemCountAfter = await getLastTokenId(api, collectionId);
67
68 // What to expect54 // What to expect
69 // tslint:disable-next-line:no-unused-expression55 expect(token?.tokenId).to.be.gte(itemCountBefore);
70 expect(result.success).to.be.true;
71 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);56 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
72 expect(collectionId).to.be.equal(result.collectionId);57 expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
73 expect(itemCountAfter.toString()).to.be.equal(result.itemId.toString());
74 });58 });
75 });59 });
76 60
77 it('RPC method tokenOnewrs for refungible collection and token', async () => {61 it('RPC method tokenOnewrs for refungible collection and token', async () => {
78 await usingApi(async (api, privateKeyWrapper) => {62 await usingPlaygrounds(async (helper, privateKey) => {
79 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};63 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
80 const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));64 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
65
66 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
67
68 const token = await collection.mintToken(alice, {Substrate: alice.address}, 10_000n);
69
70 await token.transfer(alice, {Substrate: bob.address}, 1000n);
71 await token.transfer(alice, ethAcc, 900n);
81 72
82 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
83 const collectionId = createCollectionResult.collectionId;
84
85 const result = await createRefungibleToken(api, alice, collectionId, 10_000n);
86 const aliceTokenId = result.itemId;
87
88
89 await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
90 await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
91
92 for (let i = 0; i < 7; i++) {73 for (let i = 0; i < 7; i++) {
93 await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 50*(i+1));74 await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
94 } 75 }
95 76
96 const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);77 const owners = await token.getTop10Owners();
97 const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));78
98
99 const aliceID = normalizeAccountId(alice);
100 const bobId = normalizeAccountId(bob);
101
102 // What to expect79 // What to expect
103 // tslint:disable-next-line:no-unused-expression80 expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
104 expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
105 expect(owners.length).to.be.equal(10);81 expect(owners.length).to.be.equal(10);
106 82
107 const eleven = privateKeyWrapper('11');83 const eleven = privateKey('//ALice+11');
108 expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;84 expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
109 expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);85 expect((await token.getTop10Owners()).length).to.be.equal(10);
110 });86 });
111 });87 });
112 88
113 it('Transfer token pieces', async () => {89 it('Transfer token pieces', async () => {
114 await usingApi(async api => {90 await usingPlaygrounds(async helper => {
115 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;91 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
116 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;92 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
11793
118 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);94 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
119 expect(await transfer(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;95 expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
12096
121 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(40n);97 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
122 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(60n);98 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
123 await expect(transfer(api, collectionId, tokenId, alice, bob, 41n)).to.eventually.be.rejected;99
100 await expect(token.transfer(alice, {Substrate: bob.address}, 41n)).to.eventually.be.rejected;
124 });101 });
125 });102 });
126103
127 it('Create multiple tokens', async () => {104 it('Create multiple tokens', async () => {
128 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});105 await usingPlaygrounds(async helper => {
106 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
129 const args = [107 // TODO: fix mintMultipleTokens
108 // await collection.mintMultipleTokens(alice, [
130 {ReFungible: {pieces: 1}},109 // {owner: {Substrate: alice.address}, pieces: 1n},
131 {ReFungible: {pieces: 2}},110 // {owner: {Substrate: alice.address}, pieces: 2n},
132 {ReFungible: {pieces: 100}},111 // {owner: {Substrate: alice.address}, pieces: 100n},
133 ];112 // ]);
134 await createMultipleItemsExpectSuccess(alice, collectionId, args);113 await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
135114 {pieces: 1n},
136 await usingApi(async api => { 115 {pieces: 2n},
116 {pieces: 100n},
137 const tokenId = await getLastTokenId(api, collectionId);117 ]);
118 const lastTokenId = await collection.getLastTokenId();
138 expect(tokenId).to.be.equal(3);119 expect(lastTokenId).to.be.equal(3);
139 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);120 expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
140 });121 });
141 });122 });
142123
143 it('Burn some pieces', async () => {124 it('Burn some pieces', async () => {
144 await usingApi(async api => { 125 await usingPlaygrounds(async helper => {
145 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;126 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
146 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;127 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
147 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;128 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
148 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);129 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
149 expect(await burnItem(api, alice, collectionId, tokenId, 99n)).to.be.true;130 expect((await token.burn(alice, 99n)).success).to.be.true;
150 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;131 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
151 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(1n);132 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
152 });133 });
153 });134 });
154135
155 it('Burn all pieces', async () => {136 it('Burn all pieces', async () => {
156 await usingApi(async api => { 137 await usingPlaygrounds(async helper => {
157 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;138 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
158 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;139 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
159 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;140
141 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
160 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);142 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
143
161 expect(await burnItem(api, alice, collectionId, tokenId, 100n)).to.be.true;144 expect((await token.burn(alice, 100n)).success).to.be.true;
162 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;145 expect(await collection.isTokenExists(token.tokenId)).to.be.false;
163 });146 });
164 });147 });
165148
166 it('Burn some pieces for multiple users', async () => {149 it('Burn some pieces for multiple users', async () => {
167 await usingApi(async api => { 150 await usingPlaygrounds(async helper => {
168 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;151 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
169 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;152 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
170 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;
171153
172 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);154 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
173 expect(await transfer(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;
174
175 155
176 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(40n);156 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
177 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(60n);157 expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
178 expect(await burnItem(api, alice, collectionId, tokenId, 40n)).to.be.true;
179158
180 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(0n);159 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
181 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;160 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
182 expect(await burnItem(api, bob, collectionId, tokenId, 59n)).to.be.true;
183161
184 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(1n);162 expect((await token.burn(alice, 40n)).success).to.be.true;
163
164 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
165 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
166
185 expect(await isTokenExists(api, collectionId, tokenId)).to.be.true;167 expect((await token.burn(bob, 59n)).success).to.be.true;
168
186 expect(await burnItem(api, bob, collectionId, tokenId, 1n)).to.be.true;169 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
170 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
171
187 172 expect((await token.burn(bob, 1n)).success).to.be.true;
173
188 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;174 expect(await collection.isTokenExists(token.tokenId)).to.be.false;
189 });175 });
190 });176 });
191177
192 it('Set allowance for token', async () => {178 it('Set allowance for token', async () => {
193 await usingApi(async api => {179 await usingPlaygrounds(async helper => {
194 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;180 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
195 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;181 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
182
183 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
196184
197 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(100n);185 expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
186 expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
198187
199 expect(await approve(api, collectionId, tokenId, alice, bob, 60n)).to.be.true;188 expect(await token.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
200 expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(60n);
201
202 expect(await transferFrom(api, collectionId, tokenId, bob, alice, bob, 20n)).to.be.true;
203 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(80n);189 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
204 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(20n);190 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
205 expect(await getAllowance(api, collectionId, alice, bob, tokenId)).to.be.equal(40n);191 expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
206 });192 });
207 });193 });
208194
209 it('Repartition', async () => {195 it('Repartition', async () => {
210 await usingApi(async api => {196 await usingPlaygrounds(async helper => {
211 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;197 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
212 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;198 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
213199
214 expect(await repartitionRFT(api, collectionId, alice, tokenId, 200n)).to.be.true;200 expect(await token.repartition(alice, 200n)).to.be.true;
201 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
202 expect(await token.getTotalPieces()).to.be.equal(200n);
203
204 expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
215 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(200n);205 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
206 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
207
208 await expect(token.repartition(alice, 80n)).to.eventually.be.rejected;
209
210 expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
211 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
212 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
216213
217 expect(await transfer(api, collectionId, tokenId, alice, bob, 110n)).to.be.true;214 expect(await token.repartition(bob, 150n)).to.be.true;
218 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(90n);215 await expect(token.transfer(bob, {Substrate: alice.address}, 160n)).to.eventually.be.rejected;
219 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(110n);
220216
221 await expect(repartitionRFT(api, collectionId, alice, tokenId, 80n)).to.eventually.be.rejected;
222
223 expect(await transfer(api, collectionId, tokenId, alice, bob, 90n)).to.be.true;
224 expect(await getBalance(api, collectionId, alice, tokenId)).to.be.equal(0n);
225 expect(await getBalance(api, collectionId, bob, tokenId)).to.be.equal(200n);
226
227 expect(await repartitionRFT(api, collectionId, bob, tokenId, 150n)).to.be.true;
228 await expect(transfer(api, collectionId, tokenId, bob, alice, 160n)).to.eventually.be.rejected;
229 });217 });
230 });218 });
231219
232 it('Repartition with increased amount', async () => {220 it('Repartition with increased amount', async () => {
233 await usingApi(async api => {221 await usingPlaygrounds(async helper => {
234 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;222 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
235 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;223 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
236
237 const tx = api.tx.unique.repartition(collectionId, tokenId, 200n);224 await token.repartition(alice, 200n);
238 const events = await submitTransactionAsync(alice, tx);225 const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
239 const substrateEvents = getCreateItemsResult(events);
240 expect(substrateEvents).to.include.deep.members([226 expect(chainEvents).to.include.deep.members([{
241 {227 method: 'ItemCreated',
242 success: true,228 section: 'common',
229 index: '0x4202',
243 collectionId,230 data: [
231 collection.collectionId.toString(),
244 itemId: tokenId,232 token.tokenId.toString(),
245 recipient: {Substrate: alice.address},233 {Substrate: alice.address},
246 amount: 100,234 '100',
247 },235 ],
248 ]);236 }]);
249 });237 });
250 });238 });
251239
252 it('Repartition with decreased amount', async () => {240 it('Repartition with decreased amount', async () => {
253 await usingApi(async api => {241 await usingPlaygrounds(async helper => {
254 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;242 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
255 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n)).itemId;243 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
256
257 const tx = api.tx.unique.repartition(collectionId, tokenId, 50n);244 await token.repartition(alice, 50n);
258 const events = await submitTransactionAsync(alice, tx);245 const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
259 const substrateEvents = getDestroyItemsResult(events);
260 expect(substrateEvents).to.include.deep.members([246 expect(chainEvents).to.include.deep.members([{
261 {247 method: 'ItemDestroyed',
262 success: true,248 section: 'common',
249 index: '0x4203',
263 collectionId,250 data: [
251 collection.collectionId.toString(),
264 itemId: tokenId,252 token.tokenId.toString(),
265 owner: {Substrate: alice.address},253 {Substrate: alice.address},
266 amount: 50,254 '50',
267 },255 ],
268 ]);256 }]);
269 });257 });
270 });258 });
271});
272
273describe('Test Refungible properties:', () => {
274 before(async () => {
275 await usingApi(async (api, privateKeyWrapper) => {
276 alice = privateKeyWrapper('//Alice');
277 bob = privateKeyWrapper('//Bob');
278 });
279 });
280 259
281 it('Сreate new collection with properties', async () => {260 it('Create new collection with properties', async () => {
282 await usingApi(async api => {261 await usingPlaygrounds(async helper => {
283 const properties = [{key: 'key1', value: 'val1'}];262 const properties = [{key: 'key1', value: 'val1'}];
284 const propertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];263 const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
285 const collectionId = await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'ReFungible'},264 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
286 properties: properties,
287 propPerm: propertyPermissions,
288 });
289 const collection = (await getDetailedCollectionInfo(api, collectionId))!;265 const info = await collection.getData();
290 expect(collection.properties.toHuman()).to.be.deep.equal(properties);266 expect(info?.raw.properties).to.be.deep.equal(properties);
291 expect(collection.tokenPropertyPermissions.toHuman()).to.be.deep.equal(propertyPermissions);267 expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
292 });268 });
293 });269 });
294});270});
271
295272
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
1616
17import chai from 'chai';17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
20import {createCollectionExpectSuccess, destroyCollectionExpectSuccess, getAdminList, normalizeAccountId, queryCollectionExpectSuccess} from './util/helpers';19import {usingPlaygrounds} from './util/playgrounds';
2120
22chai.use(chaiAsPromised);21chai.use(chaiAsPromised);
23const expect = chai.expect;22const expect = chai.expect;
2423
25describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {24describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
26 it('Remove collection admin.', async () => {25 it('Remove collection admin.', async () => {
27 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
28 const collectionId = await createCollectionExpectSuccess();27 const alice = privateKey('//Alice');
29 const alice = privateKeyWrapper('//Alice');28 const bob = privateKey('//Bob');
30 const bob = privateKeyWrapper('//Bob');29 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
31 const collection = await queryCollectionExpectSuccess(api, collectionId);30 const collectionInfo = await collection.getData();
32 expect(collection.owner.toString()).to.be.deep.eq(alice.address);31 expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
33 // first - add collection admin Bob32 // first - add collection admin Bob
34 const addAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));33 await collection.addAdmin(alice, {Substrate: bob.address});
35 await submitTransactionAsync(alice, addAdminTx);
3634
37 const adminListAfterAddAdmin = await getAdminList(api, collectionId);35 const adminListAfterAddAdmin = await collection.getAdmins();
38 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));36 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
3937
40 // then remove bob from admins of collection38 // then remove bob from admins of collection
41 const removeAdminTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));39 await collection.removeAdmin(alice, {Substrate: bob.address});
42 await submitTransactionAsync(alice, removeAdminTx);
4340
44 const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);41 const adminListAfterRemoveAdmin = await collection.getAdmins();
45 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(bob.address));42 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
46 });43 });
47 });44 });
4845
49 it('Remove admin from collection that has no admins', async () => {46 it('Remove admin from collection that has no admins', async () => {
50 await usingApi(async (api, privateKeyWrapper) => {47 await usingPlaygrounds(async (helper, privateKey) => {
51 const alice = privateKeyWrapper('//Alice');48 const alice = privateKey('//Alice');
52 const collectionId = await createCollectionExpectSuccess();49 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
5350
54 const adminListBeforeAddAdmin = await getAdminList(api, collectionId);51 const adminListBeforeAddAdmin = await collection.getAdmins();
55 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);52 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
5653
54 // await expect(collection.removeAdmin(alice, {Substrate: alice.address})).to.be.rejectedWith('Unable to remove collection admin');
57 const tx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(alice.address));55 await collection.removeAdmin(alice, {Substrate: alice.address});
58 await submitTransactionAsync(alice, tx);
59 });56 });
60 });57 });
61});58});
6259
63describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {60describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
64 it('Can\'t remove collection admin from not existing collection', async () => {61 it('Can\'t remove collection admin from not existing collection', async () => {
65 await usingApi(async (api, privateKeyWrapper) => {62 await usingPlaygrounds(async (helper, privateKey) => {
66 // tslint:disable-next-line: no-bitwise63 // tslint:disable-next-line: no-bitwise
67 const collectionId = (1 << 32) - 1;64 const collectionId = (1 << 32) - 1;
68 const alice = privateKeyWrapper('//Alice');65 const alice = privateKey('//Alice');
69 const bob = privateKeyWrapper('//Bob');66 const bob = privateKey('//Bob');
7067
71 const changeOwnerTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
72 await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;68 await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address})).to.be.rejected;
7369
74 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)70 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
75 await createCollectionExpectSuccess();71 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
76 });72 });
77 });73 });
7874
79 it('Can\'t remove collection admin from deleted collection', async () => {75 it('Can\'t remove collection admin from deleted collection', async () => {
80 await usingApi(async (api, privateKeyWrapper) => {76 await usingPlaygrounds(async (helper, privateKey) => {
81 // tslint:disable-next-line: no-bitwise
82 const collectionId = await createCollectionExpectSuccess();
83 const alice = privateKeyWrapper('//Alice');77 const alice = privateKey('//Alice');
84 const bob = privateKeyWrapper('//Bob');78 const bob = privateKey('//Bob');
85
86 await destroyCollectionExpectSuccess(collectionId);79 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
8780
88 const changeOwnerTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));81 expect(await collection.burn(alice)).to.be.true;
82
89 await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;83 await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address})).to.be.rejected;
9084
91 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)85 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
92 await createCollectionExpectSuccess();86 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
93 });87 });
94 });88 });
9589
96 it('Regular user can\'t remove collection admin', async () => {90 it('Regular user can\'t remove collection admin', async () => {
97 await usingApi(async (api, privateKeyWrapper) => {91 await usingPlaygrounds(async (helper, privateKey) => {
98 const collectionId = await createCollectionExpectSuccess();
99 const alice = privateKeyWrapper('//Alice');92 const alice = privateKey('//Alice');
100 const bob = privateKeyWrapper('//Bob');93 const bob = privateKey('//Bob');
101 const charlie = privateKeyWrapper('//Charlie');94 const charlie = privateKey('//Charlie');
102
103 const addAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));95 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
104 await submitTransactionAsync(alice, addAdminTx);
10596
106 const changeOwnerTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));97 await collection.addAdmin(alice, {Substrate: bob.address});
98
107 await expect(submitTransactionExpectFailAsync(charlie, changeOwnerTx)).to.be.rejected;99 await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
108100
109 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)101 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
110 await createCollectionExpectSuccess();102 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
111 });103 });
112 });104 });
113105
114 it('Admin can\'t remove collection admin.', async () => {106 it('Admin can\'t remove collection admin.', async () => {
115 await usingApi(async (api, privateKeyWrapper) => {107 await usingPlaygrounds(async (helper, privateKey) => {
116 const collectionId = await createCollectionExpectSuccess();
117 const alice = privateKeyWrapper('//Alice');108 const alice = privateKey('//Alice');
118 const bob = privateKeyWrapper('//Bob');109 const bob = privateKey('//Bob');
119 const charlie = privateKeyWrapper('//Charlie');110 const charlie = privateKey('//Charlie');
120
121 const addBobAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));111 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
112
122 await submitTransactionAsync(alice, addBobAdminTx);113 await collection.addAdmin(alice, {Substrate: bob.address});
123 const addCharlieAdminTx = api.tx.unique.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));114 await collection.addAdmin(alice, {Substrate: charlie.address});
124 await submitTransactionAsync(alice, addCharlieAdminTx);
125115
126 const adminListAfterAddAdmin = await getAdminList(api, collectionId);116 const adminListAfterAddAdmin = await collection.getAdmins();
127 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));117 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
128 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));118 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
129119
130 const removeAdminTx = api.tx.unique.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
131 await expect(submitTransactionExpectFailAsync(charlie, removeAdminTx)).to.be.rejected;120 await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
132121
133 const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);122 const adminListAfterRemoveAdmin = await collection.getAdmins();
134 expect(adminListAfterRemoveAdmin).to.be.deep.contains(normalizeAccountId(bob.address));123 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
135 expect(adminListAfterRemoveAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));124 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
136 });125 });
137 });126 });
138});127});
modifiedtests/src/rmrk/acceptNft.test.tsdiffbeforeafterboth
8} from './util/tx';8} from './util/tx';
9import {NftIdTuple} from './util/fetch';9import {NftIdTuple} from './util/fetch';
10import {isNftChildOfAnother, expectTxFailure} from './util/helpers';10import {isNftChildOfAnother, expectTxFailure} from './util/helpers';
11import {requirePallets, Pallets} from '../util/helpers';
1112
12describe('integration test: accept NFT', () => {13describe('integration test: accept NFT', () => {
13 let api: any;14 let api: any;
14 before(async () => { api = await getApiConnection(); });15 before(async function() {
1516 api = await getApiConnection();
17 await requirePallets(this, [Pallets.RmrkCore]);
18 });
19
20
modifiedtests/src/rmrk/addResource.test.tsdiffbeforeafterboth
12 addNftComposableResource,12 addNftComposableResource,
13} from './util/tx';13} from './util/tx';
14import {RmrkTraitsResourceResourceInfo as ResourceInfo} from '@polkadot/types/lookup';14import {RmrkTraitsResourceResourceInfo as ResourceInfo} from '@polkadot/types/lookup';
15import {requirePallets, Pallets} from '../util/helpers';
1516
16describe('integration test: add NFT resource', () => {17describe('integration test: add NFT resource', () => {
17 const Alice = '//Alice';18 const Alice = '//Alice';
24 const nonexistentId = 99999;25 const nonexistentId = 99999;
2526
26 let api: any;27 let api: any;
27 before(async () => {28 before(async function() {
28 api = await getApiConnection();29 api = await getApiConnection();
30 await requirePallets(this, [Pallets.RmrkCore]);
29 });31 });
3032
31 it('add resource', async () => {33 it('add resource', async () => {
modifiedtests/src/rmrk/addTheme.test.tsdiffbeforeafterboth
3import {createBase, addTheme} from './util/tx';3import {createBase, addTheme} from './util/tx';
4import {expectTxFailure} from './util/helpers';4import {expectTxFailure} from './util/helpers';
5import {getThemeNames} from './util/fetch';5import {getThemeNames} from './util/fetch';
6import {requirePallets, Pallets} from '../util/helpers';
67
7describe('integration test: add Theme to Base', () => {8describe('integration test: add Theme to Base', () => {
8 let api: any;9 let api: any;
9 before(async () => { api = await getApiConnection(); });10 before(async function() {
11 api = await getApiConnection();
12 await requirePallets(this, [Pallets.RmrkEquip]);
13 });
1014
11 const alice = '//Alice';15 const alice = '//Alice';
modifiedtests/src/rmrk/burnNft.test.tsdiffbeforeafterboth
55
6import chai from 'chai';6import chai from 'chai';
7import chaiAsPromised from 'chai-as-promised';7import chaiAsPromised from 'chai-as-promised';
8import {requirePallets, Pallets} from '../util/helpers';
89
9chai.use(chaiAsPromised);10chai.use(chaiAsPromised);
10const expect = chai.expect;11const expect = chai.expect;
14 const Bob = '//Bob';15 const Bob = '//Bob';
1516
16 let api: any;17 let api: any;
17 before(async () => {18 before(async function() {
18 api = await getApiConnection();19 api = await getApiConnection();
20 await requirePallets(this, [Pallets.RmrkCore]);
19 });21 });
22
2023
modifiedtests/src/rmrk/changeCollectionIssuer.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {expectTxFailure} from './util/helpers';3import {expectTxFailure} from './util/helpers';
3import {4import {
4 changeIssuer,5 changeIssuer,
10 const Bob = '//Bob';11 const Bob = '//Bob';
1112
12 let api: any;13 let api: any;
13 before(async () => {14 before(async function() {
14 api = await getApiConnection();15 api = await getApiConnection();
16 await requirePallets(this, [Pallets.RmrkCore]);
15 });17 });
18
19
modifiedtests/src/rmrk/createBase.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {createCollection, createBase} from './util/tx';3import {createCollection, createBase} from './util/tx';
34
4describe('integration test: create new Base', () => {5describe('integration test: create new Base', () => {
5 let api: any;6 let api: any;
6 before(async () => { api = await getApiConnection(); });7 before(async function() {
8 api = await getApiConnection();
9 await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
10 });
711
8 const alice = '//Alice';12 const alice = '//Alice';
modifiedtests/src/rmrk/createCollection.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {createCollection} from './util/tx';3import {createCollection} from './util/tx';
34
4describe('Integration test: create new collection', () => {5describe('Integration test: create new collection', () => {
5 let api: any;6 let api: any;
6 before(async () => { api = await getApiConnection(); });7 before(async function () {
8 api = await getApiConnection();
9 await requirePallets(this, [Pallets.RmrkCore]);
10 });
11
12
modifiedtests/src/rmrk/deleteCollection.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {expectTxFailure} from './util/helpers';3import {expectTxFailure} from './util/helpers';
3import {createCollection, deleteCollection} from './util/tx';4import {createCollection, deleteCollection} from './util/tx';
45
5describe('integration test: delete collection', () => {6describe('integration test: delete collection', () => {
6 let api: any;7 let api: any;
7 before(async () => {8 before(async function () {
8 api = await getApiConnection();9 api = await getApiConnection();
10 await requirePallets(this, [Pallets.RmrkCore]);
9 });11 });
1012
11 const Alice = '//Alice';13 const Alice = '//Alice';
modifiedtests/src/rmrk/equipNft.test.tsdiffbeforeafterboth
1import {ApiPromise} from '@polkadot/api';1import {ApiPromise} from '@polkadot/api';
2import {expect} from 'chai';2import {expect} from 'chai';
3import {getApiConnection} from '../substrate/substrate-api';3import {getApiConnection} from '../substrate/substrate-api';
4import {requirePallets, Pallets} from '../util/helpers';
4import {getNft, getParts, NftIdTuple} from './util/fetch';5import {getNft, getParts, NftIdTuple} from './util/fetch';
5import {expectTxFailure} from './util/helpers';6import {expectTxFailure} from './util/helpers';
6import {7import {
123124
124 let api: any;125 let api: any;
126
125 before(async () => {127 before(async function () {
126 api = await getApiConnection();128 api = await getApiConnection();
129 await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
127 });130 });
128131
129 it('equip nft', async () => {132 it('equip nft', async () => {
modifiedtests/src/rmrk/getOwnedNfts.test.tsdiffbeforeafterboth
1import {expect} from 'chai';1import {expect} from 'chai';
2import {getApiConnection} from '../substrate/substrate-api';2import {getApiConnection} from '../substrate/substrate-api';
3import {requirePallets, Pallets} from '../util/helpers';
3import {getOwnedNfts} from './util/fetch';4import {getOwnedNfts} from './util/fetch';
4import {mintNft, createCollection} from './util/tx';5import {mintNft, createCollection} from './util/tx';
56
6describe('integration test: get owned NFTs', () => {7describe('integration test: get owned NFTs', () => {
7 let api: any;8 let api: any;
9
8 before(async () => { api = await getApiConnection(); });10 before(async function () {
11 api = await getApiConnection();
12 await requirePallets(this, [Pallets.RmrkCore]);
13 });
14
915
modifiedtests/src/rmrk/lockCollection.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {expectTxFailure} from './util/helpers';3import {expectTxFailure} from './util/helpers';
3import {createCollection, lockCollection, mintNft} from './util/tx';4import {createCollection, lockCollection, mintNft} from './util/tx';
45
8 const Max = 5;9 const Max = 5;
910
10 let api: any;11 let api: any;
11 before(async () => {12 before(async function () {
12 api = await getApiConnection();13 api = await getApiConnection();
14 await requirePallets(this, [Pallets.RmrkCore]);
13 });15 });
1416
15 it('lock collection', async () => {17 it('lock collection', async () => {
modifiedtests/src/rmrk/mintNft.test.tsdiffbeforeafterboth
1import {expect} from 'chai';1import {expect} from 'chai';
2import {getApiConnection} from '../substrate/substrate-api';2import {getApiConnection} from '../substrate/substrate-api';
3import {requirePallets, Pallets} from '../util/helpers';
3import {getNft} from './util/fetch';4import {getNft} from './util/fetch';
4import {expectTxFailure} from './util/helpers';5import {expectTxFailure} from './util/helpers';
5import {createCollection, mintNft} from './util/tx';6import {createCollection, mintNft} from './util/tx';
67
7describe('integration test: mint new NFT', () => {8describe('integration test: mint new NFT', () => {
8 let api: any;9 let api: any;
10
9 before(async () => { api = await getApiConnection(); });11 before(async function () {
12 api = await getApiConnection();
13 await requirePallets(this, [Pallets.RmrkCore]);
14 });
15
1016
modifiedtests/src/rmrk/rejectNft.test.tsdiffbeforeafterboth
8} from './util/tx';8} from './util/tx';
9import {getChildren, NftIdTuple} from './util/fetch';9import {getChildren, NftIdTuple} from './util/fetch';
10import {isNftChildOfAnother, expectTxFailure} from './util/helpers';10import {isNftChildOfAnother, expectTxFailure} from './util/helpers';
11import {requirePallets, Pallets} from '../util/helpers';
1112
12describe('integration test: reject NFT', () => {13describe('integration test: reject NFT', () => {
13 let api: any;14 let api: any;
14 before(async () => { api = await getApiConnection(); });15 before(async function () {
16 api = await getApiConnection();
17 await requirePallets(this, [Pallets.RmrkCore]);
18 });
19
20
modifiedtests/src/rmrk/removeResource.test.tsdiffbeforeafterboth
1import {expect} from 'chai';1import {expect} from 'chai';
2import privateKey from '../substrate/privateKey';2import privateKey from '../substrate/privateKey';
3import {executeTransaction, getApiConnection} from '../substrate/substrate-api';3import {executeTransaction, getApiConnection} from '../substrate/substrate-api';
4import {requirePallets, Pallets} from '../util/helpers';
4import {getNft, NftIdTuple} from './util/fetch';5import {getNft, NftIdTuple} from './util/fetch';
5import {expectTxFailure} from './util/helpers';6import {expectTxFailure} from './util/helpers';
6import {7import {
16describe('Integration test: remove nft resource', () => {17describe('Integration test: remove nft resource', () => {
17 let api: any;18 let api: any;
18 let ss58Format: string;19 let ss58Format: string;
19 before(async () => {20 before(async function() {
20 api = await getApiConnection();21 api = await getApiConnection();
21 ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;22 ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
23 await requirePallets(this, [Pallets.RmrkCore]);
22 });24 });
2325
24 const Alice = '//Alice';26 const Alice = '//Alice';
modifiedtests/src/rmrk/rmrkIsolation.test.tsdiffbeforeafterboth
6 getCreateCollectionResult,6 getCreateCollectionResult,
7 getDetailedCollectionInfo,7 getDetailedCollectionInfo,
8 getGenericResult,8 getGenericResult,
9 requirePallets,
9 normalizeAccountId,10 normalizeAccountId,
11 Pallets,
10} from '../util/helpers';12} from '../util/helpers';
11import {IKeyringPair} from '@polkadot/types/types';13import {IKeyringPair} from '@polkadot/types/types';
12import {ApiPromise} from '@polkadot/api';14import {ApiPromise} from '@polkadot/api';
59describe('RMRK External Integration Test', async () => {61describe('RMRK External Integration Test', async () => {
60 const it_rmrk = (await isUnique() ? it : it.skip);62 const it_rmrk = (await isUnique() ? it : it.skip);
6163
62 before(async () => {64 before(async function() {
63 await usingApi(async (api, privateKeyWrapper) => {65 await usingApi(async (api, privateKeyWrapper) => {
64 alice = privateKeyWrapper('//Alice');66 alice = privateKeyWrapper('//Alice');
6567 await requirePallets(this, [Pallets.RmrkCore]);
66
67 });68 });
68 });69 });
modifiedtests/src/rmrk/sendNft.test.tsdiffbeforeafterboth
3import {createCollection, mintNft, sendNft} from './util/tx';3import {createCollection, mintNft, sendNft} from './util/tx';
4import {NftIdTuple} from './util/fetch';4import {NftIdTuple} from './util/fetch';
5import {isNftChildOfAnother, expectTxFailure} from './util/helpers';5import {isNftChildOfAnother, expectTxFailure} from './util/helpers';
6import {requirePallets, Pallets} from '../util/helpers';
67
7describe('integration test: send NFT', () => {8describe('integration test: send NFT', () => {
8 let api: any;9 let api: any;
9 before(async () => { api = await getApiConnection(); });10 before(async function () {
11 api = await getApiConnection();
12 await requirePallets(this, [Pallets.RmrkCore]);
13 });
1014
11 const maxNftId = 0xFFFFFFFF;15 const maxNftId = 0xFFFFFFFF;
modifiedtests/src/rmrk/setCollectionProperty.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {expectTxFailure} from './util/helpers';3import {expectTxFailure} from './util/helpers';
3import {createCollection, setPropertyCollection} from './util/tx';4import {createCollection, setPropertyCollection} from './util/tx';
45
7 const Bob = '//Bob';8 const Bob = '//Bob';
89
9 let api: any;10 let api: any;
10 before(async () => {11 before(async function () {
11 api = await getApiConnection();12 api = await getApiConnection();
13 await requirePallets(this, [Pallets.RmrkCore]);
12 });14 });
1315
14 it('set collection property', async () => {16 it('set collection property', async () => {
modifiedtests/src/rmrk/setEquippableList.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {expectTxFailure} from './util/helpers';3import {expectTxFailure} from './util/helpers';
3import {createCollection, createBase, setEquippableList} from './util/tx';4import {createCollection, createBase, setEquippableList} from './util/tx';
45
5describe("integration test: set slot's Equippable List", () => {6describe("integration test: set slot's Equippable List", () => {
6 let api: any;7 let api: any;
7 before(async () => { api = await getApiConnection(); });8 before(async function () {
9 api = await getApiConnection();
10 await requirePallets(this, [Pallets.RmrkCore]);
11 });
812
9 const alice = '//Alice';13 const alice = '//Alice';
modifiedtests/src/rmrk/setNftProperty.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {NftIdTuple} from './util/fetch';3import {NftIdTuple} from './util/fetch';
3import {expectTxFailure} from './util/helpers';4import {expectTxFailure} from './util/helpers';
4import {createCollection, mintNft, sendNft, setNftProperty} from './util/tx';5import {createCollection, mintNft, sendNft, setNftProperty} from './util/tx';
56
6describe('integration test: set NFT property', () => {7describe('integration test: set NFT property', () => {
7 let api: any;8 let api: any;
8 before(async () => { api = await getApiConnection(); });9 before(async function () {
10 api = await getApiConnection();
11 await requirePallets(this, [Pallets.RmrkCore]);
12 });
913
10 const alice = '//Alice';14 const alice = '//Alice';
modifiedtests/src/rmrk/setResourcePriorities.test.tsdiffbeforeafterboth
1import {getApiConnection} from '../substrate/substrate-api';1import {getApiConnection} from '../substrate/substrate-api';
2import {requirePallets, Pallets} from '../util/helpers';
2import {expectTxFailure} from './util/helpers';3import {expectTxFailure} from './util/helpers';
3import {mintNft, createCollection, setResourcePriorities} from './util/tx';4import {mintNft, createCollection, setResourcePriorities} from './util/tx';
45
5describe('integration test: set NFT resource priorities', () => {6describe('integration test: set NFT resource priorities', () => {
6 let api: any;7 let api: any;
7 before(async () => { api = await getApiConnection(); });8 before(async function () {
9 api = await getApiConnection();
10 await requirePallets(this, [Pallets.RmrkCore]);
11 });
812
9 const alice = '//Alice';13 const alice = '//Alice';
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
23 setCollectionSponsorExpectFailure,23 setCollectionSponsorExpectFailure,
24 addCollectionAdminExpectSuccess,24 addCollectionAdminExpectSuccess,
25 getCreatedCollectionCount,25 getCreatedCollectionCount,
26 requirePallets,
27 Pallets,
26} from './util/helpers';28} from './util/helpers';
27import {IKeyringPair} from '@polkadot/types/types';29import {IKeyringPair} from '@polkadot/types/types';
2830
50 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});52 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
51 await setCollectionSponsorExpectSuccess(collectionId, bob.address);53 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
52 });54 });
53 it('Set ReFungible collection sponsor', async () => {55 it('Set ReFungible collection sponsor', async function() {
56 await requirePallets(this, [Pallets.ReFungible]);
57
54 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});58 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
55 await setCollectionSponsorExpectSuccess(collectionId, bob.address);59 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
35 getBalance as getTokenBalance,35 getBalance as getTokenBalance,
36 transferFromExpectSuccess,36 transferFromExpectSuccess,
37 transferFromExpectFail,37 transferFromExpectFail,
38 requirePallets,
39 Pallets,
38} from './util/helpers';40} from './util/helpers';
39import {41import {
40 subToEth,42 subToEth,
41 itWeb3, 43 itWeb3,
42} from './eth/util/helpers';44} from './eth/util/helpers';
45import {request} from 'https';
4346
44let alice: IKeyringPair;47let alice: IKeyringPair;
45let bob: IKeyringPair;48let bob: IKeyringPair;
89 });92 });
90 });93 });
94
95 it('[nft] User can transfer owned token', async () => {
96 const nftCollectionId = await createCollectionExpectSuccess();
97 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
98 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
99 });
91100
92 it('User can transfer owned token', async () => {101 it('[fungible] User can transfer owned token', async () => {
93 await usingApi(async (api, privateKeyWrapper) => {
94 // nft
95 const nftCollectionId = await createCollectionExpectSuccess();
96 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
97 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
98 // fungible
99 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});102 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
100 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');103 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
101 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');104 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
102 // reFungible
103 const reFungibleCollectionId = await
104 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
105 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
106 await transferExpectSuccess(
107 reFungibleCollectionId,
108 newReFungibleTokenId,
109 alice,
110 bob,
111 100,
112 'ReFungible',
113 );
114 });
115 });105 });
106
107 it('[refungible] User can transfer owned token', async function() {
108 await requirePallets(this, [Pallets.ReFungible]);
109
110 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
111 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
112 await transferExpectSuccess(
113 reFungibleCollectionId,
114 newReFungibleTokenId,
115 alice,
116 bob,
117 100,
118 'ReFungible',
119 );
120 });
121
122 it('[nft] Collection admin can transfer owned token', async () => {
123 const nftCollectionId = await createCollectionExpectSuccess();
124 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
125 const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
126 await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
127 });
116128
117 it('Collection admin can transfer owned token', async () => {129 it('[fungible] Collection admin can transfer owned token', async () => {
118 await usingApi(async (api, privateKeyWrapper) => {
119 // nft
120 const nftCollectionId = await createCollectionExpectSuccess();
121 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
122 const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
123 await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
124 // fungible
125 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});130 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
126 await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);131 await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
127 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);132 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
128 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');133 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
129 // reFungible
130 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
131 await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
132 const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
133 await transferExpectSuccess(
134 reFungibleCollectionId,
135 newReFungibleTokenId,
136 bob,
137 alice,
138 100,
139 'ReFungible',
140 );
141 });
142 });134 });
135
136 it('[refungible] Collection admin can transfer owned token', async function() {
137 await requirePallets(this, [Pallets.ReFungible]);
138
139 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
140 await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
141 const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
142 await transferExpectSuccess(
143 reFungibleCollectionId,
144 newReFungibleTokenId,
145 bob,
146 alice,
147 100,
148 'ReFungible',
149 );
150 });
143});151});
144152
145describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {153describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
151 });159 });
152 });160 });
161
153 it('Transfer with not existed collection_id', async () => {162 it('[nft] Transfer with not existed collection_id', async () => {
154 await usingApi(async (api) => {163 await usingApi(async (api) => {
155 // nft
156 const nftCollectionCount = await getCreatedCollectionCount(api);164 const nftCollectionCount = await getCreatedCollectionCount(api);
157 await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);165 await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);
158 // fungible
159 const fungibleCollectionCount = await getCreatedCollectionCount(api);
160 await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
161 // reFungible
162 const reFungibleCollectionCount = await getCreatedCollectionCount(api);
163 await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
164 });166 });
165 });167 });
166 it('Transfer with deleted collection_id', async () => {168
167 // nft169 it('[fungible] Transfer with not existed collection_id', async () => {
170 await usingApi(async (api) => {
171 const fungibleCollectionCount = await getCreatedCollectionCount(api);
172 await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
173 });
174 });
175
176 it('[refungible] Transfer with not existed collection_id', async function() {
177 await requirePallets(this, [Pallets.ReFungible]);
178
179 await usingApi(async (api) => {
180 const reFungibleCollectionCount = await getCreatedCollectionCount(api);
181 await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
182 });
168 const nftCollectionId = await createCollectionExpectSuccess();183 });
169 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');184
170 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);185 it('[nft] Transfer with deleted collection_id', async () => {
171 await destroyCollectionExpectSuccess(nftCollectionId);186 const nftCollectionId = await createCollectionExpectSuccess();
172 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);187 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
173 // fungible188 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);
189 await destroyCollectionExpectSuccess(nftCollectionId);
190 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
191 });
192
193 it('[fungible] Transfer with deleted collection_id', async () => {
174 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});194 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
175 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');195 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
176 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);196 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
177 await destroyCollectionExpectSuccess(fungibleCollectionId);197 await destroyCollectionExpectSuccess(fungibleCollectionId);
178 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);198 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
179 // reFungible199 });
200
201 it('[refungible] Transfer with deleted collection_id', async function() {
202 await requirePallets(this, [Pallets.ReFungible]);
203
180 const reFungibleCollectionId = await204 const reFungibleCollectionId = await
181 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});205 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
189 bob,213 bob,
190 1,214 1,
191 );215 );
192 });216 });
217
218 it('[nft] Transfer with not existed item_id', async () => {
219 const nftCollectionId = await createCollectionExpectSuccess();
220 await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
221 });
222
223 it('[fungible] Transfer with not existed item_id', async () => {
224 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
225 await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);
226 });
227
228 it('[refungible] Transfer with not existed item_id', async function() {
229 await requirePallets(this, [Pallets.ReFungible]);
230
231 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
232 await transferExpectFailure(
233 reFungibleCollectionId,
234 2,
235 alice,
236 bob,
237 1,
238 );
239 });
240
241 it('[nft] Transfer with deleted item_id', async () => {
242 const nftCollectionId = await createCollectionExpectSuccess();
243 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
244 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
245 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
246 });
247
193 it('Transfer with not existed item_id', async () => {248 it('[fungible] Transfer with deleted item_id', async () => {
194 // nft
195 const nftCollectionId = await createCollectionExpectSuccess();
196 await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
197 // fungible
198 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});249 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
199 await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);250 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
200 // reFungible
201 const reFungibleCollectionId = await251 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
202 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
203 await transferExpectFailure(252 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
204 reFungibleCollectionId,
205 2,
206 alice,
207 bob,
208 1,
209 );
210 });253 });
254
211 it('Transfer with deleted item_id', async () => {255 it('[refungible] Transfer with deleted item_id', async function() {
212 // nft
213 const nftCollectionId = await createCollectionExpectSuccess();
214 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
215 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
216 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
217 // fungible
218 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});256 await requirePallets(this, [Pallets.ReFungible]);
219 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');257
220 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
221 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
222 // reFungible
223 const reFungibleCollectionId = await258 const reFungibleCollectionId = await
224 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});259 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
225 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');260 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
233 );268 );
234 });269 });
270
271 it('[nft] Transfer with recipient that is not owner', async () => {
272 const nftCollectionId = await createCollectionExpectSuccess();
273 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
274 await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
275 });
276
277 it('[fungible] Transfer with recipient that is not owner', async () => {
278 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
279 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
280 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
281 });
282
235 it('Transfer with recipient that is not owner', async () => {283 it('[refungible] Transfer with recipient that is not owner', async function() {
236 // nft
237 const nftCollectionId = await createCollectionExpectSuccess();
238 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
239 await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
240 // fungible
241 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});284 await requirePallets(this, [Pallets.ReFungible]);
242 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');285
243 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
244 // reFungible
245 const reFungibleCollectionId = await286 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
246 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
247 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');287 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
276 });316 });
277 });317 });
278318
279 it('RFT', async () => {319 it('RFT', async function() {
320 await requirePallets(this, [Pallets.ReFungible]);
321
280 await usingApi(async (api: ApiPromise) => {322 await usingApi(async (api: ApiPromise) => {
281 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});323 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
31 burnItemExpectSuccess,31 burnItemExpectSuccess,
32 setCollectionLimitsExpectSuccess,32 setCollectionLimitsExpectSuccess,
33 getCreatedCollectionCount,33 getCreatedCollectionCount,
34 requirePallets,
35 Pallets,
34} from './util/helpers';36} from './util/helpers';
3537
36chai.use(chaiAsPromised);38chai.use(chaiAsPromised);
49 });51 });
50 });52 });
53
54 it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {
55 const nftCollectionId = await createCollectionExpectSuccess();
56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
58
59 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
60 });
5161
52 it('Execute the extrinsic and check nftItemList - owner of token', async () => {62 it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {
53 await usingApi(async () => {
54 // nft
55 const nftCollectionId = await createCollectionExpectSuccess();
56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
58
59 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
60
61 // fungible
62 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});63 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
63 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');64 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
64 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);65 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
65 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');66 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
66
67 // reFungible
68 const reFungibleCollectionId = await
69 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
70 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
71 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
72 await transferFromExpectSuccess(
73 reFungibleCollectionId,
74 newReFungibleTokenId,
75 bob,
76 alice,
77 charlie,
78 100,
79 'ReFungible',
80 );
81 });
82 });67 });
68
69 it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {
70 await requirePallets(this, [Pallets.ReFungible]);
71
72 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
73 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
74 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
75 await transferFromExpectSuccess(
76 reFungibleCollectionId,
77 newReFungibleTokenId,
78 bob,
79 alice,
80 charlie,
81 100,
82 'ReFungible',
83 );
84 });
8385
84 it('Should reduce allowance if value is big', async () => {86 it('Should reduce allowance if value is big', async () => {
85 await usingApi(async (api, privateKeyWrapper) => {87 await usingApi(async (api, privateKeyWrapper) => {
119 });121 });
120 });122 });
121123
122 it('transferFrom for a collection that does not exist', async () => {124 it('[nft] transferFrom for a collection that does not exist', async () => {
123 await usingApi(async (api: ApiPromise) => {125 await usingApi(async (api: ApiPromise) => {
124 // nft
125 const nftCollectionCount = await getCreatedCollectionCount(api);126 const nftCollectionCount = await getCreatedCollectionCount(api);
126 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);127 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
127128
128 await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);129 await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);
129
130 // fungible
131 const fungibleCollectionCount = await getCreatedCollectionCount(api);
132 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
133
134 await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
135 // reFungible
136 const reFungibleCollectionCount = await getCreatedCollectionCount(api);
137 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
138
139 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);
140 });130 });
141 });131 });
132
133 it('[fungible] transferFrom for a collection that does not exist', async () => {
134 await usingApi(async (api: ApiPromise) => {
135 const fungibleCollectionCount = await getCreatedCollectionCount(api);
136 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
137
138 await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
139 });
140 });
141
142 it('[refungible] transferFrom for a collection that does not exist', async function() {
143 await requirePallets(this, [Pallets.ReFungible]);
144
145 await usingApi(async (api: ApiPromise) => {
146 const reFungibleCollectionCount = await getCreatedCollectionCount(api);
147 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
148
149 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);
150 });
151 });
142152
143 /* it('transferFrom for a collection that was destroyed', async () => {153 /* it('transferFrom for a collection that was destroyed', async () => {
144 await usingApi(async (api: ApiPromise) => {154 await usingApi(async (api: ApiPromise) => {
158 });168 });
159 }); */169 }); */
170
171 it('[nft] transferFrom for not approved address', async () => {
172 const nftCollectionId = await createCollectionExpectSuccess();
173 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
174
175 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
176 });
160177
161 it('transferFrom for not approved address', async () => {178 it('[fungible] transferFrom for not approved address', async () => {
162 await usingApi(async () => {
163 // nft
164 const nftCollectionId = await createCollectionExpectSuccess();
165 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
166
167 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
168
169 // fungible
170 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});179 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
171 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');180 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
172 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);181 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
173 // reFungible
174 const reFungibleCollectionId = await
175 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
176 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
177 await transferFromExpectFail(
178 reFungibleCollectionId,
179 newReFungibleTokenId,
180 bob,
181 alice,
182 charlie,
183 1,
184 );
185 });
186 });182 });
183
184 it('[refungible] transferFrom for not approved address', async function() {
185 await requirePallets(this, [Pallets.ReFungible]);
186
187 const reFungibleCollectionId = await
188 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
189 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
190 await transferFromExpectFail(
191 reFungibleCollectionId,
192 newReFungibleTokenId,
193 bob,
194 alice,
195 charlie,
196 1,
197 );
198 });
199
200 it('[nft] transferFrom incorrect token count', async () => {
201 const nftCollectionId = await createCollectionExpectSuccess();
202 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
203 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
204
205 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
206 });
187207
188 it('transferFrom incorrect token count', async () => {208 it('[fungible] transferFrom incorrect token count', async () => {
189 await usingApi(async () => {
190 // nft
191 const nftCollectionId = await createCollectionExpectSuccess();
192 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
193 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
194
195 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
196
197 // fungible
198 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});209 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
199 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');210 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
200 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);211 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
201 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);212 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
202 // reFungible
203 const reFungibleCollectionId = await
204 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
205 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
206 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
207 await transferFromExpectFail(
208 reFungibleCollectionId,
209 newReFungibleTokenId,
210 bob,
211 alice,
212 charlie,
213 2,
214 );
215 });
216 });213 });
214
215 it('[refungible] transferFrom incorrect token count', async function() {
216 await requirePallets(this, [Pallets.ReFungible]);
217
218 const reFungibleCollectionId = await
219 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
220 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
221 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
222 await transferFromExpectFail(
223 reFungibleCollectionId,
224 newReFungibleTokenId,
225 bob,
226 alice,
227 charlie,
228 2,
229 );
230 });
231
232 it('[nft] execute transferFrom from account that is not owner of collection', async () => {
233 await usingApi(async (api, privateKeyWrapper) => {
234 const dave = privateKeyWrapper('//Dave');
235 const nftCollectionId = await createCollectionExpectSuccess();
236 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
237 try {
238 await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
239 await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);
240 } catch (e) {
241 // tslint:disable-next-line:no-unused-expression
242 expect(e).to.be.exist;
243 }
244
245 // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
246 });
247 });
217248
218 it('execute transferFrom from account that is not owner of collection', async () => {249 it('[fungible] execute transferFrom from account that is not owner of collection', async () => {
219 await usingApi(async (api, privateKeyWrapper) => {250 await usingApi(async (api, privateKeyWrapper) => {
220 const dave = privateKeyWrapper('//Dave');251 const dave = privateKeyWrapper('//Dave');
221 // nft252
222 const nftCollectionId = await createCollectionExpectSuccess();
223 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
224 try {
225 await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
226 await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);
227 } catch (e) {
228 // tslint:disable-next-line:no-unused-expression
229 expect(e).to.be.exist;
230 }
231
232 // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
233
234 // fungible
235 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});253 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
236 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');254 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
237 try {255 try {
241 // tslint:disable-next-line:no-unused-expression259 // tslint:disable-next-line:no-unused-expression
242 expect(e).to.be.exist;260 expect(e).to.be.exist;
243 }261 }
244 // reFungible
245 const reFungibleCollectionId = await
246 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
247 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
248 try {
249 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
250 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
251 } catch (e) {
252 // tslint:disable-next-line:no-unused-expression
253 expect(e).to.be.exist;
254 }
255 });262 });
256 });263 });
264
265 it('[refungible] execute transferFrom from account that is not owner of collection', async function() {
266 await requirePallets(this, [Pallets.ReFungible]);
267
268 await usingApi(async (api, privateKeyWrapper) => {
269 const dave = privateKeyWrapper('//Dave');
270 const reFungibleCollectionId = await
271 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
272 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
273 try {
274 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
275 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
276 } catch (e) {
277 // tslint:disable-next-line:no-unused-expression
278 expect(e).to.be.exist;
279 }
280 });
281 });
257 it('transferFrom burnt token before approve NFT', async () => {282 it('transferFrom burnt token before approve NFT', async () => {
258 await usingApi(async () => {283 await usingApi(async () => {
259 // nft284 // nft
276301
277 });302 });
278 });303 });
279 it('transferFrom burnt token before approve ReFungible', async () => {304 it('transferFrom burnt token before approve ReFungible', async function() {
305 await requirePallets(this, [Pallets.ReFungible]);
306
280 await usingApi(async () => {307 await usingApi(async () => {
281 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});308 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
308335
309 });336 });
310 });337 });
311 it('transferFrom burnt token after approve ReFungible', async () => {338 it('transferFrom burnt token after approve ReFungible', async function() {
339 await requirePallets(this, [Pallets.ReFungible]);
340
312 await usingApi(async () => {341 await usingApi(async () => {
313 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});342 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
28import {hexToStr, strToUTF16, utf16ToStr} from './util';28import {hexToStr, strToUTF16, utf16ToStr} from './util';
29import {UpDataStructsRpcCollection, UpDataStructsCreateItemData, UpDataStructsProperty} from '@polkadot/types/lookup';29import {UpDataStructsRpcCollection, UpDataStructsCreateItemData, UpDataStructsProperty} from '@polkadot/types/lookup';
30import {UpDataStructsTokenChild} from '../interfaces';30import {UpDataStructsTokenChild} from '../interfaces';
31import {Context} from 'mocha';
3132
32chai.use(chaiAsPromised);33chai.use(chaiAsPromised);
33const expect = chai.expect;34const expect = chai.expect;
39};40};
41
42
43export enum Pallets {
44 Inflation = 'inflation',
45 RmrkCore = 'rmrkcore',
46 RmrkEquip = 'rmrkequip',
47 ReFungible = 'refungible',
48 Fungible = 'fungible',
49 NFT = 'nonfungible',
50 Scheduler = 'scheduler',
51}
52
53export async function isUnique(): Promise<boolean> {
54 return usingApi(async api => {
55 const chain = await api.rpc.system.chain();
56
57 return chain.eq('UNIQUE');
58 });
59}
60
61export async function isQuartz(): Promise<boolean> {
62 return usingApi(async api => {
63 const chain = await api.rpc.system.chain();
64
65 return chain.eq('QUARTZ');
66 });
67}
68
69let modulesNames: any;
70export function getModuleNames(api: ApiPromise): string[] {
71 if (typeof modulesNames === 'undefined')
72 modulesNames = api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());
73 return modulesNames;
74}
75
76export async function missingRequiredPallets(requiredPallets: string[]): Promise<string[]> {
77 return await usingApi(async api => {
78 const pallets = getModuleNames(api);
79
80 return requiredPallets.filter(p => !pallets.includes(p));
81 });
82}
83
84export async function checkPalletsPresence(requiredPallets: string[]): Promise<boolean> {
85 return (await missingRequiredPallets(requiredPallets)).length == 0;
86}
87
88export async function requirePallets(mocha: Context, requiredPallets: string[]) {
89 const missingPallets = await missingRequiredPallets(requiredPallets);
90
91 if (missingPallets.length > 0) {
92 const skippingTestMsg = `\tSkipping test "${mocha.test?.title}".`;
93 const missingPalletsMsg = `\tThe following pallets are missing:\n\t- ${missingPallets.join('\n\t- ')}`;
94 const skipMsg = `${skippingTestMsg}\n${missingPalletsMsg}`;
95
96 console.error('\x1b[38:5:208m%s\x1b[0m', skipMsg);
97
98 mocha.skip();
99 }
100}
40101
41export function normalizeAccountId(input: string | AccountId | CrossAccountId | IKeyringPair): CrossAccountId {102export function normalizeAccountId(input: string | AccountId | CrossAccountId | IKeyringPair): CrossAccountId {
42 if (typeof input === 'string') {103 if (typeof input === 'string') {
addedtests/src/util/playgrounds/index.tsdiffbeforeafterboth

no changes

addedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth

no changes

modifiedtests/yarn.lockdiffbeforeafterboth
963 dependencies:963 dependencies:
964 "@types/chai" "*"964 "@types/chai" "*"
965965
966"@types/chai-like@^1.1.1":
967 version "1.1.1"
968 resolved "https://registry.yarnpkg.com/@types/chai-like/-/chai-like-1.1.1.tgz#c454039b0a2f92664fb5b7b7a2a66c3358783ae7"
969 integrity sha512-s46EZsupBuVhLn66DbRee5B0SELLmL4nFXVrBiV29BxLGm9Sh7Bful623j3AfiQRu2zAP4cnlZ3ETWB3eWc4bA==
970 dependencies:
971 "@types/chai" "*"
972
966"@types/chai@*", "@types/chai@^4.3.1":973"@types/chai@*", "@types/chai@^4.3.1":
967 version "4.3.1"974 version "4.3.1"
968 resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04"975 resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04"
1544 integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==1551 integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==
1545 dependencies:1552 dependencies:
1546 check-error "^1.0.2"1553 check-error "^1.0.2"
1554
1555chai-like@^1.1.1:
1556 version "1.1.1"
1557 resolved "https://registry.yarnpkg.com/chai-like/-/chai-like-1.1.1.tgz#8c558a414c34514e814d497c772547ceb7958f64"
1558 integrity sha512-VKa9z/SnhXhkT1zIjtPACFWSoWsqVoaz1Vg+ecrKo5DCKVlgL30F/pEyEvXPBOVwCgLZcWUleCM/C1okaKdTTA==
15471559
1548chai@^4.3.6:1560chai@^4.3.6:
1549 version "4.3.6"1561 version "4.3.6"