git.delta.rocks / unique-network / refs/commits / 555e682e0063

difftreelog

Merge pull request #222 from UniqueNetwork/feature/split-collection-pallets

kozyrevdev2021-11-08parents: #6cd8e0c #f24a360.patch.diff
in: master
Upgrade tests for split pallets

130 files changed

modifiedCargo.lockdiffbeforeafterboth
18source = "registry+https://github.com/rust-lang/crates.io-index"18source = "registry+https://github.com/rust-lang/crates.io-index"
19checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"19checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
20dependencies = [20dependencies = [
21 "gimli",21 "gimli 0.25.0",
22]22]
23
24[[package]]
25name = "addr2line"
26version = "0.17.0"
27source = "registry+https://github.com/rust-lang/crates.io-index"
28checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
29dependencies = [
30 "gimli 0.26.1",
31]
2332
24[[package]]33[[package]]
25name = "adler"34name = "adler"
385394
386[[package]]395[[package]]
387name = "backtrace"396name = "backtrace"
388version = "0.3.62"397version = "0.3.63"
389source = "registry+https://github.com/rust-lang/crates.io-index"398source = "registry+https://github.com/rust-lang/crates.io-index"
390checksum = "091bcdf2da9950f96aa522681ce805e6857f6ca8df73833d35736ab2dc78e152"399checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6"
391dependencies = [400dependencies = [
392 "addr2line",401 "addr2line 0.17.0",
393 "cc",402 "cc",
394 "cfg-if 1.0.0",403 "cfg-if 1.0.0",
395 "libc",404 "libc",
10651074
1066[[package]]1075[[package]]
1067name = "clang-sys"1076name = "clang-sys"
1068version = "1.2.2"1077version = "1.3.0"
1069source = "registry+https://github.com/rust-lang/crates.io-index"1078source = "registry+https://github.com/rust-lang/crates.io-index"
1070checksum = "10612c0ec0e0a1ff0e97980647cb058a6e7aedb913d01d009c406b8b7d0b26ee"1079checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90"
1071dependencies = [1080dependencies = [
1072 "glob",1081 "glob",
1073 "libc",1082 "libc",
1181 "cranelift-codegen-meta",1190 "cranelift-codegen-meta",
1182 "cranelift-codegen-shared",1191 "cranelift-codegen-shared",
1183 "cranelift-entity",1192 "cranelift-entity",
1184 "gimli",1193 "gimli 0.25.0",
1185 "log",1194 "log",
1186 "regalloc",1195 "regalloc",
1187 "smallvec",1196 "smallvec",
2997 "stable_deref_trait",3006 "stable_deref_trait",
2998]3007]
3008
3009[[package]]
3010name = "gimli"
3011version = "0.26.1"
3012source = "registry+https://github.com/rust-lang/crates.io-index"
3013checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
29993014
3000[[package]]3015[[package]]
3001name = "glob"3016name = "glob"
5055 "sp-transaction-pool",5070 "sp-transaction-pool",
5056 "substrate-frame-rpc-system",5071 "substrate-frame-rpc-system",
5057 "tokio 0.2.25",5072 "tokio 0.2.25",
5073 "uc-rpc",
5074 "up-rpc",
5058]5075]
50595076
5060[[package]]5077[[package]]
5082 "nft-data-structs",5099 "nft-data-structs",
5083 "pallet-aura",5100 "pallet-aura",
5084 "pallet-balances",5101 "pallet-balances",
5102 "pallet-common",
5085 "pallet-ethereum",5103 "pallet-ethereum",
5086 "pallet-evm",5104 "pallet-evm",
5087 "pallet-evm-coder-substrate",5105 "pallet-evm-coder-substrate",
5088 "pallet-evm-contract-helpers",5106 "pallet-evm-contract-helpers",
5089 "pallet-evm-migration",5107 "pallet-evm-migration",
5090 "pallet-evm-transaction-payment",5108 "pallet-evm-transaction-payment",
5109 "pallet-fungible",
5091 "pallet-inflation",5110 "pallet-inflation",
5092 "pallet-nft",5111 "pallet-nft",
5093 "pallet-nft-transaction-payment",5112 "pallet-nft-transaction-payment",
5113 "pallet-nonfungible",
5094 "pallet-randomness-collective-flip",5114 "pallet-randomness-collective-flip",
5115 "pallet-refungible",
5095 "pallet-sudo",5116 "pallet-sudo",
5096 "pallet-template-charge-transaction",5117 "pallet-template-charge-transaction",
5097 "pallet-timestamp",5118 "pallet-timestamp",
5121 "sp-transaction-pool",5142 "sp-transaction-pool",
5122 "sp-version",5143 "sp-version",
5123 "substrate-wasm-builder",5144 "substrate-wasm-builder",
5145 "up-rpc",
5124 "xcm",5146 "xcm",
5125 "xcm-builder",5147 "xcm-builder",
5126 "xcm-executor",5148 "xcm-executor",
5537 "sp-std",5559 "sp-std",
5538]5560]
5561
5562[[package]]
5563name = "pallet-common"
5564version = "0.1.0"
5565dependencies = [
5566 "evm-coder",
5567 "frame-support",
5568 "frame-system",
5569 "nft-data-structs",
5570 "pallet-evm",
5571 "pallet-evm-coder-substrate",
5572 "parity-scale-codec",
5573 "scale-info",
5574 "serde",
5575 "sp-core",
5576 "sp-runtime",
5577 "sp-std",
5578]
55395579
5540[[package]]5580[[package]]
5541name = "pallet-contract-helpers"5581name = "pallet-contract-helpers"
5787 "up-sponsorship",5827 "up-sponsorship",
5788]5828]
5829
5830[[package]]
5831name = "pallet-fungible"
5832version = "0.1.0"
5833dependencies = [
5834 "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)",
5835 "evm-coder",
5836 "frame-benchmarking",
5837 "frame-support",
5838 "frame-system",
5839 "nft-data-structs",
5840 "pallet-common",
5841 "pallet-evm-coder-substrate",
5842 "parity-scale-codec",
5843 "scale-info",
5844 "sp-core",
5845 "sp-runtime",
5846 "sp-std",
5847]
57895848
5790[[package]]5849[[package]]
5791name = "pallet-gilt"5850name = "pallet-gilt"
5993 "hex-literal",6052 "hex-literal",
5994 "nft-data-structs",6053 "nft-data-structs",
5995 "pallet-balances",6054 "pallet-balances",
6055 "pallet-common",
5996 "pallet-ethereum",6056 "pallet-ethereum",
5997 "pallet-evm",6057 "pallet-evm",
5998 "pallet-evm-coder-substrate",6058 "pallet-evm-coder-substrate",
6059 "pallet-fungible",
6060 "pallet-nonfungible",
5999 "pallet-randomness-collective-flip",6061 "pallet-randomness-collective-flip",
6062 "pallet-refungible",
6000 "pallet-timestamp",6063 "pallet-timestamp",
6001 "pallet-transaction-payment",6064 "pallet-transaction-payment",
6002 "parity-scale-codec",6065 "parity-scale-codec",
6044 "sp-std",6107 "sp-std",
6045]6108]
6109
6110[[package]]
6111name = "pallet-nonfungible"
6112version = "0.1.0"
6113dependencies = [
6114 "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)",
6115 "evm-coder",
6116 "frame-benchmarking",
6117 "frame-support",
6118 "frame-system",
6119 "nft-data-structs",
6120 "pallet-common",
6121 "pallet-evm-coder-substrate",
6122 "parity-scale-codec",
6123 "scale-info",
6124 "sp-core",
6125 "sp-runtime",
6126 "sp-std",
6127]
60466128
6047[[package]]6129[[package]]
6048name = "pallet-offences"6130name = "pallet-offences"
6127 "sp-std",6209 "sp-std",
6128]6210]
6211
6212[[package]]
6213name = "pallet-refungible"
6214version = "0.1.0"
6215dependencies = [
6216 "frame-benchmarking",
6217 "frame-support",
6218 "frame-system",
6219 "nft-data-structs",
6220 "pallet-common",
6221 "parity-scale-codec",
6222 "scale-info",
6223 "sp-core",
6224 "sp-runtime",
6225 "sp-std",
6226]
61296227
6130[[package]]6228[[package]]
6131name = "pallet-scheduler"6229name = "pallet-scheduler"
64706568
6471[[package]]6569[[package]]
6472name = "parity-db"6570name = "parity-db"
6473version = "0.3.2"6571version = "0.3.3"
6474source = "registry+https://github.com/rust-lang/crates.io-index"6572source = "registry+https://github.com/rust-lang/crates.io-index"
6475checksum = "91b679c6acc14fac74382942e2b73bea441686a33430b951ea03b5aeb6a7f254"6573checksum = "e7ccc4a8687027deb53d45c5434a1f1b330c9d1069a59cfe80a62aa9a1da25ae"
6476dependencies = [6574dependencies = [
6477 "blake2-rfc",6575 "blake2-rfc",
6478 "crc32fast",6576 "crc32fast",
11609source = "registry+https://github.com/rust-lang/crates.io-index"11707source = "registry+https://github.com/rust-lang/crates.io-index"
11610checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"11708checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
11709
11710[[package]]
11711name = "uc-rpc"
11712version = "0.1.0"
11713dependencies = [
11714 "jsonrpc-core",
11715 "jsonrpc-core-client",
11716 "jsonrpc-derive",
11717 "nft-data-structs",
11718 "pallet-common",
11719 "parity-scale-codec",
11720 "sp-api",
11721 "sp-blockchain",
11722 "sp-core",
11723 "sp-rpc",
11724 "sp-runtime",
11725 "up-rpc",
11726]
1161111727
11612[[package]]11728[[package]]
11613name = "ucd-trie"11729name = "ucd-trie"
11715source = "registry+https://github.com/rust-lang/crates.io-index"11831source = "registry+https://github.com/rust-lang/crates.io-index"
11716checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"11832checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
11833
11834[[package]]
11835name = "up-rpc"
11836version = "0.1.0"
11837dependencies = [
11838 "nft-data-structs",
11839 "pallet-common",
11840 "parity-scale-codec",
11841 "sp-api",
11842 "sp-core",
11843 "sp-runtime",
11844 "sp-std",
11845]
1171711846
11718[[package]]11847[[package]]
11719name = "up-sponsorship"11848name = "up-sponsorship"
12007 "cranelift-frontend",12136 "cranelift-frontend",
12008 "cranelift-native",12137 "cranelift-native",
12009 "cranelift-wasm",12138 "cranelift-wasm",
12010 "gimli",12139 "gimli 0.25.0",
12011 "more-asserts",12140 "more-asserts",
12012 "object 0.26.2",12141 "object 0.26.2",
12013 "target-lexicon",12142 "target-lexicon",
12025 "anyhow",12154 "anyhow",
12026 "cfg-if 1.0.0",12155 "cfg-if 1.0.0",
12027 "cranelift-entity",12156 "cranelift-entity",
12028 "gimli",12157 "gimli 0.25.0",
12029 "indexmap",12158 "indexmap",
12030 "log",12159 "log",
12031 "more-asserts",12160 "more-asserts",
12043source = "registry+https://github.com/rust-lang/crates.io-index"12172source = "registry+https://github.com/rust-lang/crates.io-index"
12044checksum = "24f46dd757225f29a419be415ea6fb8558df9b0194f07e3a6a9c99d0e14dd534"12173checksum = "24f46dd757225f29a419be415ea6fb8558df9b0194f07e3a6a9c99d0e14dd534"
12045dependencies = [12174dependencies = [
12046 "addr2line",12175 "addr2line 0.16.0",
12047 "anyhow",12176 "anyhow",
12048 "bincode",12177 "bincode",
12049 "cfg-if 1.0.0",12178 "cfg-if 1.0.0",
12050 "gimli",12179 "gimli 0.25.0",
12051 "libc",12180 "libc",
12052 "log",12181 "log",
12053 "more-asserts",12182 "more-asserts",
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
75 ) -> Result<String>;75 ) -> Result<String>;
7676
77 #[rpc(name = "nft_adminlist")]77 #[rpc(name = "nft_adminlist")]
78 fn adminlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;78 fn adminlist(
79 &self,
80 collection: CollectionId,
81 at: Option<BlockHash>,
82 ) -> Result<Vec<CrossAccountId>>;
79 #[rpc(name = "nft_allowlist")]83 #[rpc(name = "nft_allowlist")]
80 fn allowlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;84 fn allowlist(
85 &self,
86 collection: CollectionId,
87 at: Option<BlockHash>,
88 ) -> Result<Vec<CrossAccountId>>;
81 #[rpc(name = "nft_lastTokenId")]89 #[rpc(name = "nft_lastTokenId")]
82 fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;90 fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;
83}91}
150 pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> String => |v| v.to_string());158 pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> String => |v| v.to_string());
151 pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> String => |v| v.to_string());159 pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> String => |v| v.to_string());
152160
153 pass_method!(adminlist(collection: CollectionId) -> Vec<AccountId>);161 pass_method!(adminlist(collection: CollectionId) -> Vec<CrossAccountId>);
154 pass_method!(allowlist(collection: CollectionId) -> Vec<AccountId>);162 pass_method!(allowlist(collection: CollectionId) -> Vec<CrossAccountId>);
155 pass_method!(last_token_id(collection: CollectionId) -> TokenId);163 pass_method!(last_token_id(collection: CollectionId) -> TokenId);
156}164}
157165
modifiedlaunch-config.jsondiffbeforeafterboth
9 "rpcPort": 9843,9 "rpcPort": 9843,
10 "port": 30444,10 "port": 30444,
11 "flags": [11 "flags": [
12 "--rpc-port=9843"12 "--rpc-port=9843",
13 "-lparachain::candidate_validation=debug"
13 ]14 ]
14 },15 },
15 {16 {
18 "rpcPort": 9854,19 "rpcPort": 9854,
19 "port": 30555,20 "port": 30555,
20 "flags": [21 "flags": [
21 "--rpc-port=9854"22 "--rpc-port=9854",
23 "-lparachain::candidate_validation=debug"
22 ]24 ]
23 },25 },
24 {26 {
27 "rpcPort": 9865,29 "rpcPort": 9865,
28 "port": 30666,30 "port": 30666,
29 "flags": [31 "flags": [
30 "--rpc-port=9865"32 "--rpc-port=9865",
33 "-lparachain::candidate_validation=debug"
31 ]34 ]
32 },35 },
33 {36 {
36 "rpcPort": 9876,39 "rpcPort": 9876,
37 "port": 30777,40 "port": 30777,
38 "flags": [41 "flags": [
39 "--rpc-port=9876"42 "--rpc-port=9876",
43 "-lparachain::candidate_validation=debug"
40 ]44 ]
41 }45 }
42 ],46 ],
modifiedpallets/common/src/account.rsdiffbeforeafterboth
20 fn from_sub(account: AccountId) -> Self;20 fn from_sub(account: AccountId) -> Self;
21 fn from_eth(account: H160) -> Self;21 fn from_eth(account: H160) -> Self;
22
23 fn conv_eq(&self, other: &Self) -> bool;
22}24}
2325
24#[derive(Encode, Decode, Serialize, Deserialize, TypeInfo)]26#[derive(Encode, Decode, Serialize, Deserialize, TypeInfo)]
28 Ethereum(H160),30 Ethereum(H160),
29}31}
3032
31#[derive(Eq)]33#[derive(PartialEq, Eq)]
32pub struct BasicCrossAccountId<T: Config> {34pub struct BasicCrossAccountId<T: Config> {
33 /// If true - then ethereum is canonical encoding35 /// If true - then ethereum is canonical encoding
34 from_ethereum: bool,36 from_ethereum: bool,
77 }79 }
78}80}
7981
80impl<T: Config> PartialEq for BasicCrossAccountId<T> {
81 fn eq(&self, other: &Self) -> bool {
82 if self.from_ethereum == other.from_ethereum {
83 self.substrate == other.substrate && self.ethereum == other.ethereum
84 } else if self.from_ethereum {
85 // ethereum is canonical encoding, but we need to compare derived address
86 self.substrate == other.substrate
87 } else {
88 self.ethereum == other.ethereum
89 }
90 }
91}
92impl<T: Config> Clone for BasicCrossAccountId<T> {82impl<T: Config> Clone for BasicCrossAccountId<T> {
93 fn clone(&self) -> Self {83 fn clone(&self) -> Self {
94 Self {84 Self {
158 from_ethereum: true,148 from_ethereum: true,
159 }149 }
160 }150 }
151 fn conv_eq(&self, other: &Self) -> bool {
152 if self.from_ethereum == other.from_ethereum {
153 self.substrate == other.substrate && self.ethereum == other.ethereum
154 } else if self.from_ethereum {
155 // ethereum is canonical encoding, but we need to compare derived address
156 self.substrate == other.substrate
157 } else {
158 self.ethereum == other.ethereum
159 }
160 }
161}161}
162impl<T: Config> From<BasicCrossAccountIdRepr<T::AccountId>> for BasicCrossAccountId<T> {162impl<T: Config> From<BasicCrossAccountIdRepr<T::AccountId>> for BasicCrossAccountId<T> {
163 fn from(repr: BasicCrossAccountIdRepr<T::AccountId>) -> Self {163 fn from(repr: BasicCrossAccountIdRepr<T::AccountId>) -> Self {
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
11use nft_data_structs::{11use nft_data_structs::{
12 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,12 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,
13 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,13 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
14 MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,14 COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight,
15 WithdrawReasons,
15};16};
16pub use pallet::*;17pub use pallet::*;
98 pub fn is_owner_or_admin(&self, subject: &T::CrossAccountId) -> Result<bool, DispatchError> {99 pub fn is_owner_or_admin(&self, subject: &T::CrossAccountId) -> Result<bool, DispatchError> {
99 self.consume_sload()?;100 self.consume_sload()?;
100101
101 Ok(*subject.as_sub() == self.owner || <IsAdmin<T>>::get((self.id, subject.as_sub())))102 Ok(*subject.as_sub() == self.owner || <IsAdmin<T>>::get((self.id, subject)))
102 }103 }
103 pub fn check_is_owner_or_admin(&self, subject: &T::CrossAccountId) -> DispatchResult {104 pub fn check_is_owner_or_admin(&self, subject: &T::CrossAccountId) -> DispatchResult {
104 ensure!(self.is_owner_or_admin(subject)?, <Error<T>>::NoPermission);105 ensure!(self.is_owner_or_admin(subject)?, <Error<T>>::NoPermission);
105 Ok(())106 Ok(())
106 }107 }
107 pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {108 pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {
108 Ok(self.limits.owner_can_transfer && self.is_owner_or_admin(user)?)109 Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)
109 }110 }
110 pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {111 pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {
111 Ok(self.limits.owner_can_transfer && self.is_owner_or_admin(user)?)112 Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)
112 }113 }
113 pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {114 pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {
114 self.consume_sload()?;115 self.consume_sload()?;
115116
116 ensure!(117 ensure!(
117 <Allowlist<T>>::get((self.id, user.as_sub())),118 <Allowlist<T>>::get((self.id, user)),
118 <Error<T>>::AddressNotInAllowlist119 <Error<T>>::AddressNotInAllowlist
119 );120 );
120 Ok(())121 Ok(())
139#[frame_support::pallet]140#[frame_support::pallet]
140pub mod pallet {141pub mod pallet {
141 use super::*;142 use super::*;
142 use frame_support::{pallet_prelude::*};
143 use frame_support::{Blake2_128Concat, storage::Key};143 use frame_support::{Blake2_128Concat, pallet_prelude::*, storage::Key};
144 use account::{EvmBackwardsAddressMapping, CrossAccountId};144 use account::{EvmBackwardsAddressMapping, CrossAccountId};
145 use frame_support::traits::Currency;145 use frame_support::traits::Currency;
146 use nft_data_structs::TokenId;146 use nft_data_structs::TokenId;
166 #[pallet::generate_store(pub(super) trait Store)]166 #[pallet::generate_store(pub(super) trait Store)]
167 pub struct Pallet<T>(_);167 pub struct Pallet<T>(_);
168
169 #[pallet::extra_constants]
170 impl<T: Config> Pallet<T> {
171 pub fn collection_admins_limit() -> u32 {
172 COLLECTION_ADMINS_LIMIT
173 }
174 }
168175
169 #[pallet::event]176 #[pallet::event]
170 #[pallet::generate_deposit(pub fn deposit_event)]177 #[pallet::generate_deposit(pub fn deposit_event)]
266 TotalCollectionsLimitExceeded,273 TotalCollectionsLimitExceeded,
267 /// variable_data exceeded data limit.274 /// variable_data exceeded data limit.
268 TokenVariableDataLimitExceeded,275 TokenVariableDataLimitExceeded,
276 /// Exceeded max admin amount
277 CollectionAdminAmountExceeded,
269278
270 /// Collection settings not allowing items transferring279 /// Collection settings not allowing items transferring
271 TransferNotAllowed,280 TransferNotAllowed,
306 QueryKind = OptionQuery,315 QueryKind = OptionQuery,
307 >;316 >;
317
318 #[pallet::storage]
319 pub type AdminAmount<T> = StorageMap<
320 Hasher = Blake2_128Concat,
321 Key = CollectionId,
322 Value = u32,
323 QueryKind = ValueQuery,
324 >;
308325
309 /// List of collection admins326 /// List of collection admins
310 #[pallet::storage]327 #[pallet::storage]
311 pub type IsAdmin<T: Config> = StorageNMap<328 pub type IsAdmin<T: Config> = StorageNMap<
312 Key = (329 Key = (
313 Key<Blake2_128Concat, CollectionId>,330 Key<Blake2_128Concat, CollectionId>,
314 Key<Blake2_128Concat, T::AccountId>,331 Key<Blake2_128Concat, T::CrossAccountId>,
315 ),332 ),
316 Value = bool,333 Value = bool,
317 QueryKind = ValueQuery,334 QueryKind = ValueQuery,
322 pub type Allowlist<T: Config> = StorageNMap<339 pub type Allowlist<T: Config> = StorageNMap<
323 Key = (340 Key = (
324 Key<Blake2_128Concat, CollectionId>,341 Key<Blake2_128Concat, CollectionId>,
325 Key<Blake2_128Concat, T::AccountId>,342 Key<Blake2_128Concat, T::CrossAccountId>,
326 ),343 ),
327 Value = bool,344 Value = bool,
328 QueryKind = ValueQuery,345 QueryKind = ValueQuery,
405 collection: CollectionHandle<T>,422 collection: CollectionHandle<T>,
406 sender: &T::CrossAccountId,423 sender: &T::CrossAccountId,
407 ) -> DispatchResult {424 ) -> DispatchResult {
408 if !collection.limits.owner_can_destroy {
409 fail!(Error::<T>::NoPermission);425 ensure!(
410 }426 collection.limits.owner_can_destroy(),
427 <Error<T>>::NoPermission,
428 );
411 collection.check_is_owner(&sender)?;429 collection.check_is_owner(&sender)?;
412430
419437
420 <DestroyedCollectionCount<T>>::put(destroyed_collections);438 <DestroyedCollectionCount<T>>::put(destroyed_collections);
421 <CollectionById<T>>::remove(collection.id);439 <CollectionById<T>>::remove(collection.id);
440 <AdminAmount<T>>::remove(collection.id);
422 <IsAdmin<T>>::remove_prefix((collection.id,), None);441 <IsAdmin<T>>::remove_prefix((collection.id,), None);
423 <Allowlist<T>>::remove_prefix((collection.id,), None);442 <Allowlist<T>>::remove_prefix((collection.id,), None);
424 Ok(())443 Ok(())
435 // =========454 // =========
436455
437 if allowed {456 if allowed {
438 <Allowlist<T>>::insert((collection.id, user.as_sub()), true);457 <Allowlist<T>>::insert((collection.id, user), true);
439 } else {458 } else {
440 <Allowlist<T>>::remove((collection.id, user.as_sub()));459 <Allowlist<T>>::remove((collection.id, user));
441 }460 }
442461
443 Ok(())462 Ok(())
444 }463 }
464
465 pub fn toggle_admin(
466 collection: &CollectionHandle<T>,
467 sender: &T::CrossAccountId,
468 user: &T::CrossAccountId,
469 admin: bool,
470 ) -> DispatchResult {
471 collection.check_is_owner_or_admin(&sender)?;
472
473 let was_admin = <IsAdmin<T>>::get((collection.id, user));
474 if was_admin == admin {
475 return Ok(());
476 }
477 let amount = <AdminAmount<T>>::get(collection.id);
478
479 if admin {
480 let amount = amount
481 .checked_add(1)
482 .ok_or(<Error<T>>::CollectionAdminAmountExceeded)?;
483 ensure!(
484 amount <= Self::collection_admins_limit(),
485 <Error<T>>::CollectionAdminAmountExceeded,
486 );
487
488 // =========
489
490 <AdminAmount<T>>::insert(collection.id, amount);
491 <IsAdmin<T>>::insert((collection.id, user), true);
492 } else {
493 <AdminAmount<T>>::insert(collection.id, amount.saturating_sub(1));
494 <IsAdmin<T>>::remove((collection.id, user));
495 }
496
497 Ok(())
498 }
445}499}
446500
447#[macro_export]501#[macro_export]
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
3use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};3use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
4use nft_data_structs::TokenId;4use nft_data_structs::TokenId;
5use pallet_common::{5use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
6 CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,
7};
8use sp_runtime::ArithmeticError;6use sp_runtime::ArithmeticError;
9use sp_std::{vec::Vec, vec};7use sp_std::{vec::Vec, vec};
188 }186 }
189187
190 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {188 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
191 if <Balance<T>>::get((self.id, account.as_sub())) != 0 {189 if <Balance<T>>::get((self.id, account)) != 0 {
192 vec![TokenId::default()]190 vec![TokenId::default()]
193 } else {191 } else {
194 vec![]192 vec![]
218 }216 }
219217
220 fn account_balance(&self, account: T::CrossAccountId) -> u32 {218 fn account_balance(&self, account: T::CrossAccountId) -> u32 {
221 if <Balance<T>>::get((self.id, account.as_sub())) != 0 {219 if <Balance<T>>::get((self.id, account)) != 0 {
222 1220 1
223 } else {221 } else {
224 0222 0
229 if token != TokenId::default() {227 if token != TokenId::default() {
230 return 0;228 return 0;
231 }229 }
232 <Balance<T>>::get((self.id, account.as_sub()))230 <Balance<T>>::get((self.id, account))
233 }231 }
234232
235 fn allowance(233 fn allowance(
241 if token != TokenId::default() {239 if token != TokenId::default() {
242 return 0;240 return 0;
243 }241 }
244 <Allowance<T>>::get((self.id, sender.as_sub(), spender.as_sub()))242 <Allowance<T>>::get((self.id, sender, spender))
245 }243 }
246}244}
247245
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
52 }52 }
53 fn balance_of(&self, owner: address) -> Result<uint256> {53 fn balance_of(&self, owner: address) -> Result<uint256> {
54 let owner = T::CrossAccountId::from_eth(owner);54 let owner = T::CrossAccountId::from_eth(owner);
55 let balance = <Balance<T>>::get((self.id, owner.as_sub()));55 let balance = <Balance<T>>::get((self.id, owner));
56 Ok(balance.into())56 Ok(balance.into())
57 }57 }
58 fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {58 fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
92 let owner = T::CrossAccountId::from_eth(owner);92 let owner = T::CrossAccountId::from_eth(owner);
93 let spender = T::CrossAccountId::from_eth(spender);93 let spender = T::CrossAccountId::from_eth(spender);
9494
95 Ok(<Allowance<T>>::get((self.id, owner.as_sub(), spender.as_sub())).into())95 Ok(<Allowance<T>>::get((self.id, owner, spender)).into())
96 }96 }
97}97}
9898
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
55 pub(super) type Balance<T: Config> = StorageNMap<55 pub(super) type Balance<T: Config> = StorageNMap<
56 Key = (56 Key = (
57 Key<Twox64Concat, CollectionId>,57 Key<Twox64Concat, CollectionId>,
58 Key<Blake2_128Concat, T::AccountId>,58 Key<Blake2_128Concat, T::CrossAccountId>,
59 ),59 ),
60 Value = u128,60 Value = u128,
61 QueryKind = ValueQuery,61 QueryKind = ValueQuery,
65 pub(super) type Allowance<T: Config> = StorageNMap<65 pub(super) type Allowance<T: Config> = StorageNMap<
66 Key = (66 Key = (
67 Key<Twox64Concat, CollectionId>,67 Key<Twox64Concat, CollectionId>,
68 Key<Blake2_128, T::AccountId>,68 Key<Blake2_128, T::CrossAccountId>,
69 Key<Blake2_128Concat, T::AccountId>,69 Key<Blake2_128Concat, T::CrossAccountId>,
70 ),70 ),
71 Value = u128,71 Value = u128,
72 QueryKind = ValueQuery,72 QueryKind = ValueQuery,
119 .checked_sub(amount)119 .checked_sub(amount)
120 .ok_or(<CommonError<T>>::TokenValueTooLow)?;120 .ok_or(<CommonError<T>>::TokenValueTooLow)?;
121121
122 let balance = <Balance<T>>::get((collection.id, owner.as_sub()))122 let balance = <Balance<T>>::get((collection.id, owner))
123 .checked_sub(amount)123 .checked_sub(amount)
124 .ok_or(<CommonError<T>>::TokenValueTooLow)?;124 .ok_or(<CommonError<T>>::TokenValueTooLow)?;
125125
130 // =========130 // =========
131131
132 if balance == 0 {132 if balance == 0 {
133 <Balance<T>>::remove((collection.id, owner.as_sub()));133 <Balance<T>>::remove((collection.id, owner));
134 } else {134 } else {
135 <Balance<T>>::insert((collection.id, owner.as_sub()), balance);135 <Balance<T>>::insert((collection.id, owner), balance);
136 }136 }
137 <TotalSupply<T>>::insert(collection.id, total_supply);137 <TotalSupply<T>>::insert(collection.id, total_supply);
138138
157 amount: u128,157 amount: u128,
158 ) -> DispatchResult {158 ) -> DispatchResult {
159 ensure!(159 ensure!(
160 collection.transfers_enabled,160 collection.limits.transfers_enabled(),
161 <CommonError<T>>::TransferNotAllowed161 <CommonError<T>>::TransferNotAllowed,
162 );162 );
163163
164 if collection.access == AccessMode::WhiteList {164 if collection.access == AccessMode::WhiteList {
167 }167 }
168 <PalletCommon<T>>::ensure_correct_receiver(to)?;168 <PalletCommon<T>>::ensure_correct_receiver(to)?;
169169
170 let balance_from = <Balance<T>>::get((collection.id, from.as_sub()))170 let balance_from = <Balance<T>>::get((collection.id, from))
171 .checked_sub(amount)171 .checked_sub(amount)
172 .ok_or(<CommonError<T>>::TokenValueTooLow)?;172 .ok_or(<CommonError<T>>::TokenValueTooLow)?;
173 let balance_to = if from != to {173 let balance_to = if from != to {
174 Some(174 Some(
175 <Balance<T>>::get((collection.id, to.as_sub()))175 <Balance<T>>::get((collection.id, to))
176 .checked_add(amount)176 .checked_add(amount)
177 .ok_or(ArithmeticError::Overflow)?,177 .ok_or(ArithmeticError::Overflow)?,
178 )178 )
190 if let Some(balance_to) = balance_to {190 if let Some(balance_to) = balance_to {
191 // from != to191 // from != to
192 if balance_from == 0 {192 if balance_from == 0 {
193 <Balance<T>>::remove((collection.id, from.as_sub()));193 <Balance<T>>::remove((collection.id, from));
194 } else {194 } else {
195 <Balance<T>>::insert((collection.id, from.as_sub()), balance_from);195 <Balance<T>>::insert((collection.id, from), balance_from);
196 }196 }
197 <Balance<T>>::insert((collection.id, to.as_sub()), balance_to);197 <Balance<T>>::insert((collection.id, to), balance_to);
198 }198 }
199199
200 collection.log_infallible(ERC20Events::Transfer {200 collection.log_infallible(ERC20Events::Transfer {
235 let total_supply = data235 let total_supply = data
236 .iter()236 .iter()
237 .map(|u| u.1)237 .map(|u| u.1)
238 .try_fold(0u128, |acc, v| acc.checked_add(v))238 .try_fold(<TotalSupply<T>>::get(collection.id), |acc, v| {
239 acc.checked_add(v)
240 })
239 .ok_or(ArithmeticError::Overflow)?;241 .ok_or(ArithmeticError::Overflow)?;
240242
241 for (user, amount) in data.into_iter() {243 for (user, amount) in data.into_iter() {
242 collection.consume_sload()?;244 collection.consume_sload()?;
243 let balance = balances245 let balance = balances
244 .entry(user.clone())246 .entry(user.clone())
245 .or_insert_with(|| <Balance<T>>::get((collection.id, user.as_sub())));247 .or_insert_with(|| <Balance<T>>::get((collection.id, user)));
246 *balance = (*balance)248 *balance = (*balance)
247 .checked_add(amount)249 .checked_add(amount)
248 .ok_or(ArithmeticError::Overflow)?;250 .ok_or(ArithmeticError::Overflow)?;
259261
260 <TotalSupply<T>>::insert(collection.id, total_supply);262 <TotalSupply<T>>::insert(collection.id, total_supply);
261 for (user, amount) in balances {263 for (user, amount) in balances {
262 <Balance<T>>::insert((collection.id, user.as_sub()), amount);264 <Balance<T>>::insert((collection.id, &user), amount);
263265
264 collection.log_infallible(ERC20Events::Transfer {266 collection.log_infallible(ERC20Events::Transfer {
265 from: H160::default(),267 from: H160::default(),
283 spender: &T::CrossAccountId,285 spender: &T::CrossAccountId,
284 amount: u128,286 amount: u128,
285 ) {287 ) {
286 <Allowance<T>>::insert((collection.id, owner.as_sub(), spender.as_sub()), amount);288 <Allowance<T>>::insert((collection.id, owner, spender), amount);
287289
288 collection.log_infallible(ERC20Events::Approval {290 collection.log_infallible(ERC20Events::Approval {
289 owner: *owner.as_eth(),291 owner: *owner.as_eth(),
310 collection.check_allowlist(&spender)?;312 collection.check_allowlist(&spender)?;
311 }313 }
312314
313 if <Balance<T>>::get((collection.id, owner.as_sub())) < amount {315 if <Balance<T>>::get((collection.id, owner)) < amount {
314 ensure!(316 ensure!(
315 collection.ignores_owned_amount(owner)?,317 collection.ignores_owned_amount(owner)?,
316 <CommonError<T>>::CantApproveMoreThanOwned318 <CommonError<T>>::CantApproveMoreThanOwned
330 to: &T::CrossAccountId,332 to: &T::CrossAccountId,
331 amount: u128,333 amount: u128,
332 ) -> DispatchResult {334 ) -> DispatchResult {
333 if spender == from {335 if spender.conv_eq(from) {
334 return Self::transfer(collection, from, to, amount);336 return Self::transfer(collection, from, to, amount);
335 }337 }
336 if collection.access == AccessMode::WhiteList {338 if collection.access == AccessMode::WhiteList {
337 // `from`, `to` checked in [`transfer`]339 // `from`, `to` checked in [`transfer`]
338 collection.check_allowlist(spender)?;340 collection.check_allowlist(spender)?;
339 }341 }
340342
341 let allowance = <Allowance<T>>::get((collection.id, from.as_sub(), spender.as_sub()))343 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);
342 .checked_sub(amount);
343 if allowance.is_none() {344 if allowance.is_none() {
344 ensure!(345 ensure!(
362 from: &T::CrossAccountId,363 from: &T::CrossAccountId,
363 amount: u128,364 amount: u128,
364 ) -> DispatchResult {365 ) -> DispatchResult {
365 if spender == from {366 if spender.conv_eq(from) {
366 return Self::burn(collection, from, amount);367 return Self::burn(collection, from, amount);
367 }368 }
368 if collection.access == AccessMode::WhiteList {369 if collection.access == AccessMode::WhiteList {
369 // `from` checked in [`burn`]370 // `from` checked in [`burn`]
370 collection.check_allowlist(spender)?;371 collection.check_allowlist(spender)?;
371 }372 }
372373
373 let allowance = <Allowance<T>>::get((collection.id, from.as_sub(), spender.as_sub()))374 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);
374 .checked_sub(amount);
375 if allowance.is_none() {375 if allowance.is_none() {
376 ensure!(376 ensure!(
modifiedpallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth
43 let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;43 let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;
44 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;44 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
45 let collection_limits = &collection.limits;45 let collection_limits = &collection.limits;
46 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {46 let limit =
47 collection_limits.sponsor_transfer_timeout
48 } else {
49 NFT_SPONSOR_TRANSFER_TIMEOUT47 collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
50 };
5148
52 let mut sponsor = true;49 let mut sponsor = true;
53 if <NftTransferBasket<T>>::contains_key(collection_id, token_id) {50 if <NftTransferBasket<T>>::contains_key(collection_id, token_id) {
74 UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {71 UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
75 let who = T::CrossAccountId::from_eth(*caller);72 let who = T::CrossAccountId::from_eth(*caller);
76 let collection_limits = &collection.limits;73 let collection_limits = &collection.limits;
77 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {74 let limit = collection_limits
78 collection_limits.sponsor_transfer_timeout
79 } else {
80 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT75 .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
81 };
8276
83 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;77 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
84 let mut sponsored = true;78 let mut sponsored = true;
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
36use sp_runtime::{sp_std::prelude::Vec};36use sp_runtime::{sp_std::prelude::Vec};
37use nft_data_structs::{37use nft_data_structs::{
38 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,38 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,
39 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,39 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,
40 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
40 OFFCHAIN_SCHEMA_LIMIT, AccessMode, Collection, CreateItemData, CollectionLimits, CollectionId,41 NFT_SPONSOR_TRANSFER_TIMEOUT, AccessMode, Collection, CreateItemData, CollectionLimits,
41 CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,42 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,
42};43};
43use pallet_common::{44use pallet_common::{
155 where156 where
156 origin: T::Origin157 origin: T::Origin
157 {158 {
158 const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;
159 type Error = Error<T>;159 type Error = Error<T>;
160160
161 fn on_initialize(_now: T::BlockNumber) -> Weight {161 fn on_initialize(_now: T::BlockNumber) -> Weight {
189 // Anyone can create a collection189 // Anyone can create a collection
190 let who = ensure_signed(origin)?;190 let who = ensure_signed(origin)?;
191
192 let limits = CollectionLimits::<T::BlockNumber> {
193 sponsored_data_size: CUSTOM_DATA_LIMIT,
194 ..Default::default()
195 };
196191
197 // Create new collection192 // Create new collection
198 let new_collection = Collection::<T> {193 let new_collection = Collection::<T> {
208 sponsorship: SponsorshipState::Disabled,203 sponsorship: SponsorshipState::Disabled,
209 variable_on_chain_schema: Vec::new(),204 variable_on_chain_schema: Vec::new(),
210 const_on_chain_schema: Vec::new(),205 const_on_chain_schema: Vec::new(),
211 limits,206 limits: Default::default(),
212 transfers_enabled: true,
213 meta_update_permission: Default::default(),207 meta_update_permission: Default::default(),
214 };208 };
215209
413 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);407 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
414
415 let collection = <CollectionHandle<T>>::try_get(collection_id)?;408 let collection = <CollectionHandle<T>>::try_get(collection_id)?;
416 collection.check_is_owner_or_admin(&sender)?;
417409
418 <IsAdmin<T>>::insert((collection_id, new_admin_id.as_sub()), true);410 <PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin_id, true)
419 Ok(())
420 }411 }
421412
422 /// Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.413 /// Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.
437 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);428 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
438
439 let collection = <CollectionHandle<T>>::try_get(collection_id)?;429 let collection = <CollectionHandle<T>>::try_get(collection_id)?;
440 collection.check_is_owner_or_admin(&sender)?;
441430
442 <IsAdmin<T>>::remove((collection_id, account_id.as_sub()));431 <PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)
443 Ok(())
444 }432 }
445433
446 /// # Permissions434 /// # Permissions
458 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);446 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
459447
460 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;448 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
461 target_collection.check_is_owner_or_admin(&sender)?;449 target_collection.check_is_owner(&sender)?;
462450
463 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);451 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);
464 target_collection.save()452 target_collection.save()
582570
583 // =========571 // =========
584572
585 target_collection.transfers_enabled = value;573 target_collection.limits.transfers_enabled = Some(value);
586 target_collection.save()574 target_collection.save()
587 }575 }
588576
888 pub fn set_collection_limits(876 pub fn set_collection_limits(
889 origin,877 origin,
890 collection_id: CollectionId,878 collection_id: CollectionId,
891 new_limits: CollectionLimits<T::BlockNumber>,879 new_limit: CollectionLimits,
892 ) -> DispatchResult {880 ) -> DispatchResult {
881 let mut new_limit = new_limit;
893 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);882 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
894 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;883 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
895 target_collection.check_is_owner(&sender)?;884 target_collection.check_is_owner(&sender)?;
896 let old_limits = &target_collection.limits;885 let old_limit = &target_collection.limits;
897886
898 // collection bounds
899 ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&887 macro_rules! limit_default {
888 ($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{
889 $(
890 if let Some($new) = $new.$field {
900 new_limits.account_token_ownership_limit.unwrap_or(0) <= MAX_TOKEN_OWNERSHIP &&891 let $old = $old.$field($($arg)?);
892 let _ = $new;
893 let _ = $old;
894 $check
895 } else {
896 $new.$field = $old.$field
897 }
898 )*
899 }};
900 }
901
902 limit_default!(old_limit, new_limit,
903 account_token_ownership_limit => ensure!(
904 new_limit <= MAX_TOKEN_OWNERSHIP,
905 <Error<T>>::CollectionLimitBoundsExceeded,
906 ),
901 new_limits.sponsored_data_size <= CUSTOM_DATA_LIMIT,907 sponsor_transfer_timeout(match target_collection.mode {
908 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
909 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
910 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
911 }) => ensure!(
912 new_limit <= MAX_SPONSOR_TIMEOUT,
902 Error::<T>::CollectionLimitBoundsExceeded);913 <Error<T>>::CollectionLimitBoundsExceeded,
903914 ),
904 // token_limit check prev
905 ensure!(old_limits.token_limit >= new_limits.token_limit, <CommonError<T>>::CollectionTokenLimitExceeded);915 sponsored_data_size => ensure!(
916 new_limit <= CUSTOM_DATA_LIMIT,
917 <Error<T>>::CollectionLimitBoundsExceeded,
918 ),
906 ensure!(new_limits.token_limit > 0, <CommonError<T>>::CollectionTokenLimitExceeded);919 token_limit => ensure!(
907920 old_limit >= new_limit && new_limit > 0,
921 <CommonError<T>>::CollectionTokenLimitExceeded
922 ),
908 ensure!(923 owner_can_transfer => ensure!(
909 (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&924 old_limit || !new_limit,
925 <Error<T>>::OwnerPermissionsCantBeReverted,
926 ),
910 (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),927 owner_can_destroy => ensure!(
928 old_limit || !new_limit,
911 Error::<T>::OwnerPermissionsCantBeReverted,929 <Error<T>>::OwnerPermissionsCantBeReverted,
930 ),
931 sponsored_data_rate_limit => {},
932 transfers_enabled => {},
912 );933 );
913934
914 target_collection.limits = new_limits;935 target_collection.limits = new_limit;
915936
916 target_collection.save()937 target_collection.save()
917 }938 }
920941
921// TODO: limit returned entries?942// TODO: limit returned entries?
922impl<T: Config> Pallet<T> {943impl<T: Config> Pallet<T> {
923 pub fn adminlist(collection: CollectionId) -> Vec<T::AccountId> {944 pub fn adminlist(collection: CollectionId) -> Vec<T::CrossAccountId> {
924 <IsAdmin<T>>::iter_prefix((collection,))945 <IsAdmin<T>>::iter_prefix((collection,))
925 .map(|(a, _)| a)946 .map(|(a, _)| a)
926 .collect()947 .collect()
927 }948 }
928 pub fn allowlist(collection: CollectionId) -> Vec<T::AccountId> {949 pub fn allowlist(collection: CollectionId) -> Vec<T::CrossAccountId> {
929 <Allowlist<T>>::iter_prefix((collection,))950 <Allowlist<T>>::iter_prefix((collection,))
930 .map(|(a, _)| a)951 .map(|(a, _)| a)
931 .collect()952 .collect()
modifiedpallets/nft/src/sponsorship.rsdiffbeforeafterboth
2828
29 let limit = collection.limits.sponsor_transfer_timeout;29 let limit = collection
30 .limits
31 .sponsor_transfer_timeout(match _properties {
32 CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
33 CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
34 CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
35 });
30 if CreateItemBasket::<T>::contains_key((collection_id, &who)) {36 if CreateItemBasket::<T>::contains_key((collection_id, &who)) {
31 let last_tx_block = CreateItemBasket::<T>::get((collection_id, &who));37 let last_tx_block = CreateItemBasket::<T>::get((collection_id, &who));
32 let limit_time = last_tx_block + limit.into();38 let limit_time = last_tx_block + limit.into();
37 CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);43 CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);
3844
39 // check free create limit45 // check free create limit
40 if collection.limits.sponsored_data_size >= (_properties.data_size() as u32) {46 if collection.limits.sponsored_data_size() >= (_properties.data_size() as u32) {
41 collection.sponsorship.sponsor().cloned()47 collection.sponsorship.sponsor().cloned()
42 } else {48 } else {
43 None49 None
61 sponsor_transfer = match collection_mode {67 sponsor_transfer = match collection_mode {
62 CollectionMode::NFT => {68 CollectionMode::NFT => {
63 // get correct limit69 // get correct limit
64 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {70 let limit =
65 collection_limits.sponsor_transfer_timeout
66 } else {
67 NFT_SPONSOR_TRANSFER_TIMEOUT71 collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
68 };
6972
70 let mut sponsored = true;73 let mut sponsored = true;
71 if NftTransferBasket::<T>::contains_key(collection_id, item_id) {74 if NftTransferBasket::<T>::contains_key(collection_id, item_id) {
83 }86 }
84 CollectionMode::Fungible(_) => {87 CollectionMode::Fungible(_) => {
85 // get correct limit88 // get correct limit
86 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {89 let limit = collection_limits
87 collection_limits.sponsor_transfer_timeout
88 } else {
89 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT90 .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
90 };
9191
92 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;92 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
93 let mut sponsored = true;93 let mut sponsored = true;
106 }106 }
107 CollectionMode::ReFungible => {107 CollectionMode::ReFungible => {
108 // get correct limit108 // get correct limit
109 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {109 let limit = collection_limits
110 collection_limits.sponsor_transfer_timeout
111 } else {
112 REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT110 .sponsor_transfer_timeout(REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
113 };
114111
115 let mut sponsored = true;112 let mut sponsored = true;
116 if ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {113 if ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {
150 // Can't sponsor fungible collection, this tx will be rejected147 // Can't sponsor fungible collection, this tx will be rejected
151 // as invalid148 // as invalid
152 !matches!(collection.mode, CollectionMode::Fungible(_)) &&149 !matches!(collection.mode, CollectionMode::Fungible(_)) &&
153 data.len() <= collection.limits.sponsored_data_size as usize150 data.len() <= collection.limits.sponsored_data_size() as usize
154 {151 {
155 if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit {152 if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit() {
156 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;153 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
157154
158 if VariableMetaDataBasket::<T>::get(collection_id, item_id)155 if VariableMetaDataBasket::<T>::get(collection_id, item_id)
159 .map(|last_block| block_number - last_block > rate_limit)156 .map(|last_block| block_number - last_block > rate_limit.into())
160 .unwrap_or(true)157 .unwrap_or(true)
161 {158 {
162 sponsor_metadata_changes = true;159 sponsor_metadata_changes = true;
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
3use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};3use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
4use nft_data_structs::TokenId;4use nft_data_structs::TokenId;
5use pallet_common::{5use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
6 CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,
7};
8use sp_runtime::DispatchError;6use sp_runtime::DispatchError;
9use sp_std::vec::Vec;7use sp_std::vec::Vec;
200 }198 }
201199
202 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {200 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
203 <Owned<T>>::iter_prefix((self.id, account.as_sub()))201 <Owned<T>>::iter_prefix((self.id, account))
204 .map(|(id, _)| id)202 .map(|(id, _)| id)
205 .collect()203 .collect()
206 }204 }
234 }232 }
235233
236 fn account_balance(&self, account: T::CrossAccountId) -> u32 {234 fn account_balance(&self, account: T::CrossAccountId) -> u32 {
237 <AccountBalance<T>>::get((self.id, account.as_sub()))235 <AccountBalance<T>>::get((self.id, account))
238 }236 }
239237
240 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {238 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {
255 token: TokenId,253 token: TokenId,
256 ) -> u128 {254 ) -> u128 {
257 if <TokenData<T>>::get((self.id, token))255 if <TokenData<T>>::get((self.id, token))
258 .map(|a| a.owner == sender)256 .map(|a| a.owner != sender)
259 .unwrap_or(false)257 .unwrap_or(true)
260 {258 {
261 0259 0
262 } else if <Allowance<T>>::get((self.id, token)) == Some(spender) {260 } else if <Allowance<T>>::get((self.id, token)) == Some(spender) {
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
93impl<T: Config> NonfungibleHandle<T> {93impl<T: Config> NonfungibleHandle<T> {
94 fn balance_of(&self, owner: address) -> Result<uint256> {94 fn balance_of(&self, owner: address) -> Result<uint256> {
95 let owner = T::CrossAccountId::from_eth(owner);95 let owner = T::CrossAccountId::from_eth(owner);
96 let balance = <AccountBalance<T>>::get((self.id, owner.as_sub()));96 let balance = <AccountBalance<T>>::get((self.id, owner));
97 Ok(balance.into())97 Ok(balance.into())
98 }98 }
99 fn owner_of(&self, token_id: uint256) -> Result<address> {99 fn owner_of(&self, token_id: uint256) -> Result<address> {
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
80 pub(super) type Owned<T: Config> = StorageNMap<80 pub(super) type Owned<T: Config> = StorageNMap<
81 Key = (81 Key = (
82 Key<Twox64Concat, CollectionId>,82 Key<Twox64Concat, CollectionId>,
83 Key<Blake2_128Concat, T::AccountId>,83 Key<Blake2_128Concat, T::CrossAccountId>,
84 Key<Twox64Concat, TokenId>,84 Key<Twox64Concat, TokenId>,
85 ),85 ),
86 Value = bool,86 Value = bool,
91 pub(super) type AccountBalance<T: Config> = StorageNMap<91 pub(super) type AccountBalance<T: Config> = StorageNMap<
92 Key = (92 Key = (
93 Key<Twox64Concat, CollectionId>,93 Key<Twox64Concat, CollectionId>,
94 Key<Blake2_128Concat, T::AccountId>,94 Key<Blake2_128Concat, T::CrossAccountId>,
95 ),95 ),
96 Value = u32,96 Value = u32,
97 QueryKind = ValueQuery,97 QueryKind = ValueQuery,
164 .ok_or_else(|| <CommonError<T>>::TokenNotFound)?;164 .ok_or_else(|| <CommonError<T>>::TokenNotFound)?;
165 ensure!(165 ensure!(
166 &token_data.owner == sender166 &token_data.owner == sender
167 || (collection.limits.owner_can_transfer167 || (collection.limits.owner_can_transfer()
168 && collection.is_owner_or_admin(sender)?),168 && collection.is_owner_or_admin(sender)?),
169 <CommonError<T>>::NoPermission169 <CommonError<T>>::NoPermission
170 );170 );
179179
180 // =========180 // =========
181181
182 <Owned<T>>::remove((collection.id, token_data.owner.as_sub(), token));182 <Owned<T>>::remove((collection.id, &token_data.owner, token));
183 <TokensBurnt<T>>::insert(collection.id, burnt);183 <TokensBurnt<T>>::insert(collection.id, burnt);
184 <TokenData<T>>::remove((collection.id, token));184 <TokenData<T>>::remove((collection.id, token));
185 let old_spender = <Allowance<T>>::take((collection.id, token));185 let old_spender = <Allowance<T>>::take((collection.id, token));
215 token: TokenId,215 token: TokenId,
216 ) -> DispatchResult {216 ) -> DispatchResult {
217 ensure!(217 ensure!(
218 collection.transfers_enabled,218 collection.limits.transfers_enabled(),
219 <CommonError<T>>::TransferNotAllowed219 <CommonError<T>>::TransferNotAllowed
220 );220 );
221221
222 let token_data = <TokenData<T>>::get((collection.id, token))222 let token_data = <TokenData<T>>::get((collection.id, token))
223 .ok_or_else(|| <CommonError<T>>::TokenNotFound)?;223 .ok_or_else(|| <CommonError<T>>::TokenNotFound)?;
224 ensure!(224 ensure!(
225 &token_data.owner == from225 &token_data.owner == from
226 || (collection.limits.owner_can_transfer && collection.is_owner_or_admin(from)?),226 || (collection.limits.owner_can_transfer()
227 && collection.is_owner_or_admin(from)?),
227 <CommonError<T>>::NoPermission228 <CommonError<T>>::NoPermission
228 );229 );
233 }234 }
234 <PalletCommon<T>>::ensure_correct_receiver(to)?;235 <PalletCommon<T>>::ensure_correct_receiver(to)?;
235236
236 let balance_from = <AccountBalance<T>>::get((collection.id, from.as_sub()))237 let balance_from = <AccountBalance<T>>::get((collection.id, from))
237 .checked_sub(1)238 .checked_sub(1)
238 .ok_or(<CommonError<T>>::TokenValueTooLow)?;239 .ok_or(<CommonError<T>>::TokenValueTooLow)?;
239 let balance_to = if from != to {240 let balance_to = if from != to {
240 let balance_to = <AccountBalance<T>>::get((collection.id, to.as_sub()))241 let balance_to = <AccountBalance<T>>::get((collection.id, to))
241 .checked_add(1)242 .checked_add(1)
242 .ok_or(ArithmeticError::Overflow)?;243 .ok_or(ArithmeticError::Overflow)?;
243244
267 if let Some(balance_to) = balance_to {268 if let Some(balance_to) = balance_to {
268 // from != to269 // from != to
269 if balance_from == 0 {270 if balance_from == 0 {
270 <AccountBalance<T>>::remove((collection.id, from.as_sub()));271 <AccountBalance<T>>::remove((collection.id, from));
271 } else {272 } else {
272 <AccountBalance<T>>::insert((collection.id, from.as_sub()), balance_from);273 <AccountBalance<T>>::insert((collection.id, from), balance_from);
273 }274 }
274 <AccountBalance<T>>::insert((collection.id, to.as_sub()), balance_to);275 <AccountBalance<T>>::insert((collection.id, to), balance_to);
275 <Owned<T>>::remove((collection.id, from.as_sub(), token));276 <Owned<T>>::remove((collection.id, from, token));
276 <Owned<T>>::insert((collection.id, to.as_sub(), token), true);277 <Owned<T>>::insert((collection.id, to, token), true);
277 }278 }
278 Self::set_allowance_unchecked(collection, from, token, None);279 Self::set_allowance_unchecked(collection, from, token, None, true);
279280
280 collection.log_infallible(ERC721Events::Transfer {281 collection.log_infallible(ERC721Events::Transfer {
281 from: *from.as_eth(),282 from: *from.as_eth(),
327 .checked_add(data.len() as u32)328 .checked_add(data.len() as u32)
328 .ok_or(ArithmeticError::Overflow)?;329 .ok_or(ArithmeticError::Overflow)?;
329 ensure!(330 ensure!(
330 tokens_minted < collection.limits.token_limit,331 tokens_minted < collection.limits.token_limit(),
331 <CommonError<T>>::CollectionTokenLimitExceeded332 <CommonError<T>>::CollectionTokenLimitExceeded
332 );333 );
333 collection.consume_sstore()?;334 collection.consume_sstore()?;
334335
335 let mut balances = BTreeMap::new();336 let mut balances = BTreeMap::new();
336 for data in &data {337 for data in &data {
337 let balance = balances338 let balance = balances
338 .entry(data.owner.as_sub())339 .entry(&data.owner)
339 .or_insert_with(|| <AccountBalance<T>>::get((collection.id, data.owner.as_sub())));340 .or_insert_with(|| <AccountBalance<T>>::get((collection.id, &data.owner)));
340 *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;341 *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;
341342
342 ensure!(343 ensure!(
363 owner: data.owner.clone(),364 owner: data.owner.clone(),
364 },365 },
365 );366 );
366 <Owned<T>>::insert((collection.id, data.owner.as_sub(), token), true);367 <Owned<T>>::insert((collection.id, &data.owner, token), true);
367368
368 collection.log_infallible(ERC721Events::Transfer {369 collection.log_infallible(ERC721Events::Transfer {
369 from: H160::default(),370 from: H160::default(),
385 sender: &T::CrossAccountId,386 sender: &T::CrossAccountId,
386 token: TokenId,387 token: TokenId,
387 spender: Option<&T::CrossAccountId>,388 spender: Option<&T::CrossAccountId>,
389 assume_implicit_eth: bool,
388 ) {390 ) {
389 if let Some(spender) = spender {391 if let Some(spender) = spender {
390 let old_spender = <Allowance<T>>::get((collection.id, token));392 let old_spender = <Allowance<T>>::get((collection.id, token));
418 }420 }
419 } else {421 } else {
420 let old_spender = <Allowance<T>>::take((collection.id, token));422 let old_spender = <Allowance<T>>::take((collection.id, token));
423 if !assume_implicit_eth {
421 // In ERC721 there is only one possible approved user of token, so we set424 // In ERC721 there is only one possible approved user of token, so we set
422 // approved user to zero address425 // approved user to zero address
423 collection.log_infallible(ERC721Events::Approval {426 collection.log_infallible(ERC721Events::Approval {
424 owner: *sender.as_eth(),427 owner: *sender.as_eth(),
425 approved: H160::default(),428 approved: H160::default(),
426 token_id: token.into(),429 token_id: token.into(),
427 });430 });
431 }
428 // In Unique chain, any token can have any amount of approved users, so we need to432 // In Unique chain, any token can have any amount of approved users, so we need to
429 // set allowance of old owner to 0433 // set allowance of old owner to 0
430 if let Some(old_spender) = old_spender {434 if let Some(old_spender) = old_spender {
466470
467 // =========471 // =========
468472
469 Self::set_allowance_unchecked(collection, sender, token, spender);473 Self::set_allowance_unchecked(collection, sender, token, spender, false);
470 Ok(())474 Ok(())
471 }475 }
472476
477 to: &T::CrossAccountId,481 to: &T::CrossAccountId,
478 token: TokenId,482 token: TokenId,
479 ) -> DispatchResult {483 ) -> DispatchResult {
480 if spender == from {484 if spender.conv_eq(from) {
481 return Self::transfer(collection, from, to, token);485 return Self::transfer(collection, from, to, token);
482 }486 }
483 if collection.access == AccessMode::WhiteList {487 if collection.access == AccessMode::WhiteList {
505 from: &T::CrossAccountId,509 from: &T::CrossAccountId,
506 token: TokenId,510 token: TokenId,
507 ) -> DispatchResult {511 ) -> DispatchResult {
508 if spender == from {512 if spender.conv_eq(from) {
509 return Self::burn(collection, from, token);513 return Self::burn(collection, from, token);
510 }514 }
511 if collection.access == AccessMode::WhiteList {515 if collection.access == AccessMode::WhiteList {
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
4use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};4use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};
5use nft_data_structs::TokenId;5use nft_data_structs::TokenId;
6use pallet_common::{6use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
7 CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,
8};
9use sp_runtime::DispatchError;7use sp_runtime::DispatchError;
10use sp_std::vec::Vec;8use sp_std::vec::Vec;
196 }194 }
197195
198 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {196 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
199 <Owned<T>>::iter_prefix((self.id, account.as_sub()))197 <Owned<T>>::iter_prefix((self.id, account))
200 .map(|(id, _)| id)198 .map(|(id, _)| id)
201 .collect()199 .collect()
202 }200 }
224 }222 }
225223
226 fn account_balance(&self, account: T::CrossAccountId) -> u32 {224 fn account_balance(&self, account: T::CrossAccountId) -> u32 {
227 <AccountBalance<T>>::get((self.id, account.as_sub()))225 <AccountBalance<T>>::get((self.id, account))
228 }226 }
229227
230 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {228 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {
231 <Balance<T>>::get((self.id, token, account.as_sub()))229 <Balance<T>>::get((self.id, token, account))
232 }230 }
233231
234 fn allowance(232 fn allowance(
237 spender: T::CrossAccountId,235 spender: T::CrossAccountId,
238 token: TokenId,236 token: TokenId,
239 ) -> u128 {237 ) -> u128 {
240 <Allowance<T>>::get((self.id, token, sender.as_sub(), spender))238 <Allowance<T>>::get((self.id, token, sender, spender))
241 }239 }
242}240}
243241
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
83 pub(super) type Owned<T: Config> = StorageNMap<83 pub(super) type Owned<T: Config> = StorageNMap<
84 Key = (84 Key = (
85 Key<Twox64Concat, CollectionId>,85 Key<Twox64Concat, CollectionId>,
86 Key<Blake2_128Concat, T::AccountId>,86 Key<Blake2_128Concat, T::CrossAccountId>,
87 Key<Twox64Concat, TokenId>,87 Key<Twox64Concat, TokenId>,
88 ),88 ),
89 Value = bool,89 Value = bool,
95 Key = (95 Key = (
96 Key<Twox64Concat, CollectionId>,96 Key<Twox64Concat, CollectionId>,
97 // Owner97 // Owner
98 Key<Blake2_128Concat, T::AccountId>,98 Key<Blake2_128Concat, T::CrossAccountId>,
99 ),99 ),
100 Value = u32,100 Value = u32,
101 QueryKind = ValueQuery,101 QueryKind = ValueQuery,
107 Key<Twox64Concat, CollectionId>,107 Key<Twox64Concat, CollectionId>,
108 Key<Twox64Concat, TokenId>,108 Key<Twox64Concat, TokenId>,
109 // Owner109 // Owner
110 Key<Blake2_128Concat, T::AccountId>,110 Key<Blake2_128Concat, T::CrossAccountId>,
111 ),111 ),
112 Value = u128,112 Value = u128,
113 QueryKind = ValueQuery,113 QueryKind = ValueQuery,
119 Key<Twox64Concat, CollectionId>,119 Key<Twox64Concat, CollectionId>,
120 Key<Twox64Concat, TokenId>,120 Key<Twox64Concat, TokenId>,
121 // Owner121 // Owner
122 Key<Blake2_128, T::AccountId>,122 Key<Blake2_128, T::CrossAccountId>,
123 // Spender123 // Spender
124 Key<Blake2_128Concat, T::CrossAccountId>,124 Key<Blake2_128Concat, T::CrossAccountId>,
125 ),125 ),
206 if total_supply == 0 {206 if total_supply == 0 {
207 // Ensure user actually owns this amount207 // Ensure user actually owns this amount
208 ensure!(208 ensure!(
209 <Balance<T>>::get((collection.id, token, owner.as_sub())) == amount,209 <Balance<T>>::get((collection.id, token, owner)) == amount,
210 <CommonError<T>>::TokenValueTooLow210 <CommonError<T>>::TokenValueTooLow
211 );211 );
212 let account_balance = <AccountBalance<T>>::get((collection.id, owner.as_sub()))212 let account_balance = <AccountBalance<T>>::get((collection.id, owner))
213 .checked_sub(1)213 .checked_sub(1)
214 // Should not occur214 // Should not occur
215 .ok_or(ArithmeticError::Underflow)?;215 .ok_or(ArithmeticError::Underflow)?;
216216
217 // =========217 // =========
218218
219 <Owned<T>>::remove((collection.id, owner.as_sub(), token));219 <Owned<T>>::remove((collection.id, owner, token));
220 <AccountBalance<T>>::insert((collection.id, owner.as_sub()), account_balance);220 <AccountBalance<T>>::insert((collection.id, owner), account_balance);
221 Self::burn_token(collection, token)?;221 Self::burn_token(collection, token)?;
222 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(222 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
223 collection.id,223 collection.id,
228 return Ok(());228 return Ok(());
229 }229 }
230230
231 let balance = <Balance<T>>::get((collection.id, token, owner.as_sub()))231 let balance = <Balance<T>>::get((collection.id, token, owner))
232 .checked_sub(amount)232 .checked_sub(amount)
233 .ok_or(<CommonError<T>>::TokenValueTooLow)?;233 .ok_or(<CommonError<T>>::TokenValueTooLow)?;
234 let account_balance = if balance == 0 {234 let account_balance = if balance == 0 {
235 <AccountBalance<T>>::get((collection.id, owner.as_sub()))235 <AccountBalance<T>>::get((collection.id, owner))
236 .checked_sub(1)236 .checked_sub(1)
237 // Should not occur237 // Should not occur
238 .ok_or(ArithmeticError::Underflow)?238 .ok_or(ArithmeticError::Underflow)?
243 // =========243 // =========
244244
245 if balance == 0 {245 if balance == 0 {
246 <Owned<T>>::remove((collection.id, owner.as_sub(), token));246 <Owned<T>>::remove((collection.id, owner, token));
247 <Balance<T>>::remove((collection.id, token, owner.as_sub()));247 <Balance<T>>::remove((collection.id, token, owner));
248 <AccountBalance<T>>::insert((collection.id, owner.as_sub()), account_balance);248 <AccountBalance<T>>::insert((collection.id, owner), account_balance);
249 } else {249 } else {
250 <Balance<T>>::insert((collection.id, token, owner.as_sub()), balance);250 <Balance<T>>::insert((collection.id, token, owner), balance);
251 }251 }
252 <TotalSupply<T>>::insert((collection.id, token), total_supply);252 <TotalSupply<T>>::insert((collection.id, token), total_supply);
253 // TODO: ERC20 transfer event253 // TODO: ERC20 transfer event
268 amount: u128,268 amount: u128,
269 ) -> DispatchResult {269 ) -> DispatchResult {
270 ensure!(270 ensure!(
271 collection.transfers_enabled,271 collection.limits.transfers_enabled(),
272 <CommonError<T>>::TransferNotAllowed272 <CommonError<T>>::TransferNotAllowed
273 );273 );
274274
278 }278 }
279 <PalletCommon<T>>::ensure_correct_receiver(to)?;279 <PalletCommon<T>>::ensure_correct_receiver(to)?;
280280
281 let balance_from = <Balance<T>>::get((collection.id, token, from.as_sub()))281 let balance_from = <Balance<T>>::get((collection.id, token, from))
282 .checked_sub(amount)282 .checked_sub(amount)
283 .ok_or(<CommonError<T>>::TokenValueTooLow)?;283 .ok_or(<CommonError<T>>::TokenValueTooLow)?;
284 let mut create_target = false;284 let mut create_target = false;
285 let from_to_differ = from != to;285 let from_to_differ = from != to;
286 let balance_to = if from != to {286 let balance_to = if from != to {
287 let old_balance = <Balance<T>>::get((collection.id, token, to.as_sub()));287 let old_balance = <Balance<T>>::get((collection.id, token, to));
288 if old_balance == 0 {288 if old_balance == 0 {
289 create_target = true;289 create_target = true;
290 }290 }
299299
300 let account_balance_from = if balance_from == 0 {300 let account_balance_from = if balance_from == 0 {
301 Some(301 Some(
302 <AccountBalance<T>>::get((collection.id, from.as_sub()))302 <AccountBalance<T>>::get((collection.id, from))
303 .checked_sub(1)303 .checked_sub(1)
304 // Should not occur304 // Should not occur
305 .ok_or(ArithmeticError::Underflow)?,305 .ok_or(ArithmeticError::Underflow)?,
310 // Account data is created in token, AccountBalance should be increased310 // Account data is created in token, AccountBalance should be increased
311 // But only if from != to as we shouldn't check overflow in this case311 // But only if from != to as we shouldn't check overflow in this case
312 let account_balance_to = if create_target && from_to_differ {312 let account_balance_to = if create_target && from_to_differ {
313 let account_balance_to = <AccountBalance<T>>::get((collection.id, to.as_sub()))313 let account_balance_to = <AccountBalance<T>>::get((collection.id, to))
314 .checked_add(1)314 .checked_add(1)
315 .ok_or(ArithmeticError::Overflow)?;315 .ok_or(ArithmeticError::Overflow)?;
316 ensure!(316 ensure!(
328 if let Some(balance_to) = balance_to {328 if let Some(balance_to) = balance_to {
329 // from != to329 // from != to
330 if balance_from == 0 {330 if balance_from == 0 {
331 <Balance<T>>::remove((collection.id, token, from.as_sub()));331 <Balance<T>>::remove((collection.id, token, from));
332 } else {332 } else {
333 <Balance<T>>::insert((collection.id, token, from.as_sub()), balance_from);333 <Balance<T>>::insert((collection.id, token, from), balance_from);
334 }334 }
335 <Balance<T>>::insert((collection.id, token, to.as_sub()), balance_to);335 <Balance<T>>::insert((collection.id, token, to), balance_to);
336 if let Some(account_balance_from) = account_balance_from {336 if let Some(account_balance_from) = account_balance_from {
337 <AccountBalance<T>>::insert((collection.id, from.as_sub()), account_balance_from);337 <AccountBalance<T>>::insert((collection.id, from), account_balance_from);
338 <Owned<T>>::remove((collection.id, from.as_sub(), token));338 <Owned<T>>::remove((collection.id, from, token));
339 }339 }
340 if let Some(account_balance_to) = account_balance_to {340 if let Some(account_balance_to) = account_balance_to {
341 <AccountBalance<T>>::insert((collection.id, to.as_sub()), account_balance_to);341 <AccountBalance<T>>::insert((collection.id, to), account_balance_to);
342 <Owned<T>>::insert((collection.id, to.as_sub(), token), true);342 <Owned<T>>::insert((collection.id, to, token), true);
343 }343 }
344 }344 }
345345
404 .checked_add(data.len() as u32)404 .checked_add(data.len() as u32)
405 .ok_or(ArithmeticError::Overflow)?;405 .ok_or(ArithmeticError::Overflow)?;
406 ensure!(406 ensure!(
407 tokens_minted < collection.limits.token_limit,407 tokens_minted < collection.limits.token_limit(),
408 <CommonError<T>>::CollectionTokenLimitExceeded408 <CommonError<T>>::CollectionTokenLimitExceeded
409 );409 );
410410
411 let mut balances = BTreeMap::new();411 let mut balances = BTreeMap::new();
412 for data in &data {412 for data in &data {
413 for (owner, _) in &data.users {413 for (owner, _) in &data.users {
414 let balance = balances414 let balance = balances
415 .entry(owner.as_sub())415 .entry(owner)
416 .or_insert_with(|| <AccountBalance<T>>::get((collection.id, owner.as_sub())));416 .or_insert_with(|| <AccountBalance<T>>::get((collection.id, owner)));
417 *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;417 *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;
418418
419 ensure!(419 ensure!(
444 if amount == 0 {444 if amount == 0 {
445 continue;445 continue;
446 }446 }
447 <Balance<T>>::insert((collection.id, token_id, user.as_sub()), amount);447 <Balance<T>>::insert((collection.id, token_id, &user), amount);
448 <Owned<T>>::insert((collection.id, user.as_sub(), TokenId(token_id)), true);448 <Owned<T>>::insert((collection.id, &user, TokenId(token_id)), true);
449 // TODO: ERC20 transfer event449 // TODO: ERC20 transfer event
450 <PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(450 <PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(
451 collection.id,451 collection.id,
465 token: TokenId,465 token: TokenId,
466 amount: u128,466 amount: u128,
467 ) {467 ) {
468 <Allowance<T>>::insert((collection.id, token, sender.as_sub(), spender), amount);468 <Allowance<T>>::insert((collection.id, token, sender, spender), amount);
469 // TODO: ERC20 approval event469 // TODO: ERC20 approval event
470 <PalletCommon<T>>::deposit_event(CommonEvent::Approved(470 <PalletCommon<T>>::deposit_event(CommonEvent::Approved(
471 collection.id,471 collection.id,
490490
491 <PalletCommon<T>>::ensure_correct_receiver(spender)?;491 <PalletCommon<T>>::ensure_correct_receiver(spender)?;
492492
493 if <Balance<T>>::get((collection.id, token, sender.as_sub())) < amount {493 if <Balance<T>>::get((collection.id, token, sender)) < amount {
494 ensure!(494 ensure!(
495 collection.ignores_owned_amount(sender)?,495 collection.ignores_owned_amount(sender)? && Self::token_exists(collection, token),
496 <CommonError<T>>::CantApproveMoreThanOwned496 <CommonError<T>>::CantApproveMoreThanOwned
497 );497 );
498 }498 }
511 token: TokenId,511 token: TokenId,
512 amount: u128,512 amount: u128,
513 ) -> DispatchResult {513 ) -> DispatchResult {
514 if spender == from {514 if spender.conv_eq(from) {
515 return Self::transfer(collection, from, to, token, amount);515 return Self::transfer(collection, from, to, token, amount);
516 }516 }
517 if collection.access == AccessMode::WhiteList {517 if collection.access == AccessMode::WhiteList {
518 // `from`, `to` checked in [`transfer`]518 // `from`, `to` checked in [`transfer`]
519 collection.check_allowlist(spender)?;519 collection.check_allowlist(spender)?;
520 }520 }
521521
522 let allowance = <Allowance<T>>::get((collection.id, token, from.as_sub(), &spender))522 let allowance =
523 .checked_sub(amount);523 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
524 if allowance.is_none() {524 if allowance.is_none() {
525 ensure!(525 ensure!(
544 token: TokenId,544 token: TokenId,
545 amount: u128,545 amount: u128,
546 ) -> DispatchResult {546 ) -> DispatchResult {
547 if spender == from {547 if spender.conv_eq(from) {
548 return Self::burn(collection, from, token, amount);548 return Self::burn(collection, from, token, amount);
549 }549 }
550 if collection.access == AccessMode::WhiteList {550 if collection.access == AccessMode::WhiteList {
551 // `from` checked in [`burn`]551 // `from` checked in [`burn`]
552 collection.check_allowlist(spender)?;552 collection.check_allowlist(spender)?;
553 }553 }
554554
555 let allowance = <Allowance<T>>::get((collection.id, token, from.as_sub(), &spender))555 let allowance =
556 .checked_sub(amount);556 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
557 if allowance.is_none() {557 if allowance.is_none() {
558 ensure!(558 ensure!(
modifiedprimitives/nft/src/lib.rsdiffbeforeafterboth
41} else {41} else {
42 1042 10
43};43};
44pub const COLLECTION_ADMINS_LIMIT: u64 = 5;44pub const COLLECTION_ADMINS_LIMIT: u32 = 5;
45pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;
45pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {46pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
46 100000047 1000000
47} else {48} else {
217 pub offchain_schema: Vec<u8>,218 pub offchain_schema: Vec<u8>,
218 pub schema_version: SchemaVersion,219 pub schema_version: SchemaVersion,
219 pub sponsorship: SponsorshipState<T::AccountId>,220 pub sponsorship: SponsorshipState<T::AccountId>,
220 pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions221 pub limits: CollectionLimits, // Collection private restrictions
221 pub variable_on_chain_schema: Vec<u8>, //222 pub variable_on_chain_schema: Vec<u8>, //
222 pub const_on_chain_schema: Vec<u8>, //223 pub const_on_chain_schema: Vec<u8>, //
223 pub meta_update_permission: MetaUpdatePermission,224 pub meta_update_permission: MetaUpdatePermission,
224 pub transfers_enabled: bool,
225}225}
226226
227#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]227#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
246 pub variable_data: Vec<u8>,246 pub variable_data: Vec<u8>,
247}247}
248248
249#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]249#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo)]
250#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]250#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
251pub struct CollectionLimits<BlockNumber: Encode + Decode> {251pub struct CollectionLimits {
252 pub account_token_ownership_limit: Option<u32>,252 pub account_token_ownership_limit: Option<u32>,
253 pub sponsored_data_size: u32,253 pub sponsored_data_size: Option<u32>,
254 /// None - setVariableMetadata is not sponsored254 /// None - setVariableMetadata is not sponsored
255 /// Some(v) - setVariableMetadata is sponsored255 /// Some(v) - setVariableMetadata is sponsored
256 /// if there is v block between txs256 /// if there is v block between txs
257 pub sponsored_data_rate_limit: Option<BlockNumber>,257 pub sponsored_data_rate_limit: Option<u32>,
258 pub token_limit: u32,258 pub token_limit: Option<u32>,
259259
260 // Timeouts for item types in passed blocks260 // Timeouts for item types in passed blocks
261 pub sponsor_transfer_timeout: u32,261 pub sponsor_transfer_timeout: Option<u32>,
262 pub owner_can_transfer: bool,262 pub owner_can_transfer: Option<bool>,
263 pub owner_can_destroy: bool,263 pub owner_can_destroy: Option<bool>,
264 pub transfers_enabled: Option<bool>,
264}265}
265266
266impl<BlockNumber: Encode + Decode> CollectionLimits<BlockNumber> {267impl CollectionLimits {
267 pub fn account_token_ownership_limit(&self) -> u32 {268 pub fn account_token_ownership_limit(&self) -> u32 {
268 self.account_token_ownership_limit269 self.account_token_ownership_limit
269 .unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)270 .unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)
270 .min(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)271 .min(MAX_TOKEN_OWNERSHIP)
271 }272 }
273 pub fn sponsored_data_size(&self) -> u32 {
274 self.sponsored_data_size
275 .unwrap_or(CUSTOM_DATA_LIMIT)
276 .min(CUSTOM_DATA_LIMIT)
277 }
278 pub fn token_limit(&self) -> u32 {
279 self.token_limit
280 .unwrap_or(COLLECTION_TOKEN_LIMIT)
281 .min(COLLECTION_TOKEN_LIMIT)
282 }
283 pub fn sponsor_transfer_timeout(&self, default: u32) -> u32 {
284 self.sponsor_transfer_timeout
285 .unwrap_or(default)
286 .min(MAX_SPONSOR_TIMEOUT)
287 }
288 pub fn owner_can_transfer(&self) -> bool {
289 self.owner_can_transfer.unwrap_or(true)
290 }
291 pub fn owner_can_destroy(&self) -> bool {
292 self.owner_can_destroy.unwrap_or(true)
293 }
294 pub fn transfers_enabled(&self) -> bool {
295 self.transfers_enabled.unwrap_or(true)
296 }
297 pub fn sponsored_data_rate_limit(&self) -> Option<u32> {
298 self.sponsored_data_rate_limit
299 .map(|v| v.min(MAX_SPONSOR_TIMEOUT))
300 }
272}301}
273
274impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {
275 fn default() -> Self {
276 Self {
277 account_token_ownership_limit: Some(10_000_000),
278 token_limit: u32::max_value(),
279 sponsored_data_size: u32::MAX,
280 sponsored_data_rate_limit: None,
281 sponsor_transfer_timeout: 14400,
282 owner_can_transfer: true,
283 owner_can_destroy: true,
284 }
285 }
286}
287302
288/// BoundedVec doesn't supports serde303/// BoundedVec doesn't supports serde
289#[cfg(feature = "serde1")]304#[cfg(feature = "serde1")]
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
30 /// Used for ethereum integration30 /// Used for ethereum integration
31 fn eth_contract_code(account: H160) -> Option<Vec<u8>>;31 fn eth_contract_code(account: H160) -> Option<Vec<u8>>;
3232
33 fn adminlist(collection: CollectionId) -> Vec<AccountId>;33 fn adminlist(collection: CollectionId) -> Vec<CrossAccountId>;
34 fn allowlist(collection: CollectionId) -> Vec<AccountId>;34 fn allowlist(collection: CollectionId) -> Vec<CrossAccountId>;
35 fn last_token_id(collection: CollectionId) -> TokenId;35 fn last_token_id(collection: CollectionId) -> TokenId;
36 }36 }
37}37}
modifiedruntime/src/lib.rsdiffbeforeafterboth
1039 .or_else(|| <pallet_evm_migration::OnMethodCall<Runtime>>::get_code(&account))
1040 .or_else(|| <pallet_evm_contract_helpers::HelpersOnMethodCall<Self>>::get_code(&account))
1039 }1041 }
1040 fn adminlist(collection: CollectionId) -> Vec<AccountId> {1042 fn adminlist(collection: CollectionId) -> Vec<CrossAccountId> {
1041 <pallet_nft::Pallet<Runtime>>::adminlist(collection)1043 <pallet_nft::Pallet<Runtime>>::adminlist(collection)
1042 }1044 }
1043 fn allowlist(collection: CollectionId) -> Vec<AccountId> {1045 fn allowlist(collection: CollectionId) -> Vec<CrossAccountId> {
1044 <pallet_nft::Pallet<Runtime>>::allowlist(collection)1046 <pallet_nft::Pallet<Runtime>>::allowlist(collection)
1045 }1047 }
1046 fn last_token_id(collection: CollectionId) -> TokenId {1048 fn last_token_id(collection: CollectionId) -> TokenId {
modifiedtests/.eslintrc.jsondiffbeforeafterboth
63 {63 {
64 "destructuring": "all"64 "destructuring": "all"
65 }65 }
66 ]66 ],
67 "object-curly-spacing": "warn",
68 "arrow-spacing": "warn",
69 "array-bracket-spacing": "warn",
70 "template-curly-spacing": "warn",
71 "space-in-parens": "warn",
72 "@typescript-eslint/naming-convention": [
73 "warn",
74 {
75 "selector": "default",
76 "format": [
77 "camelCase"
78 ],
79 "leadingUnderscore": "allow",
80 "trailingUnderscore": "allow"
81 },
82 {
83 "selector": "variable",
84 "format": [
85 "camelCase",
86 "UPPER_CASE"
87 ],
88 "leadingUnderscore": "allow",
89 "trailingUnderscore": "allow"
90 },
91 {
92 "selector": "typeLike",
93 "format": [
94 "PascalCase"
95 ]
96 },
97 {
98 "selector": "memberLike",
99 "format": null
100 }
101 ]
67 }102 }
68}103}
104
modifiedtests/package.jsondiffbeforeafterboth
4 "description": "Substrate Nft tests",4 "description": "Substrate Nft tests",
5 "main": "",5 "main": "",
6 "devDependencies": {6 "devDependencies": {
7 "@polkadot/dev": "0.63.9",7 "@polkadot/dev": "0.63.18",
8 "@polkadot/ts": "0.4.12",8 "@polkadot/ts": "0.4.12",
9 "@polkadot/typegen": "6.5.2-3",9 "@polkadot/typegen": "6.6.2-5",
10 "@types/chai": "^4.2.22",10 "@types/chai": "^4.2.22",
11 "@types/chai-as-promised": "^7.1.4",11 "@types/chai-as-promised": "^7.1.4",
12 "@types/mocha": "^9.0.0",12 "@types/mocha": "^9.0.0",
13 "@types/node": "^16.11.4",13 "@types/node": "^16.11.6",
14 "@typescript-eslint/eslint-plugin": "^5.1.0",14 "@typescript-eslint/eslint-plugin": "^5.3.0",
15 "@typescript-eslint/parser": "^5.1.0",15 "@typescript-eslint/parser": "^5.3.0",
16 "chai": "^4.3.4",16 "chai": "^4.3.4",
17 "eslint": "^8.1.0",17 "eslint": "^8.1.0",
18 "mocha": "^9.1.3",18 "mocha": "^9.1.3",
29 "fix": "eslint --ext .ts,.js src/ --fix",29 "fix": "eslint --ext .ts,.js src/ --fix",
30 "test": "mocha --timeout 9999999 -r ts-node/register './**/*.test.ts'",30 "test": "mocha --timeout 9999999 -r ts-node/register './**/*.test.ts'",
31 "testEth": "mocha --timeout 9999999 -r ts-node/register './**/eth/**/*.test.ts'",31 "testEth": "mocha --timeout 9999999 -r ts-node/register './**/eth/**/*.test.ts'",
32 "testEthMarketplace": "mocha --timeout 9999999 -r ts-node/register './**/eth/marketplace/**/*.test.ts'",
32 "load": "mocha --timeout 9999999 -r ts-node/register './**/*.load.ts'",33 "load": "mocha --timeout 9999999 -r ts-node/register './**/*.load.ts'",
33 "loadTransfer": "ts-node src/transfer.nload.ts",34 "loadTransfer": "ts-node src/transfer.nload.ts",
34 "testCollision": "mocha --timeout 9999999 -r ts-node/register ./src/collision-tests/*.test.ts",35 "testCollision": "mocha --timeout 9999999 -r ts-node/register ./src/collision-tests/*.test.ts",
65 "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",66 "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",
66 "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",67 "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",
67 "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",68 "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",
68 "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts"69 "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts",
70 "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --input src/interfaces/ --package .",
71 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint ws://localhost:9944 --output src/interfaces/ --package .",
72 "polkadot-types": "yarn polkadot-types-from-defs && yarn polkadot-types-from-chain"
69 },73 },
70 "author": "",74 "author": "",
71 "license": "SEE LICENSE IN ../LICENSE",75 "license": "SEE LICENSE IN ../LICENSE",
72 "homepage": "",76 "homepage": "",
73 "dependencies": {77 "dependencies": {
74 "@polkadot/api": "6.5.1",78 "@polkadot/api": "6.6.2-5",
75 "@polkadot/api-contract": "6.5.1",79 "@polkadot/api-contract": "6.6.2-5",
76 "@polkadot/util-crypto": "^7.6.1",80 "@polkadot/util-crypto": "^7.7.1",
77 "bignumber.js": "^9.0.1",81 "bignumber.js": "^9.0.1",
78 "chai-as-promised": "^7.1.1",82 "chai-as-promised": "^7.1.1",
79 "solc": "^0.8.9",83 "solc": "^0.8.9",
modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
8import chaiAsPromised from 'chai-as-promised';8import chaiAsPromised from 'chai-as-promised';
9import privateKey from './substrate/privateKey';9import privateKey from './substrate/privateKey';
10import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';10import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
11import {createCollectionExpectSuccess, destroyCollectionExpectSuccess, normalizeAccountId} from './util/helpers';11import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, destroyCollectionExpectSuccess, getAdminList, normalizeAccountId} from './util/helpers';
1212
13chai.use(chaiAsPromised);13chai.use(chaiAsPromised);
14const expect = chai.expect;14const expect = chai.expect;
20 const alice = privateKey('//Alice');20 const alice = privateKey('//Alice');
21 const bob = privateKey('//Bob');21 const bob = privateKey('//Bob');
2222
23 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();23 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
24 expect(collection.owner).to.be.equal(alice.address);24 expect(collection.owner.toString()).to.be.equal(alice.address);
2525
26 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));26 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
27 await submitTransactionAsync(alice, changeAdminTx);27 await submitTransactionAsync(alice, changeAdminTx);
2828
29 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));29 const adminListAfterAddAdmin = await getAdminList(api, collectionId);
30 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(bob.address));30 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
31 });31 });
32 });32 });
3333
34 it('Add admin using added collection admin.', async () => {34 it('Add admin using added collection admin.', async () => {
35 await usingApi(async (api) => {35 await usingApi(async (api) => {
36 const collectionId = await createCollectionExpectSuccess();36 const collectionId = await createCollectionExpectSuccess();
37 const Alice = privateKey('//Alice');37 const alice = privateKey('//Alice');
38 const Bob = privateKey('//Bob');38 const bob = privateKey('//Bob');
39 const Charlie = privateKey('//CHARLIE');39 const charlie = privateKey('//CHARLIE');
4040
41 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();41 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
42 expect(collection.owner).to.be.equal(Alice.address);42 expect(collection.owner.toString()).to.be.equal(alice.address);
4343
44 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));44 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
45 await submitTransactionAsync(Alice, changeAdminTx);45 await submitTransactionAsync(alice, changeAdminTx);
4646
47 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));47 const adminListAfterAddAdmin = await getAdminList(api, collectionId);
48 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(Bob.address));48 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
4949
50 const changeAdminTxCharlie = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Charlie.address));50 const changeAdminTxCharlie = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));
51 await submitTransactionAsync(Bob, changeAdminTxCharlie);51 await submitTransactionAsync(bob, changeAdminTxCharlie);
52 const adminListAfterAddNewAdmin: any = (await api.query.nft.adminList(collectionId));52 const adminListAfterAddNewAdmin = await getAdminList(api, collectionId);
53 expect(adminListAfterAddNewAdmin).to.be.contains(normalizeAccountId(Bob.address));53 expect(adminListAfterAddNewAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
54 expect(adminListAfterAddNewAdmin).to.be.contains(normalizeAccountId(Charlie.address));54 expect(adminListAfterAddNewAdmin).to.be.deep.contains(normalizeAccountId(charlie.address));
55 });55 });
56 });56 });
57});57});
66 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(alice.address));66 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(alice.address));
67 await expect(submitTransactionExpectFailAsync(nonOwner, changeAdminTx)).to.be.rejected;67 await expect(submitTransactionExpectFailAsync(nonOwner, changeAdminTx)).to.be.rejected;
6868
69 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));69 const adminListAfterAddAdmin = await getAdminList(api, collectionId);
70 expect(adminListAfterAddAdmin).not.to.be.contains(normalizeAccountId(alice.address));70 expect(adminListAfterAddAdmin).not.to.be.deep.contains(normalizeAccountId(alice.address));
7171
72 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)72 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
73 await createCollectionExpectSuccess();73 await createCollectionExpectSuccess();
91 it("Can't add an admin to a destroyed collection.", async () => {91 it("Can't add an admin to a destroyed collection.", async () => {
92 await usingApi(async (api) => {92 await usingApi(async (api) => {
93 const collectionId = await createCollectionExpectSuccess();93 const collectionId = await createCollectionExpectSuccess();
94 const Alice = privateKey('//Alice');94 const alice = privateKey('//Alice');
95 const Bob = privateKey('//Bob');95 const bob = privateKey('//Bob');
96 await destroyCollectionExpectSuccess(collectionId);96 await destroyCollectionExpectSuccess(collectionId);
97 const changeOwnerTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));97 const changeOwnerTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
98 await expect(submitTransactionExpectFailAsync(Alice, changeOwnerTx)).to.be.rejected;98 await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;
9999
100 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)100 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
101 await createCollectionExpectSuccess();101 await createCollectionExpectSuccess();
104104
105 it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {105 it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {
106 await usingApi(async (api: ApiPromise) => {106 await usingApi(async (api: ApiPromise) => {
107 const Alice = privateKey('//Alice');107 const alice = privateKey('//Alice');
108 const accounts = [108 const accounts = [
109 'GsvVmjr1CBHwQHw84pPHMDxgNY3iBLz6Qn7qS3CH8qPhrHz',109 privateKey('//AdminTest/1').address,
110 'FoQJpPyadYccjavVdTWxpxU7rUEaYhfLCPwXgkfD6Zat9QP',110 privateKey('//AdminTest/2').address,
111 'JKspFU6ohf1Grg3Phdzj2pSgWvsYWzSfKghhfzMbdhNBWs5',111 privateKey('//AdminTest/3').address,
112 'Fr4NzY1udSFFLzb2R3qxVQkwz9cZraWkyfH4h3mVVk7BK7P',112 privateKey('//AdminTest/4').address,
113 'DfnTB4z7eUvYRqcGtTpFsLC69o6tvBSC1pEv8vWPZFtCkaK',113 privateKey('//AdminTest/5').address,
114 'HnMAUz7r2G8G3hB27SYNyit5aJmh2a5P4eMdDtACtMFDbam',114 privateKey('//AdminTest/6').address,
115 'DE14BzQ1bDXWPKeLoAqdLAm1GpyAWaWF1knF74cEZeomTBM',115 privateKey('//AdminTest/7').address,
116 ];116 ];
117 const collectionId = await createCollectionExpectSuccess();117 const collectionId = await createCollectionExpectSuccess();
118118
119 const chainAdminLimit = (api.consts.nft.collectionAdminsLimit as any).toNumber();119 const chainAdminLimit = api.consts.common.collectionAdminsLimit.toNumber();
120 expect(chainAdminLimit).to.be.equal(5);120 expect(chainAdminLimit).to.be.equal(5);
121121
122 for (let i = 0; i < chainAdminLimit; i++) {122 for (let i = 0; i < chainAdminLimit; i++) {
123 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(accounts[i]));123 await addCollectionAdminExpectSuccess(alice, collectionId, accounts[i]);
124 await submitTransactionAsync(Alice, changeAdminTx);
125 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));124 const adminListAfterAddAdmin = await getAdminList(api, collectionId);
126 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(accounts[i]));125 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(accounts[i]));
127 }126 }
128127
129 const tx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(accounts[chainAdminLimit]));128 const tx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(accounts[chainAdminLimit]));
130 await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;129 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
131 });130 });
132 });131 });
133});132});
modifiedtests/src/addToContractWhiteList.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/addToWhiteList.test.tsdiffbeforeafterboth
23chai.use(chaiAsPromised);23chai.use(chaiAsPromised);
24const expect = chai.expect;24const expect = chai.expect;
2525
26let Alice: IKeyringPair;26let alice: IKeyringPair;
27let Bob: IKeyringPair;27let bob: IKeyringPair;
28let Charlie: IKeyringPair;28let charlie: IKeyringPair;
2929
30describe('Integration Test ext. addToWhiteList()', () => {30describe('Integration Test ext. addToWhiteList()', () => {
3131
32 before(async () => {32 before(async () => {
33 await usingApi(async () => {33 await usingApi(async () => {
34 Alice = privateKey('//Alice');34 alice = privateKey('//Alice');
35 Bob = privateKey('//Bob');35 bob = privateKey('//Bob');
36 });36 });
37 });37 });
3838
39 it('Execute the extrinsic with parameters: Collection ID and address to add to the white list', async () => {39 it('Execute the extrinsic with parameters: Collection ID and address to add to the white list', async () => {
40 const collectionId = await createCollectionExpectSuccess();40 const collectionId = await createCollectionExpectSuccess();
41 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);41 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
42 });42 });
4343
44 it('Whitelisted minting: list restrictions', async () => {44 it('Whitelisted minting: list restrictions', async () => {
45 const collectionId = await createCollectionExpectSuccess();45 const collectionId = await createCollectionExpectSuccess();
46 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);46 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
47 await enableWhiteListExpectSuccess(Alice, collectionId);47 await enableWhiteListExpectSuccess(alice, collectionId);
48 await enablePublicMintingExpectSuccess(Alice, collectionId);48 await enablePublicMintingExpectSuccess(alice, collectionId);
49 await createItemExpectSuccess(Bob, collectionId, 'NFT', Bob.address);49 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
50 });50 });
51});51});
5252
55 it('White list an address in the collection that does not exist', async () => {55 it('White list an address in the collection that does not exist', async () => {
56 await usingApi(async (api) => {56 await usingApi(async (api) => {
57 // tslint:disable-next-line: no-bitwise57 // tslint:disable-next-line: no-bitwise
58 const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;58 const collectionId = ((await api.query.common.createdCollectionCount()).toNumber()) + 1;
59 const Bob = privateKey('//Bob');59 const bob = privateKey('//Bob');
6060
61 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(Bob.address));61 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(bob.address));
62 await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;62 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
63 });63 });
64 });64 });
6565
66 it('White list an address in the collection that was destroyed', async () => {66 it('White list an address in the collection that was destroyed', async () => {
67 await usingApi(async (api) => {67 await usingApi(async (api) => {
68 const Alice = privateKey('//Alice');68 const alice = privateKey('//Alice');
69 const Bob = privateKey('//Bob');69 const bob = privateKey('//Bob');
70 // tslint:disable-next-line: no-bitwise70 // tslint:disable-next-line: no-bitwise
71 const collectionId = await createCollectionExpectSuccess();71 const collectionId = await createCollectionExpectSuccess();
72 await destroyCollectionExpectSuccess(collectionId);72 await destroyCollectionExpectSuccess(collectionId);
73 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(Bob.address));73 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(bob.address));
74 await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;74 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
75 });75 });
76 });76 });
7777
78 it('White list an address in the collection that does not have white list access enabled', async () => {78 it('White list an address in the collection that does not have white list access enabled', async () => {
79 await usingApi(async (api) => {79 await usingApi(async (api) => {
80 const Alice = privateKey('//Alice');80 const alice = privateKey('//Alice');
81 const Ferdie = privateKey('//Ferdie');81 const ferdie = privateKey('//Ferdie');
82 const collectionId = await createCollectionExpectSuccess();82 const collectionId = await createCollectionExpectSuccess();
83 await enableWhiteListExpectSuccess(Alice, collectionId);83 await enableWhiteListExpectSuccess(alice, collectionId);
84 await enablePublicMintingExpectSuccess(Alice, collectionId);84 await enablePublicMintingExpectSuccess(alice, collectionId);
85 const tx = api.tx.nft.createItem(collectionId, normalizeAccountId(Ferdie.address), 'NFT');85 const tx = api.tx.nft.createItem(collectionId, normalizeAccountId(ferdie.address), 'NFT');
86 await expect(submitTransactionExpectFailAsync(Ferdie, tx)).to.be.rejected;86 await expect(submitTransactionExpectFailAsync(ferdie, tx)).to.be.rejected;
87 });87 });
88 });88 });
8989
9393
94 before(async () => {94 before(async () => {
95 await usingApi(async () => {95 await usingApi(async () => {
96 Alice = privateKey('//Alice');96 alice = privateKey('//Alice');
97 Bob = privateKey('//Bob');97 bob = privateKey('//Bob');
98 Charlie = privateKey('//Charlie');98 charlie = privateKey('//Charlie');
99 });99 });
100 });100 });
101101
102 it('Negative. Add to the white list by regular user', async () => {102 it('Negative. Add to the white list by regular user', async () => {
103 const collectionId = await createCollectionExpectSuccess();103 const collectionId = await createCollectionExpectSuccess();
104 await addToWhiteListExpectFail(Bob, collectionId, Charlie.address);104 await addToWhiteListExpectFail(bob, collectionId, charlie.address);
105 });105 });
106106
107 it('Execute the extrinsic with parameters: Collection ID and address to add to the white list', async () => {107 it('Execute the extrinsic with parameters: Collection ID and address to add to the white list', async () => {
108 const collectionId = await createCollectionExpectSuccess();108 const collectionId = await createCollectionExpectSuccess();
109 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);109 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
110 await addToWhiteListExpectSuccess(Bob, collectionId, Charlie.address);110 await addToWhiteListExpectSuccess(bob, collectionId, charlie.address);
111 });111 });
112112
113 it('Whitelisted minting: list restrictions', async () => {113 it('Whitelisted minting: list restrictions', async () => {
114 const collectionId = await createCollectionExpectSuccess();114 const collectionId = await createCollectionExpectSuccess();
115 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);115 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
116 await addToWhiteListExpectSuccess(Bob, collectionId, Charlie.address);116 await addToWhiteListExpectSuccess(bob, collectionId, charlie.address);
117117
118 // allowed only for collection owner118 // allowed only for collection owner
119 await enableWhiteListExpectSuccess(Alice, collectionId);119 await enableWhiteListExpectSuccess(alice, collectionId);
120 await enablePublicMintingExpectSuccess(Alice, collectionId);120 await enablePublicMintingExpectSuccess(alice, collectionId);
121121
122 await createItemExpectSuccess(Charlie, collectionId, 'NFT', Charlie.address);122 await createItemExpectSuccess(charlie, collectionId, 'NFT', charlie.address);
123 });123 });
124});124});
125
modifiedtests/src/approve.test.tsdiffbeforeafterboth
17 setCollectionLimitsExpectSuccess,17 setCollectionLimitsExpectSuccess,
18 transferExpectSuccess,18 transferExpectSuccess,
19 addCollectionAdminExpectSuccess,19 addCollectionAdminExpectSuccess,
20 adminApproveFromExpectSuccess,
20} from './util/helpers';21} from './util/helpers';
2122
22chai.use(chaiAsPromised);23chai.use(chaiAsPromised);
2324
24describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {25describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {
25 let Alice: IKeyringPair;26 let alice: IKeyringPair;
26 let Bob: IKeyringPair;27 let bob: IKeyringPair;
27 let Charlie: IKeyringPair;28 let charlie: IKeyringPair;
2829
29 before(async () => {30 before(async () => {
30 await usingApi(async () => {31 await usingApi(async () => {
31 Alice = privateKey('//Alice');32 alice = privateKey('//Alice');
32 Bob = privateKey('//Bob');33 bob = privateKey('//Bob');
33 Charlie = privateKey('//Charlie');34 charlie = privateKey('//Charlie');
34 });35 });
35 });36 });
3637
37 it('Execute the extrinsic and check approvedList', async () => {38 it('Execute the extrinsic and check approvedList', async () => {
38 const nftCollectionId = await createCollectionExpectSuccess();39 const nftCollectionId = await createCollectionExpectSuccess();
39 // nft40 // nft
40 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');41 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
41 await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);42 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
42 // fungible43 // fungible
43 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});44 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
44 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');45 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
45 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);46 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
46 // reFungible47 // reFungible
47 const reFungibleCollectionId =48 const reFungibleCollectionId =
48 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});49 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
49 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');50 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
50 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);51 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
51 });52 });
5253
53 it('Remove approval by using 0 amount', async () => {54 it('Remove approval by using 0 amount', async () => {
54 const nftCollectionId = await createCollectionExpectSuccess();55 const nftCollectionId = await createCollectionExpectSuccess();
55 // nft56 // nft
56 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');57 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1);58 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);
58 await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 0);59 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);
59 // fungible60 // fungible
60 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});61 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
61 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');62 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
62 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1);63 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
63 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 0);64 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
64 // reFungible65 // reFungible
65 const reFungibleCollectionId =66 const reFungibleCollectionId =
66 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});67 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
67 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');68 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
68 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 1);69 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);
69 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 0);70 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);
70 });71 });
7172
72 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {73 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {
73 const collectionId = await createCollectionExpectSuccess();74 const collectionId = await createCollectionExpectSuccess();
74 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);75 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
7576
76 await approveExpectSuccess(collectionId, itemId, Alice, Charlie);77 await adminApproveFromExpectSuccess(collectionId, itemId, alice, bob.address, charlie.address);
77 });78 });
78});79});
7980
80describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => {81describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => {
81 let Alice: IKeyringPair;82 let alice: IKeyringPair;
82 let Bob: IKeyringPair;83 let bob: IKeyringPair;
83 let Charlie: IKeyringPair;84 let charlie: IKeyringPair;
8485
85 before(async () => {86 before(async () => {
86 await usingApi(async () => {87 await usingApi(async () => {
87 Alice = privateKey('//Alice');88 alice = privateKey('//Alice');
88 Bob = privateKey('//Bob');89 bob = privateKey('//Bob');
89 Charlie = privateKey('//Charlie');90 charlie = privateKey('//Charlie');
90 });91 });
91 });92 });
9293
93 it('Approve for a collection that does not exist', async () => {94 it('Approve for a collection that does not exist', async () => {
94 await usingApi(async (api: ApiPromise) => {95 await usingApi(async (api: ApiPromise) => {
95 // nft96 // nft
96 const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;97 const nftCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
97 await approveExpectFail(nftCollectionCount + 1, 1, Alice, Bob);98 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
98 // fungible99 // fungible
99 const fungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;100 const fungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
100 await approveExpectFail(fungibleCollectionCount + 1, 1, Alice, Bob);101 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
101 // reFungible102 // reFungible
102 const reFungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;103 const reFungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
103 await approveExpectFail(reFungibleCollectionCount + 1, 1, Alice, Bob);104 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
104 });105 });
105 });106 });
106107
107 it('Approve for a collection that was destroyed', async () => {108 it('Approve for a collection that was destroyed', async () => {
108 // nft109 // nft
109 const nftCollectionId = await createCollectionExpectSuccess();110 const nftCollectionId = await createCollectionExpectSuccess();
110 await destroyCollectionExpectSuccess(nftCollectionId);111 await destroyCollectionExpectSuccess(nftCollectionId);
111 await approveExpectFail(nftCollectionId, 1, Alice, Bob);112 await approveExpectFail(nftCollectionId, 1, alice, bob);
112 // fungible113 // fungible
113 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});114 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
114 await destroyCollectionExpectSuccess(fungibleCollectionId);115 await destroyCollectionExpectSuccess(fungibleCollectionId);
115 await approveExpectFail(fungibleCollectionId, 1, Alice, Bob);116 await approveExpectFail(fungibleCollectionId, 0, alice, bob);
116 // reFungible117 // reFungible
117 const reFungibleCollectionId =118 const reFungibleCollectionId =
118 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});119 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
119 await destroyCollectionExpectSuccess(reFungibleCollectionId);120 await destroyCollectionExpectSuccess(reFungibleCollectionId);
120 await approveExpectFail(reFungibleCollectionId, 1, Alice, Bob);121 await approveExpectFail(reFungibleCollectionId, 1, alice, bob);
121 });122 });
122123
123 it('Approve transfer of a token that does not exist', async () => {124 it('Approve transfer of a token that does not exist', async () => {
124 // nft125 // nft
125 const nftCollectionId = await createCollectionExpectSuccess();126 const nftCollectionId = await createCollectionExpectSuccess();
126 await approveExpectFail(nftCollectionId, 2, Alice, Bob);127 await approveExpectFail(nftCollectionId, 2, alice, bob);
127 // reFungible128 // reFungible
128 const reFungibleCollectionId =129 const reFungibleCollectionId =
129 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});130 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
130 await approveExpectFail(reFungibleCollectionId, 2, Alice, Bob);131 await approveExpectFail(reFungibleCollectionId, 2, alice, bob);
131 });132 });
132133
133 it('Approve using the address that does not own the approved token', async () => {134 it('Approve using the address that does not own the approved token', async () => {
134 const nftCollectionId = await createCollectionExpectSuccess();135 const nftCollectionId = await createCollectionExpectSuccess();
135 // nft136 // nft
136 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');137 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
137 await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice);138 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);
138 // fungible139 // fungible
139 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});140 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
140 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');141 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
141 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice);142 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);
142 // reFungible143 // reFungible
143 const reFungibleCollectionId =144 const reFungibleCollectionId =
144 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});145 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
145 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');146 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
146 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice);147 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);
147 });148 });
148
149 it('should fail if approved more NFTs than owned', async () => {
150 const nftCollectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
151 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
152 await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1, 'NFT');
153 await approveExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice);
154 await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice);
155 });
156149
157 it('should fail if approved more ReFungibles than owned', async () => {150 it('should fail if approved more ReFungibles than owned', async () => {
158 const nftCollectionId = await createCollectionExpectSuccess({ mode: { type: 'ReFungible' } });151 const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
159 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'ReFungible');152 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');
160 await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 100, 'ReFungible');153 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 100, 'ReFungible');
161 await approveExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice, 100);154 await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 100);
162 await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, 1);155 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 101);
163 });156 });
164157
165 it('should fail if approved more Fungibles than owned', async () => {158 it('should fail if approved more Fungibles than owned', async () => {
166 const nftCollectionId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });159 const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
167 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'Fungible');160 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'Fungible');
168 await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 10, 'Fungible');161 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 10, 'Fungible');
169 await approveExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice, 10);162 await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 10);
170 await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, 1);163 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 11);
171 });164 });
172165
173 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {166 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {
174 const collectionId = await createCollectionExpectSuccess();167 const collectionId = await createCollectionExpectSuccess();
175 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);168 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
176 await setCollectionLimitsExpectSuccess(Alice, collectionId, { ownerCanTransfer: false });169 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});
177170
178 await approveExpectFail(collectionId, itemId, Alice, Charlie);171 await approveExpectFail(collectionId, itemId, alice, charlie);
179 });172 });
180});173});
181174
182describe('Integration Test approve(spender, collection_id, item_id, amount) with collection admin permissions:', () => {175describe('Integration Test approve(spender, collection_id, item_id, amount) with collection admin permissions:', () => {
183 let Alice: IKeyringPair;176 let alice: IKeyringPair;
184 let Bob: IKeyringPair;177 let bob: IKeyringPair;
185 let Charlie: IKeyringPair;178 let charlie: IKeyringPair;
186179
187 before(async () => {180 before(async () => {
188 await usingApi(async () => {181 await usingApi(async () => {
189 Alice = privateKey('//Alice');182 alice = privateKey('//Alice');
190 Bob = privateKey('//Bob');183 bob = privateKey('//Bob');
191 Charlie = privateKey('//Charlie');184 charlie = privateKey('//Charlie');
192 });185 });
193 });186 });
194187
195 it('can be called by collection admin on non-owned item', async () => {188 it('can be called by collection admin on non-owned item', async () => {
196 const collectionId = await createCollectionExpectSuccess();189 const collectionId = await createCollectionExpectSuccess();
197 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);190 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
198191
199 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);192 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
200 await approveExpectSuccess(collectionId, itemId, Bob, Charlie);193 await adminApproveFromExpectSuccess(collectionId, itemId, bob, alice.address, charlie.address);
201 });194 });
202});195});
203196
modifiedtests/src/block-production.test.tsdiffbeforeafterboth
7import { expect } from 'chai';7import {expect} from 'chai';
8import { ApiPromise } from '@polkadot/api';8import {ApiPromise} from '@polkadot/api';
99
10const BlockTimeMs = 12000;10const BLOCK_TIME_MS = 12000;
11const ToleranceMs = 1000;11const TOLERANCE_MS = 3000;
1212
13/* eslint no-async-promise-executor: "off" */13/* eslint no-async-promise-executor: "off" */
14function getBlocks(api: ApiPromise): Promise<number[]> {14function getBlocks(api: ApiPromise): Promise<number[]> {
15 return new Promise<number[]>(async (resolve, reject) => {15 return new Promise<number[]>(async (resolve, reject) => {
16 const blockNumbers: number[] = [];16 const blockNumbers: number[] = [];
17 setTimeout(() => reject('Block production test failed due to timeout.'), BlockTimeMs + ToleranceMs);17 setTimeout(() => reject('Block production test failed due to timeout.'), BLOCK_TIME_MS + TOLERANCE_MS);
18 const unsubscribe = await api.rpc.chain.subscribeNewHeads((head: any) => {18 const unsubscribe = await api.rpc.chain.subscribeNewHeads((head: any) => {
19 blockNumbers.push(head.number.toNumber());19 blockNumbers.push(head.number.toNumber());
20 if(blockNumbers.length >= 2) {20 if(blockNumbers.length >= 2) {
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
13 destroyCollectionExpectSuccess,13 destroyCollectionExpectSuccess,
14 normalizeAccountId,14 normalizeAccountId,
15 addCollectionAdminExpectSuccess,15 addCollectionAdminExpectSuccess,
16 getBalance,
17 isTokenExists,
16} from './util/helpers';18} from './util/helpers';
1719
18import chai from 'chai';20import chai from 'chai';
41 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);43 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);
42 const events = await submitTransactionAsync(alice, tx);44 const events = await submitTransactionAsync(alice, tx);
43 const result = getGenericResult(events);45 const result = getGenericResult(events);
44 // Get the item46
45 const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();
46 // What to expect
47 // tslint:disable-next-line:no-unused-expression
48 expect(result.success).to.be.true;47 expect(result.success).to.be.true;
49 // tslint:disable-next-line:no-unused-expression48 // Get the item
50 expect(item).to.be.null;49 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
51 });50 });
52 });51 });
5352
64 const result = getGenericResult(events);63 const result = getGenericResult(events);
6564
66 // Get alice balance65 // Get alice balance
67 const balance: any = (await api.query.nft.fungibleItemList(collectionId, alice.address)).toJSON();66 const balance = await getBalance(api, collectionId, alice.address, 0);
6867
69 // What to expect68 // What to expect
70 expect(result.success).to.be.true;69 expect(result.success).to.be.true;
71 expect(balance).to.be.not.null;
72 expect(balance.value).to.be.equal(9);70 expect(balance).to.be.equal(9n);
73 });71 });
74 });72 });
7573
84 const result = getGenericResult(events);82 const result = getGenericResult(events);
8583
86 // Get alice balance84 // Get alice balance
87 const balance: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();85 const balance = await getBalance(api, collectionId, alice.address, tokenId);
8886
89 // What to expect87 // What to expect
90 expect(result.success).to.be.true;88 expect(result.success).to.be.true;
91 expect(balance).to.be.null;89 expect(balance).to.be.equal(0n);
92 });90 });
93 });91 });
9492
104 const result1 = getGenericResult(events1);102 const result1 = getGenericResult(events1);
105103
106 // Get balances104 // Get balances
107 const balanceBefore: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();105 const bobBalanceBefore = await getBalance(api, collectionId, bob.address, tokenId);
106 const aliceBalanceBefore = await getBalance(api, collectionId, alice.address, tokenId);
108107
109 // Bob burns his portion108 // Bob burns his portion
110 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);109 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);
111 const events2 = await submitTransactionAsync(bob, tx);110 const events2 = await submitTransactionAsync(bob, tx);
112 const result2 = getGenericResult(events2);111 const result2 = getGenericResult(events2);
113112
114 // Get balances113 // Get balances
115 const balance: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();114 const bobBalanceAfter = await getBalance(api, collectionId, bob.address, tokenId);
115 const aliceBalanceAfter = await getBalance(api, collectionId, alice.address, tokenId);
116 // console.log(balance);116 // console.log(balance);
117117
118 // What to expect before burning118 // What to expect before burning
119 expect(result1.success).to.be.true;119 expect(result1.success).to.be.true;
120 expect(balanceBefore).to.be.not.null;
121 expect(balanceBefore.owner.length).to.be.equal(2);120 expect(aliceBalanceBefore).to.be.equal(99n);
122 expect(balanceBefore.owner[0].owner).to.be.deep.equal(normalizeAccountId(alice.address));
123 expect(balanceBefore.owner[0].fraction).to.be.equal(99);121 expect(bobBalanceBefore).to.be.equal(1n);
124 expect(balanceBefore.owner[1].owner).to.be.deep.equal(normalizeAccountId(bob.address));
125 expect(balanceBefore.owner[1].fraction).to.be.equal(1);
126122
127 // What to expect after burning123 // What to expect after burning
128 expect(result2.success).to.be.true;124 expect(result2.success).to.be.true;
129 expect(balance).to.be.not.null;
130 expect(balance.owner.length).to.be.equal(1);125 expect(aliceBalanceAfter).to.be.equal(99n);
131 expect(balance.owner[0].fraction).to.be.equal(99);126 expect(bobBalanceAfter).to.be.equal(0n);
132 expect(balance.owner[0].owner).to.be.deep.equal(normalizeAccountId(alice.address));
133 });127 });
134128
135 });129 });
149 const createMode = 'NFT';143 const createMode = 'NFT';
150 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});144 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
151 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);145 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
152 await addCollectionAdminExpectSuccess(alice, collectionId, bob);146 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
153147
154 await usingApi(async (api) => {148 await usingApi(async (api) => {
155 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);149 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);
156 const events = await submitTransactionAsync(bob, tx);150 const events = await submitTransactionAsync(bob, tx);
157 const result = getGenericResult(events);151 const result = getGenericResult(events);
158 // Get the item152
159 const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();
160 // What to expect
161 // tslint:disable-next-line:no-unused-expression
162 expect(result.success).to.be.true;153 expect(result.success).to.be.true;
163 // tslint:disable-next-line:no-unused-expression154 // Get the item
164 expect(item).to.be.null;155 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
165 });156 });
166 });157 });
167158
168159 // TODO: burnFrom
169 it('Burn item in Fungible collection', async () => {160 it('Burn item in Fungible collection', async () => {
170 const createMode = 'Fungible';161 const createMode = 'Fungible';
171 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0 }});162 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
172 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens163 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens
173 await addCollectionAdminExpectSuccess(alice, collectionId, bob);164 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
174165
175 await usingApi(async (api) => {166 await usingApi(async (api) => {
176 // Destroy 1 of 10167 // Destroy 1 of 10
179 const result = getGenericResult(events);170 const result = getGenericResult(events);
180171
181 // Get alice balance172 // Get alice balance
182 const balance: any = (await api.query.nft.fungibleItemList(collectionId, alice.address)).toJSON();173 const balance = await getBalance(api, collectionId, alice.address, 0);
183174
184 // What to expect175 // What to expect
185 expect(result.success).to.be.true;176 expect(result.success).to.be.true;
186 expect(balance).to.be.not.null;
187 expect(balance.value).to.be.equal(9);177 expect(balance).to.be.equal(9n);
188 });178 });
189 });179 });
190180
181 // TODO: burnFrom
191 it('Burn item in ReFungible collection', async () => {182 it('Burn item in ReFungible collection', async () => {
192 const createMode = 'ReFungible';183 const createMode = 'ReFungible';
193 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});184 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
194 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);185 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
195 await addCollectionAdminExpectSuccess(alice, collectionId, bob);186 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
196187
197 await usingApi(async (api) => {188 await usingApi(async (api) => {
198 const tx = api.tx.nft.burnFrom(collectionId, normalizeAccountId(alice.address), tokenId, 100);189 const tx = api.tx.nft.burnFrom(collectionId, normalizeAccountId(alice.address), tokenId, 100);
199 const events = await submitTransactionAsync(bob, tx);190 const events = await submitTransactionAsync(bob, tx);
200 const result = getGenericResult(events);191 const result = getGenericResult(events);
201 // Get alice balance192 // Get alice balance
202 const balance: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();
203
204 // What to expect
205 expect(result.success).to.be.true;193 expect(result.success).to.be.true;
194 // Get the item
206 expect(balance).to.be.null;195 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
207 });196 });
208 });197 });
209});198});
254 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);243 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
255244
256 await usingApi(async (api) => {245 await usingApi(async (api) => {
257 const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);246 const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);
258 const badTransaction = async function () {247 const badTransaction = async function () {
259 await submitTransactionExpectFailAsync(bob, tx);248 await submitTransactionExpectFailAsync(bob, tx);
260 };249 };
275 const result1 = getGenericResult(events1);264 const result1 = getGenericResult(events1);
276 expect(result1.success).to.be.true;265 expect(result1.success).to.be.true;
277266
278 const tx = api.tx.nft.transfer(normalizeAccountId(bob.address), collectionId, tokenId, 0);267 const tx = api.tx.nft.transfer(normalizeAccountId(bob.address), collectionId, tokenId, 1);
279 const badTransaction = async function () {268 const badTransaction = async function () {
280 await submitTransactionExpectFailAsync(alice, tx);269 await submitTransactionExpectFailAsync(alice, tx);
281 };270 };
300 await expect(badTransaction()).to.be.rejected;289 await expect(badTransaction()).to.be.rejected;
301290
302 // Get alice balance291 // Get alice balance
303 const balance: any = (await api.query.nft.fungibleItemList(collectionId, alice.address)).toJSON();292 const balance = await getBalance(api, collectionId, alice.address, 0);
304293
305 // What to expect294 // What to expect
306 expect(balance).to.be.not.null;
307 expect(balance.value).to.be.equal(10);295 expect(balance).to.be.equal(10n);
308 });296 });
309297
310 });298 });
modifiedtests/src/change-collection-owner.test.tsdiffbeforeafterboth
34 const alice = privateKey('//Alice');34 const alice = privateKey('//Alice');
35 const bob = privateKey('//Bob');35 const bob = privateKey('//Bob');
3636
37 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();37 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
38 expect(collection.owner).to.be.deep.eq(alice.address);38 expect(collection.owner.toString()).to.be.deep.eq(alice.address);
3939
40 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);40 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
41 await submitTransactionAsync(alice, changeOwnerTx);41 await submitTransactionAsync(alice, changeOwnerTx);
4242
43 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();43 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
44 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(bob.address);44 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(bob.address);
45 });45 });
46 });46 });
47});47});
53 const alice = privateKey('//Alice');53 const alice = privateKey('//Alice');
54 const bob = privateKey('//Bob');54 const bob = privateKey('//Bob');
5555
56 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();56 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
57 expect(collection.owner).to.be.deep.eq(alice.address);57 expect(collection.owner.toString()).to.be.deep.eq(alice.address);
5858
59 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);59 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
60 await submitTransactionAsync(alice, changeOwnerTx);60 await submitTransactionAsync(alice, changeOwnerTx);
6161
62 const badChangeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, alice.address);62 const badChangeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, alice.address);
63 await expect(submitTransactionExpectFailAsync(alice, badChangeOwnerTx)).to.be.rejected;63 await expect(submitTransactionExpectFailAsync(alice, badChangeOwnerTx)).to.be.rejected;
6464
65 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();65 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
66 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(bob.address);66 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(bob.address);
67 });67 });
68 });68 });
6969
74 const bob = privateKey('//Bob');74 const bob = privateKey('//Bob');
75 const charlie = privateKey('//Charlie');75 const charlie = privateKey('//Charlie');
7676
77 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();77 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
78 expect(collection.owner).to.be.deep.eq(alice.address);78 expect(collection.owner.toString()).to.be.deep.eq(alice.address);
7979
80 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);80 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
81 await submitTransactionAsync(alice, changeOwnerTx);81 await submitTransactionAsync(alice, changeOwnerTx);
8282
83 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();83 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
84 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(bob.address);84 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(bob.address);
8585
86 // After changing the owner of the collection, all privileged methods are available to the new owner86 // After changing the owner of the collection, all privileged methods are available to the new owner
87 // The new owner of the collection has access to sponsorship management operations in the collection87 // The new owner of the collection has access to sponsorship management operations in the collection
94 accountTokenOwnershipLimit: 1,94 accountTokenOwnershipLimit: 1,
95 sponsoredMintSize: 1,95 sponsoredMintSize: 1,
96 tokenLimit: 1,96 tokenLimit: 1,
97 sponsorTimeout: 1,97 sponsorTransferTimeout: 1,
98 ownerCanTransfer: true,98 ownerCanTransfer: true,
99 ownerCanDestroy: true,99 ownerCanDestroy: true,
100 };100 };
118 const bob = privateKey('//Bob');118 const bob = privateKey('//Bob');
119 const charlie = privateKey('//Charlie');119 const charlie = privateKey('//Charlie');
120120
121 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();121 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
122 expect(collection.owner).to.be.deep.eq(alice.address);122 expect(collection.owner.toString()).to.be.deep.eq(alice.address);
123123
124 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);124 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
125 await submitTransactionAsync(alice, changeOwnerTx);125 await submitTransactionAsync(alice, changeOwnerTx);
126126
127 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();127 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
128 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(bob.address);128 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(bob.address);
129129
130 const changeOwnerTx2 = api.tx.nft.changeCollectionOwner(collectionId, charlie.address);130 const changeOwnerTx2 = api.tx.nft.changeCollectionOwner(collectionId, charlie.address);
131 await submitTransactionAsync(bob, changeOwnerTx2);131 await submitTransactionAsync(bob, changeOwnerTx2);
132132
133 // ownership lost133 // ownership lost
134 const collectionAfterOwnerChange2: any = (await api.query.nft.collectionById(collectionId)).toJSON();134 const collectionAfterOwnerChange2 = (await api.query.common.collectionById(collectionId)).unwrap();
135 expect(collectionAfterOwnerChange2.owner).to.be.deep.eq(charlie.address);135 expect(collectionAfterOwnerChange2.owner.toString()).to.be.deep.eq(charlie.address);
136 });136 });
137 });137 });
138});138});
147 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);147 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
148 await expect(submitTransactionExpectFailAsync(bob, changeOwnerTx)).to.be.rejected;148 await expect(submitTransactionExpectFailAsync(bob, changeOwnerTx)).to.be.rejected;
149149
150 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();150 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
151 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(alice.address);151 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(alice.address);
152152
153 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)153 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
154 await createCollectionExpectSuccess();154 await createCollectionExpectSuccess();
161 const alice = privateKey('//Alice');161 const alice = privateKey('//Alice');
162 const bob = privateKey('//Bob');162 const bob = privateKey('//Bob');
163163
164 await addCollectionAdminExpectSuccess(alice, collectionId, bob);164 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
165165
166 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);166 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
167 await expect(submitTransactionExpectFailAsync(bob, changeOwnerTx)).to.be.rejected;167 await expect(submitTransactionExpectFailAsync(bob, changeOwnerTx)).to.be.rejected;
168168
169 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();169 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
170 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(alice.address);170 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(alice.address);
171171
172 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)172 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
173 await createCollectionExpectSuccess();173 await createCollectionExpectSuccess();
195 const bob = privateKey('//Bob');195 const bob = privateKey('//Bob');
196 const charlie = privateKey('//Charlie');196 const charlie = privateKey('//Charlie');
197197
198 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();198 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
199 expect(collection.owner).to.be.deep.eq(alice.address);199 expect(collection.owner.toString()).to.be.deep.eq(alice.address);
200200
201 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);201 const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
202 await submitTransactionAsync(alice, changeOwnerTx);202 await submitTransactionAsync(alice, changeOwnerTx);
203203
204 const badChangeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, alice.address);204 const badChangeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, alice.address);
205 await expect(submitTransactionExpectFailAsync(alice, badChangeOwnerTx)).to.be.rejected;205 await expect(submitTransactionExpectFailAsync(alice, badChangeOwnerTx)).to.be.rejected;
206206
207 const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();207 const collectionAfterOwnerChange = (await api.query.common.collectionById(collectionId)).unwrap();
208 expect(collectionAfterOwnerChange.owner).to.be.deep.eq(bob.address);208 expect(collectionAfterOwnerChange.owner.toString()).to.be.deep.eq(bob.address);
209209
210 await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Alice');210 await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Alice');
211 await confirmSponsorshipExpectFailure(collectionId, '//Alice');211 await confirmSponsorshipExpectFailure(collectionId, '//Alice');
215 accountTokenOwnershipLimit: 1,215 accountTokenOwnershipLimit: 1,
216 sponsoredMintSize: 1,216 sponsoredMintSize: 1,
217 tokenLimit: 1,217 tokenLimit: 1,
218 sponsorTimeout: 1,218 sponsorTransferTimeout: 1,
219 ownerCanTransfer: true,219 ownerCanTransfer: true,
220 ownerCanDestroy: true,220 ownerCanDestroy: true,
221 };221 };
modifiedtests/src/check-event/burnItemEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Burn Item event ', () => {18describe('Burn Item event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 const checkSection = 'ItemDestroyed';20 const checkSection = 'ItemDestroyed';
21 const checkTreasury = 'Deposit';21 const checkTreasury = 'Deposit';
22 const checkSystem = 'ExtrinsicSuccess';22 const checkSystem = 'ExtrinsicSuccess';
23 before(async () => {23 before(async () => {
24 await usingApi(async () => {24 await usingApi(async () => {
25 Alice = privateKey('//Alice');25 alice = privateKey('//Alice');
26 });26 });
27 });27 });
28 it('Check event from burnItem(): ', async () => {28 it('Check event from burnItem(): ', async () => {
29 await usingApi(async (api: ApiPromise) => {29 await usingApi(async (api: ApiPromise) => {
30 const collectionID = await createCollectionExpectSuccess();30 const collectionID = await createCollectionExpectSuccess();
31 const itemID = await createItemExpectSuccess(Alice, collectionID, 'NFT');31 const itemID = await createItemExpectSuccess(alice, collectionID, 'NFT');
32 const burnItem = api.tx.nft.burnItem(collectionID, itemID, 1);32 const burnItem = api.tx.nft.burnItem(collectionID, itemID, 1);
33 const events = await submitTransactionAsync(Alice, burnItem);33 const events = await submitTransactionAsync(alice, burnItem);
34 const msg = JSON.stringify(nftEventMessage(events));34 const msg = JSON.stringify(nftEventMessage(events));
35 expect(msg).to.be.contain(checkSection);35 expect(msg).to.be.contain(checkSection);
36 expect(msg).to.be.contain(checkTreasury);36 expect(msg).to.be.contain(checkTreasury);
modifiedtests/src/check-event/createCollectionEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Create collection event ', () => {18describe('Create collection event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 const checkSection = 'CollectionCreated';20 const checkSection = 'CollectionCreated';
21 const checkTreasury = 'Deposit';21 const checkTreasury = 'Deposit';
22 const checkSystem = 'ExtrinsicSuccess';22 const checkSystem = 'ExtrinsicSuccess';
23 before(async () => {23 before(async () => {
24 await usingApi(async () => {24 await usingApi(async () => {
25 Alice = privateKey('//Alice');25 alice = privateKey('//Alice');
26 });26 });
27 });27 });
28 it('Check event from createCollection(): ', async () => {28 it('Check event from createCollection(): ', async () => {
29 await usingApi(async (api: ApiPromise) => {29 await usingApi(async (api: ApiPromise) => {
30 const tx = api.tx.nft.createCollection('0x31', '0x32', '0x33', 'NFT');30 const tx = api.tx.nft.createCollection([0x31], [0x32], '0x33', 'NFT');
31 const events = await submitTransactionAsync(Alice, tx);31 const events = await submitTransactionAsync(alice, tx);
32 const msg = JSON.stringify(nftEventMessage(events));32 const msg = JSON.stringify(nftEventMessage(events));
33 expect(msg).to.be.contain(checkSection);33 expect(msg).to.be.contain(checkSection);
34 expect(msg).to.be.contain(checkTreasury);34 expect(msg).to.be.contain(checkTreasury);
modifiedtests/src/check-event/createItemEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Create Item event ', () => {18describe('Create Item event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 const checkSection = 'ItemCreated';20 const checkSection = 'ItemCreated';
21 const checkTreasury = 'Deposit';21 const checkTreasury = 'Deposit';
22 const checkSystem = 'ExtrinsicSuccess';22 const checkSystem = 'ExtrinsicSuccess';
23 before(async () => {23 before(async () => {
24 await usingApi(async () => {24 await usingApi(async () => {
25 Alice = privateKey('//Alice');25 alice = privateKey('//Alice');
26 });26 });
27 });27 });
28 it('Check event from createItem(): ', async () => {28 it('Check event from createItem(): ', async () => {
29 await usingApi(async (api: ApiPromise) => {29 await usingApi(async (api: ApiPromise) => {
30 const collectionID = await createCollectionExpectSuccess();30 const collectionID = await createCollectionExpectSuccess();
31 const createItem = api.tx.nft.createItem(collectionID, normalizeAccountId(Alice.address), 'NFT');31 const createItem = api.tx.nft.createItem(collectionID, normalizeAccountId(alice.address), 'NFT');
32 const events = await submitTransactionAsync(Alice, createItem);32 const events = await submitTransactionAsync(alice, createItem);
33 const msg = JSON.stringify(nftEventMessage(events));33 const msg = JSON.stringify(nftEventMessage(events));
34 expect(msg).to.be.contain(checkSection);34 expect(msg).to.be.contain(checkSection);
35 expect(msg).to.be.contain(checkTreasury);35 expect(msg).to.be.contain(checkTreasury);
modifiedtests/src/check-event/createMultipleItemsEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Create Multiple Items Event event ', () => {18describe('Create Multiple Items Event event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 const checkSection = 'ItemCreated';20 const checkSection = 'ItemCreated';
21 const checkTreasury = 'Deposit';21 const checkTreasury = 'Deposit';
22 const checkSystem = 'ExtrinsicSuccess';22 const checkSystem = 'ExtrinsicSuccess';
23 before(async () => {23 before(async () => {
24 await usingApi(async () => {24 await usingApi(async () => {
25 Alice = privateKey('//Alice');25 alice = privateKey('//Alice');
26 });26 });
27 });27 });
28 it('Check event from createMultipleItems(): ', async () => {28 it('Check event from createMultipleItems(): ', async () => {
29 await usingApi(async (api: ApiPromise) => {29 await usingApi(async (api: ApiPromise) => {
30 const collectionID = await createCollectionExpectSuccess();30 const collectionID = await createCollectionExpectSuccess();
31 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];31 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
32 const createMultipleItems = api.tx.nft.createMultipleItems(collectionID, normalizeAccountId(Alice.address), args);32 const createMultipleItems = api.tx.nft.createMultipleItems(collectionID, normalizeAccountId(alice.address), args);
33 const events = await submitTransactionAsync(Alice, createMultipleItems);33 const events = await submitTransactionAsync(alice, createMultipleItems);
34 const msg = JSON.stringify(nftEventMessage(events));34 const msg = JSON.stringify(nftEventMessage(events));
35 expect(msg).to.be.contain(checkSection);35 expect(msg).to.be.contain(checkSection);
36 expect(msg).to.be.contain(checkTreasury);36 expect(msg).to.be.contain(checkTreasury);
modifiedtests/src/check-event/destroyCollectionEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Destroy collection event ', () => {18describe('Destroy collection event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 const checkTreasury = 'Deposit';20 const checkTreasury = 'Deposit';
21 const checkSystem = 'ExtrinsicSuccess';21 const checkSystem = 'ExtrinsicSuccess';
22 before(async () => {22 before(async () => {
23 await usingApi(async () => {23 await usingApi(async () => {
24 Alice = privateKey('//Alice');24 alice = privateKey('//Alice');
25 });25 });
26 });26 });
27 it('Check event from destroyCollection(): ', async () => {27 it('Check event from destroyCollection(): ', async () => {
28 await usingApi(async (api: ApiPromise) => {28 await usingApi(async (api: ApiPromise) => {
29 const collectionID = await createCollectionExpectSuccess();29 const collectionID = await createCollectionExpectSuccess();
30 const destroyCollection = api.tx.nft.destroyCollection(collectionID);30 const destroyCollection = api.tx.nft.destroyCollection(collectionID);
31 const events = await submitTransactionAsync(Alice, destroyCollection);31 const events = await submitTransactionAsync(alice, destroyCollection);
32 const msg = JSON.stringify(nftEventMessage(events));32 const msg = JSON.stringify(nftEventMessage(events));
33 expect(msg).to.be.contain(checkTreasury);33 expect(msg).to.be.contain(checkTreasury);
34 expect(msg).to.be.contain(checkSystem);34 expect(msg).to.be.contain(checkSystem);
modifiedtests/src/check-event/transferEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Transfer event ', () => {18describe('Transfer event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 let Bob: IKeyringPair;20 let bob: IKeyringPair;
21 const checkSection = 'Transfer';21 const checkSection = 'Transfer';
22 const checkTreasury = 'Deposit';22 const checkTreasury = 'Deposit';
23 const checkSystem = 'ExtrinsicSuccess';23 const checkSystem = 'ExtrinsicSuccess';
24 before(async () => {24 before(async () => {
25 await usingApi(async () => {25 await usingApi(async () => {
26 Alice = privateKey('//Alice');26 alice = privateKey('//Alice');
27 Bob = privateKey('//Bob');27 bob = privateKey('//Bob');
28 });28 });
29 });29 });
30 it('Check event from transfer(): ', async () => {30 it('Check event from transfer(): ', async () => {
31 await usingApi(async (api: ApiPromise) => {31 await usingApi(async (api: ApiPromise) => {
32 const collectionID = await createCollectionExpectSuccess();32 const collectionID = await createCollectionExpectSuccess();
33 const itemID = await createItemExpectSuccess(Alice, collectionID, 'NFT');33 const itemID = await createItemExpectSuccess(alice, collectionID, 'NFT');
34 const transfer = api.tx.nft.transfer(normalizeAccountId(Bob.address), collectionID, itemID, 1);34 const transfer = api.tx.nft.transfer(normalizeAccountId(bob.address), collectionID, itemID, 1);
35 const events = await submitTransactionAsync(Alice, transfer);35 const events = await submitTransactionAsync(alice, transfer);
36 const msg = JSON.stringify(nftEventMessage(events));36 const msg = JSON.stringify(nftEventMessage(events));
37 expect(msg).to.be.contain(checkSection);37 expect(msg).to.be.contain(checkSection);
38 expect(msg).to.be.contain(checkTreasury);38 expect(msg).to.be.contain(checkTreasury);
modifiedtests/src/check-event/transferFromEvent.test.tsdiffbeforeafterboth
16const expect = chai.expect;16const expect = chai.expect;
1717
18describe('Transfer from event ', () => {18describe('Transfer from event ', () => {
19 let Alice: IKeyringPair;19 let alice: IKeyringPair;
20 let Bob: IKeyringPair;20 let bob: IKeyringPair;
21 const checkSection = 'Transfer';21 const checkSection = 'Transfer';
22 const checkTreasury = 'Deposit';22 const checkTreasury = 'Deposit';
23 const checkSystem = 'ExtrinsicSuccess';23 const checkSystem = 'ExtrinsicSuccess';
24 before(async () => {24 before(async () => {
25 await usingApi(async () => {25 await usingApi(async () => {
26 Alice = privateKey('//Alice');26 alice = privateKey('//Alice');
27 Bob = privateKey('//Bob');27 bob = privateKey('//Bob');
28 });28 });
29 });29 });
30 it('Check event from transferFrom(): ', async () => {30 it('Check event from transferFrom(): ', async () => {
31 await usingApi(async (api: ApiPromise) => {31 await usingApi(async (api: ApiPromise) => {
32 const collectionID = await createCollectionExpectSuccess();32 const collectionID = await createCollectionExpectSuccess();
33 const itemID = await createItemExpectSuccess(Alice, collectionID, 'NFT');33 const itemID = await createItemExpectSuccess(alice, collectionID, 'NFT');
34 const transferFrom = api.tx.nft.transferFrom(normalizeAccountId(Alice.address), normalizeAccountId(Bob.address), collectionID, itemID, 1);34 const transferFrom = api.tx.nft.transferFrom(normalizeAccountId(alice.address), normalizeAccountId(bob.address), collectionID, itemID, 1);
35 const events = await submitTransactionAsync(Alice, transferFrom);35 const events = await submitTransactionAsync(alice, transferFrom);
36 const msg = JSON.stringify(nftEventMessage(events));36 const msg = JSON.stringify(nftEventMessage(events));
37 expect(msg).to.be.contain(checkSection);37 expect(msg).to.be.contain(checkSection);
38 expect(msg).to.be.contain(checkTreasury);38 expect(msg).to.be.contain(checkTreasury);
modifiedtests/src/collision-tests/admVsOwnerChanges.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 createCollectionExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 createItemExpectSuccess,8import privateKey from '../substrate/privateKey';
9 normalizeAccountId,9import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
10 waitNewBlocks,10import {
11} from '../util/helpers';11 createCollectionExpectSuccess,
1212 createItemExpectSuccess,
13chai.use(chaiAsPromised);13 normalizeAccountId,
14const expect = chai.expect;14 waitNewBlocks,
15let Alice: IKeyringPair;15} from '../util/helpers';
16let Bob: IKeyringPair;16
17let Ferdie: IKeyringPair;17chai.use(chaiAsPromised);
1818const expect = chai.expect;
19before(async () => {19let Alice: IKeyringPair;
20 await usingApi(async () => {20let Bob: IKeyringPair;
21 Alice = privateKey('//Alice');21let Ferdie: IKeyringPair;
22 Bob = privateKey('//Bob');22
23 Ferdie = privateKey('//Ferdie');23before(async () => {
24 });24 await usingApi(async () => {
25});25 Alice = privateKey('//Alice');
2626 Bob = privateKey('//Bob');
27describe('Admin vs Owner changes token: ', () => {27 Ferdie = privateKey('//Ferdie');
28 // tslint:disable-next-line: max-line-length28 });
29 it('The collection admin changes the owner of the token and in the same block the current owner transfers the token to another address ', async () => {29});
3030
31 await usingApi(async (api) => {31describe('Admin vs Owner changes token: ', () => {
32 const collectionId = await createCollectionExpectSuccess();32 // tslint:disable-next-line: max-line-length
33 const changeAdminTxBob = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));33 it('The collection admin changes the owner of the token and in the same block the current owner transfers the token to another address ', async () => {
34 await submitTransactionAsync(Alice, changeAdminTxBob);34
35 const changeAdminTxFerdie = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Ferdie.address));35 await usingApi(async (api) => {
36 await submitTransactionAsync(Bob, changeAdminTxFerdie);36 const collectionId = await createCollectionExpectSuccess();
37 const itemId = await createItemExpectSuccess(Ferdie, collectionId, 'NFT');37 const changeAdminTxBob = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
3838 await submitTransactionAsync(Alice, changeAdminTxBob);
39 const changeOwner = api.tx.nft.transferFrom(normalizeAccountId(Ferdie.address), normalizeAccountId(Bob.address), collectionId, itemId, 1);39 const changeAdminTxFerdie = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Ferdie.address));
40 const approve = api.tx.nft.approve(normalizeAccountId(Bob.address), collectionId, itemId, 1);40 await submitTransactionAsync(Bob, changeAdminTxFerdie);
41 const sendItem = api.tx.nft.transfer(normalizeAccountId(Alice.address), collectionId, itemId, 1);41 const itemId = await createItemExpectSuccess(Ferdie, collectionId, 'NFT');
42 await Promise.all([42
43 changeOwner.signAndSend(Alice),43 const changeOwner = api.tx.nft.transferFrom(normalizeAccountId(Ferdie.address), normalizeAccountId(Bob.address), collectionId, itemId, 1);
44 approve.signAndSend(Bob),44 const approve = api.tx.nft.approve(normalizeAccountId(Bob.address), collectionId, itemId, 1);
45 sendItem.signAndSend(Ferdie),45 const sendItem = api.tx.nft.transfer(normalizeAccountId(Alice.address), collectionId, itemId, 1);
46 ]);46 await Promise.all([
47 const itemBefore: any = await api.query.nft.nftItemList(collectionId, itemId);47 changeOwner.signAndSend(Alice),
48 expect(itemBefore.owner).not.to.be.eq(Bob.address);48 approve.signAndSend(Bob),
49 await waitNewBlocks(2);49 sendItem.signAndSend(Ferdie),
50 });50 ]);
51 });51 const itemBefore: any = await api.query.nft.nftItemList(collectionId, itemId);
52});52 expect(itemBefore.owner).not.to.be.eq(Bob.address);
5353 await waitNewBlocks(2);
54 });
55 });
56});
57*/
modifiedtests/src/collision-tests/admVsOwnerData.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 createCollectionExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 createItemExpectSuccess,8import privateKey from '../substrate/privateKey';
9 normalizeAccountId,9import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
10 waitNewBlocks,10import {
11} from '../util/helpers';11 createCollectionExpectSuccess,
1212 createItemExpectSuccess,
13chai.use(chaiAsPromised);13 normalizeAccountId,
14const expect = chai.expect;14 waitNewBlocks,
15let Alice: IKeyringPair;15} from '../util/helpers';
16let Bob: IKeyringPair;16
1717chai.use(chaiAsPromised);
18before(async () => {18const expect = chai.expect;
19 await usingApi(async () => {19let Alice: IKeyringPair;
20 Alice = privateKey('//Alice');20let Bob: IKeyringPair;
21 Bob = privateKey('//Bob');21
22 });22before(async () => {
23});23 await usingApi(async () => {
2424 Alice = privateKey('//Alice');
25describe('Admin vs Owner changes the data in the token: ', () => {25 Bob = privateKey('//Bob');
26 it('The collection admin changes the data in the token and in the same block the token owner also changes the data in it ', async () => {26 });
27 await usingApi(async (api) => {27});
28 const AliceData = 1;28
29 const BobData = 2;29describe('Admin vs Owner changes the data in the token: ', () => {
30 const collectionId = await createCollectionExpectSuccess();30 it('The collection admin changes the data in the token and in the same block the token owner also changes the data in it ', async () => {
31 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));31 await usingApi(async (api) => {
32 await submitTransactionAsync(Alice, changeAdminTx);32 const AliceData = 1;
33 const itemId = await createItemExpectSuccess(Bob, collectionId, 'NFT');33 const BobData = 2;
34 //34 const collectionId = await createCollectionExpectSuccess();
35 // tslint:disable-next-line: max-line-length35 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
36 const AliceTx = api.tx.nft.setVariableMetaData(collectionId, itemId, AliceData.toString());36 await submitTransactionAsync(Alice, changeAdminTx);
37 // tslint:disable-next-line: max-line-length37 const itemId = await createItemExpectSuccess(Bob, collectionId, 'NFT');
38 const BobTx = api.tx.nft.setVariableMetaData(collectionId, itemId, BobData.toString());38 //
39 await Promise.all([39 // tslint:disable-next-line: max-line-length
40 AliceTx.signAndSend(Alice),40 const AliceTx = api.tx.nft.setVariableMetaData(collectionId, itemId, AliceData.toString());
41 BobTx.signAndSend(Bob),41 // tslint:disable-next-line: max-line-length
42 ]);42 const BobTx = api.tx.nft.setVariableMetaData(collectionId, itemId, BobData.toString());
43 const item: any = await api.query.nft.nftItemList(collectionId, itemId);43 await Promise.all([
44 expect(item.variableData).not.to.be.eq(null); // Pseudo-random selection of one of two values44 AliceTx.signAndSend(Alice),
45 await waitNewBlocks(2);45 BobTx.signAndSend(Bob),
46 });46 ]);
47 });47 const item: any = await api.query.nft.nftItemList(collectionId, itemId);
48});48 expect(item.variableData).not.to.be.eq(null); // Pseudo-random selection of one of two values
4949 await waitNewBlocks(2);
50 });
51 });
52});
53*/
modifiedtests/src/collision-tests/admVsOwnerTake.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 createCollectionExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 createItemExpectSuccess,8import privateKey from '../substrate/privateKey';
9 normalizeAccountId,9import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
10 waitNewBlocks,10import {
11} from '../util/helpers';11 createCollectionExpectSuccess,
1212 createItemExpectSuccess,
13chai.use(chaiAsPromised);13 normalizeAccountId,
14const expect = chai.expect;14 waitNewBlocks,
15let Alice: IKeyringPair;15} from '../util/helpers';
16let Bob: IKeyringPair;16
17let Ferdie: IKeyringPair;17chai.use(chaiAsPromised);
1818const expect = chai.expect;
19before(async () => {19let Alice: IKeyringPair;
20 await usingApi(async () => {20let Bob: IKeyringPair;
21 Alice = privateKey('//Alice');21let Ferdie: IKeyringPair;
22 Bob = privateKey('//Bob');22
23 Ferdie = privateKey('//Ferdie');23before(async () => {
24 });24 await usingApi(async () => {
25});25 Alice = privateKey('//Alice');
2626 Bob = privateKey('//Bob');
27describe('Admin vs Owner take token: ', () => {27 Ferdie = privateKey('//Ferdie');
28 // tslint:disable-next-line: max-line-length28 });
29 it('The collection admin burns the token and in the same block the token owner performs a transaction on it ', async () => {29});
30 await usingApi(async (api) => {30
31 const collectionId = await createCollectionExpectSuccess();31describe('Admin vs Owner take token: ', () => {
32 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));32 // tslint:disable-next-line: max-line-length
33 await submitTransactionAsync(Alice, changeAdminTx);33 it('The collection admin burns the token and in the same block the token owner performs a transaction on it ', async () => {
34 const itemId = await createItemExpectSuccess(Bob, collectionId, 'NFT');34 await usingApi(async (api) => {
35 //35 const collectionId = await createCollectionExpectSuccess();
36 const sendItem = api.tx.nft.transfer(normalizeAccountId(Ferdie.address), collectionId, itemId, 1);36 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
37 const burnItem = api.tx.nft.burnItem(collectionId, itemId, 1);37 await submitTransactionAsync(Alice, changeAdminTx);
38 await Promise.all([38 const itemId = await createItemExpectSuccess(Bob, collectionId, 'NFT');
39 sendItem.signAndSend(Bob),39 //
40 burnItem.signAndSend(Alice),40 const sendItem = api.tx.nft.transfer(normalizeAccountId(Ferdie.address), collectionId, itemId, 1);
41 ]);41 const burnItem = api.tx.nft.burnItem(collectionId, itemId, 1);
42 await waitNewBlocks(2);42 await Promise.all([
43 let itemBurn = false;43 sendItem.signAndSend(Bob),
44 itemBurn = (await (api.query.nft.nftItemList(collectionId, itemId))).toJSON() as boolean;44 burnItem.signAndSend(Alice),
45 // tslint:disable-next-line: no-unused-expression45 ]);
46 expect(itemBurn).to.be.null;46 await waitNewBlocks(2);
47 await waitNewBlocks(2);47 let itemBurn = false;
48 });48 itemBurn = (await (api.query.nft.nftItemList(collectionId, itemId))).toJSON() as boolean;
49 });49 // tslint:disable-next-line: no-unused-expression
50});50 expect(itemBurn).to.be.null;
5151 await waitNewBlocks(2);
52 });
53 });
54});
55*/
modifiedtests/src/collision-tests/adminDestroyCollection.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 createCollectionExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 normalizeAccountId,8import privateKey from '../substrate/privateKey';
9 waitNewBlocks,9import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
10} from '../util/helpers';10import {
1111 createCollectionExpectSuccess,
12chai.use(chaiAsPromised);12 normalizeAccountId,
13const expect = chai.expect;13 waitNewBlocks,
14let Alice: IKeyringPair;14} from '../util/helpers';
15let Bob: IKeyringPair;15
16let Ferdie: IKeyringPair;16chai.use(chaiAsPromised);
1717const expect = chai.expect;
18before(async () => {18let Alice: IKeyringPair;
19 await usingApi(async () => {19let Bob: IKeyringPair;
20 Alice = privateKey('//Alice');20let Ferdie: IKeyringPair;
21 Bob = privateKey('//Bob');21
22 Ferdie = privateKey('//Ferdie');22before(async () => {
23 });23 await usingApi(async () => {
24});24 Alice = privateKey('//Alice');
2525 Bob = privateKey('//Bob');
26describe('Deleting a collection while add address to whitelist: ', () => {26 Ferdie = privateKey('//Ferdie');
27 // tslint:disable-next-line: max-line-length27 });
28 it('Adding an address to the collection whitelist in a block by the admin, and deleting the collection by the owner ', async () => {28});
29 await usingApi(async (api) => {29
30 const collectionId = await createCollectionExpectSuccess();30describe('Deleting a collection while add address to whitelist: ', () => {
31 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));31 // tslint:disable-next-line: max-line-length
32 await submitTransactionAsync(Alice, changeAdminTx);32 it('Adding an address to the collection whitelist in a block by the admin, and deleting the collection by the owner ', async () => {
33 await waitNewBlocks(1);33 await usingApi(async (api) => {
34 //34 const collectionId = await createCollectionExpectSuccess();
35 const addWhitelistAdm = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(Ferdie.address));35 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
36 const destroyCollection = api.tx.nft.destroyCollection(collectionId);36 await submitTransactionAsync(Alice, changeAdminTx);
37 await Promise.all([37 await waitNewBlocks(1);
38 addWhitelistAdm.signAndSend(Bob),38 //
39 destroyCollection.signAndSend(Alice),39 const addWhitelistAdm = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(Ferdie.address));
40 ]);40 const destroyCollection = api.tx.nft.destroyCollection(collectionId);
41 await waitNewBlocks(1);41 await Promise.all([
42 let whiteList = false;42 addWhitelistAdm.signAndSend(Bob),
43 whiteList = (await api.query.nft.whiteList(collectionId, Ferdie.address)).toJSON() as boolean;43 destroyCollection.signAndSend(Alice),
44 // tslint:disable-next-line: no-unused-expression44 ]);
45 expect(whiteList).to.be.false;45 await waitNewBlocks(1);
46 await waitNewBlocks(2);46 let whiteList = false;
47 });47 whiteList = (await api.query.nft.whiteList(collectionId, Ferdie.address)).toJSON() as boolean;
48 });48 // tslint:disable-next-line: no-unused-expression
49});49 expect(whiteList).to.be.false;
5050 await waitNewBlocks(2);
51 });
52 });
53});
54*/
modifiedtests/src/collision-tests/adminLimitsOff.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 createCollectionExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 normalizeAccountId,8import privateKey from '../substrate/privateKey';
9 waitNewBlocks,9import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from '../substrate/substrate-api';
10} from '../util/helpers';10import {
1111 createCollectionExpectSuccess,
12chai.use(chaiAsPromised);12 normalizeAccountId,
13const expect = chai.expect;13 waitNewBlocks,
14let Alice: IKeyringPair;14} from '../util/helpers';
15let Bob: IKeyringPair;15
16let Ferdie: IKeyringPair;16chai.use(chaiAsPromised);
17let Charlie: IKeyringPair;17const expect = chai.expect;
18let Eve: IKeyringPair;18let Alice: IKeyringPair;
19let Dave: IKeyringPair;19let Bob: IKeyringPair;
2020let Ferdie: IKeyringPair;
21before(async () => {21let Charlie: IKeyringPair;
22 await usingApi(async () => {22let Eve: IKeyringPair;
23 Alice = privateKey('//Alice');23let Dave: IKeyringPair;
24 Bob = privateKey('//Bob');24
25 Ferdie = privateKey('//Ferdie');25before(async () => {
26 Charlie = privateKey('//Charlie');26 await usingApi(async () => {
27 Eve = privateKey('//Eve');27 Alice = privateKey('//Alice');
28 Dave = privateKey('//Dave');28 Bob = privateKey('//Bob');
29 });29 Ferdie = privateKey('//Ferdie');
30});30 Charlie = privateKey('//Charlie');
3131 Eve = privateKey('//Eve');
32describe('Admin limit exceeded collection: ', () => {32 Dave = privateKey('//Dave');
33 // tslint:disable-next-line: max-line-length33 });
34 it('In one block, the owner and admin add new admins to the collection more than the limit ', async () => {34});
35 await usingApi(async (api) => {35
36 const collectionId = await createCollectionExpectSuccess();36describe('Admin limit exceeded collection: ', () => {
3737 // tslint:disable-next-line: max-line-length
38 const chainAdminLimit = (api.consts.nft.collectionAdminsLimit as any).toNumber();38 it('In one block, the owner and admin add new admins to the collection more than the limit ', async () => {
39 expect(chainAdminLimit).to.be.equal(5);39 await usingApi(async (api) => {
4040 const collectionId = await createCollectionExpectSuccess();
41 const changeAdminTx1 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Eve.address));41
42 await submitTransactionAsync(Alice, changeAdminTx1);42 const chainAdminLimit = (api.consts.nft.collectionAdminsLimit as any).toNumber();
43 const changeAdminTx2 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Dave.address));43 expect(chainAdminLimit).to.be.equal(5);
44 await submitTransactionAsync(Alice, changeAdminTx2);44
45 const changeAdminTx3 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));45 const changeAdminTx1 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Eve.address));
46 await submitTransactionAsync(Alice, changeAdminTx3);46 await submitTransactionAsync(Alice, changeAdminTx1);
4747 const changeAdminTx2 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Dave.address));
48 const addAdmOne = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Ferdie.address));48 await submitTransactionAsync(Alice, changeAdminTx2);
49 const addAdmTwo = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Charlie.address));49 const changeAdminTx3 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
50 await Promise.all([50 await submitTransactionAsync(Alice, changeAdminTx3);
51 addAdmOne.signAndSend(Bob),51
52 addAdmTwo.signAndSend(Alice),52 const addAdmOne = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Ferdie.address));
53 ]);53 const addAdmTwo = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Charlie.address));
54 await waitNewBlocks(2);54 await Promise.all([
55 const changeAdminTx4 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Alice.address));55 addAdmOne.signAndSend(Bob),
56 await expect(submitTransactionExpectFailAsync(Alice, changeAdminTx4)).to.be.rejected;56 addAdmTwo.signAndSend(Alice),
5757 ]);
58 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));58 await waitNewBlocks(2);
59 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(Eve.address));59 const changeAdminTx4 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Alice.address));
60 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(Ferdie.address));60 await expect(submitTransactionExpectFailAsync(Alice, changeAdminTx4)).to.be.rejected;
61 expect(adminListAfterAddAdmin).not.to.be.contains(normalizeAccountId(Alice.address));61
62 await waitNewBlocks(2);62 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));
63 });63 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(Eve.address));
64 });64 expect(adminListAfterAddAdmin).to.be.contains(normalizeAccountId(Ferdie.address));
65});65 expect(adminListAfterAddAdmin).not.to.be.contains(normalizeAccountId(Alice.address));
6666 await waitNewBlocks(2);
67 });
68 });
69});
70*/
modifiedtests/src/collision-tests/adminRightsOff.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import BN from 'bn.js';2// substrate transactions are sequential, not parallel
3import chai from 'chai';3// the order of execution is indeterminate
4import chaiAsPromised from 'chai-as-promised';4
5import privateKey from '../substrate/privateKey';5import { IKeyringPair } from '@polkadot/types/types';
6import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';6import BN from 'bn.js';
7import {7import chai from 'chai';
8 createCollectionExpectSuccess,8import chaiAsPromised from 'chai-as-promised';
9 normalizeAccountId,9import privateKey from '../substrate/privateKey';
10 waitNewBlocks,10import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
11} from '../util/helpers';11import {
1212 createCollectionExpectSuccess,
13chai.use(chaiAsPromised);13 normalizeAccountId,
14const expect = chai.expect;14 waitNewBlocks,
15let Alice: IKeyringPair;15} from '../util/helpers';
16let Bob: IKeyringPair;16
1717chai.use(chaiAsPromised);
18before(async () => {18const expect = chai.expect;
19 await usingApi(async () => {19let Alice: IKeyringPair;
20 Alice = privateKey('//Alice');20let Bob: IKeyringPair;
21 Bob = privateKey('//Bob');21
22 });22before(async () => {
23});23 await usingApi(async () => {
2424 Alice = privateKey('//Alice');
25describe('Deprivation of admin rights: ', () => {25 Bob = privateKey('//Bob');
26 // tslint:disable-next-line: max-line-length26 });
27 it('In the block, the collection admin adds a token or changes data, and the collection owner deprives the admin of rights ', async () => {27});
28 await usingApi(async (api) => {28
29 const collectionId = await createCollectionExpectSuccess();29describe('Deprivation of admin rights: ', () => {
30 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));30 // tslint:disable-next-line: max-line-length
31 await submitTransactionAsync(Alice, changeAdminTx);31 it('In the block, the collection admin adds a token or changes data, and the collection owner deprives the admin of rights ', async () => {
32 await waitNewBlocks(1);32 await usingApi(async (api) => {
33 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];33 const collectionId = await createCollectionExpectSuccess();
34 const addItemAdm = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);34 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
35 const removeAdm = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));35 await submitTransactionAsync(Alice, changeAdminTx);
36 await Promise.all([36 await waitNewBlocks(1);
37 addItemAdm.signAndSend(Bob),37 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];
38 removeAdm.signAndSend(Alice),38 const addItemAdm = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);
39 ]);39 const removeAdm = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
40 await waitNewBlocks(2);40 await Promise.all([
41 const itemsListIndex = await api.query.nft.itemListIndex(collectionId) as unknown as BN;41 addItemAdm.signAndSend(Bob),
42 expect(itemsListIndex.toNumber()).to.be.equal(0);42 removeAdm.signAndSend(Alice),
43 const adminList: any = (await api.query.nft.adminList(collectionId));43 ]);
44 expect(adminList).not.to.be.contains(normalizeAccountId(Bob.address));44 await waitNewBlocks(2);
45 await waitNewBlocks(2);45 const itemsListIndex = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
46 });46 expect(itemsListIndex.toNumber()).to.be.equal(0);
47 });47 const adminList: any = (await api.query.nft.adminList(collectionId));
48});48 expect(adminList).not.to.be.contains(normalizeAccountId(Bob.address));
4949 await waitNewBlocks(2);
50 });
51 });
52});
53*/
modifiedtests/src/collision-tests/setSponsorNewOwner.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 createCollectionExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 setCollectionSponsorExpectSuccess,8import privateKey from '../substrate/privateKey';
9 waitNewBlocks,9import usingApi from '../substrate/substrate-api';
10} from '../util/helpers';10import {
1111 createCollectionExpectSuccess,
12chai.use(chaiAsPromised);12 setCollectionSponsorExpectSuccess,
13const expect = chai.expect;13 waitNewBlocks,
14let Alice: IKeyringPair;14} from '../util/helpers';
15let Bob: IKeyringPair;15
16let Ferdie: IKeyringPair;16chai.use(chaiAsPromised);
1717const expect = chai.expect;
18before(async () => {18let Alice: IKeyringPair;
19 await usingApi(async () => {19let Bob: IKeyringPair;
20 Alice = privateKey('//Alice');20let Ferdie: IKeyringPair;
21 Bob = privateKey('//Bob');21
22 Ferdie = privateKey('//Ferdie');22before(async () => {
23 });23 await usingApi(async () => {
24});24 Alice = privateKey('//Alice');
2525 Bob = privateKey('//Bob');
26describe('Sponsored with new owner ', () => {26 Ferdie = privateKey('//Ferdie');
27 // tslint:disable-next-line: max-line-length27 });
28 it('Confirmation of sponsorship of a collection in a block with a change in the owner of the collection: ', async () => {28});
29 await usingApi(async (api) => {29
30 const collectionId = await createCollectionExpectSuccess();30describe('Sponsored with new owner ', () => {
31 await setCollectionSponsorExpectSuccess(collectionId, Bob.address);31 // tslint:disable-next-line: max-line-length
32 await waitNewBlocks(2);32 it('Confirmation of sponsorship of a collection in a block with a change in the owner of the collection: ', async () => {
33 const confirmSponsorship = api.tx.nft.confirmSponsorship(collectionId);33 await usingApi(async (api) => {
34 const changeCollectionOwner = api.tx.nft.changeCollectionOwner(collectionId, Ferdie.address);34 const collectionId = await createCollectionExpectSuccess();
35 await Promise.all([35 await setCollectionSponsorExpectSuccess(collectionId, Bob.address);
36 confirmSponsorship.signAndSend(Bob),36 await waitNewBlocks(2);
37 changeCollectionOwner.signAndSend(Alice),37 const confirmSponsorship = api.tx.nft.confirmSponsorship(collectionId);
38 ]);38 const changeCollectionOwner = api.tx.nft.changeCollectionOwner(collectionId, Ferdie.address);
39 await waitNewBlocks(2);39 await Promise.all([
40 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();40 confirmSponsorship.signAndSend(Bob),
41 expect(collection.sponsorship.confirmed).to.be.eq(Bob.address);41 changeCollectionOwner.signAndSend(Alice),
42 expect(collection.owner).to.be.eq(Ferdie.address);42 ]);
43 await waitNewBlocks(2);43 await waitNewBlocks(2);
44 });44 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
45 });45 expect(collection.sponsorship.confirmed).to.be.eq(Bob.address);
46});46 expect(collection.owner).to.be.eq(Ferdie.address);
4747 await waitNewBlocks(2);
48 });
49 });
50});
51*/
modifiedtests/src/collision-tests/sponsorPayments.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import { alicesPublicKey, bobsPublicKey } from '../accounts';4
5import getBalance from '../substrate/get-balance';5import { IKeyringPair } from '@polkadot/types/types';
6import privateKey from '../substrate/privateKey';6import chai from 'chai';
7import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';7import chaiAsPromised from 'chai-as-promised';
8import {8import { alicesPublicKey, bobsPublicKey } from '../accounts';
9 confirmSponsorshipExpectSuccess,9import getBalance from '../substrate/get-balance';
10 createCollectionExpectSuccess,10import privateKey from '../substrate/privateKey';
11 createItemExpectSuccess,11import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
12 setCollectionSponsorExpectSuccess,12import {
13 normalizeAccountId,13 confirmSponsorshipExpectSuccess,
14 waitNewBlocks,14 createCollectionExpectSuccess,
15} from '../util/helpers';15 createItemExpectSuccess,
1616 setCollectionSponsorExpectSuccess,
17chai.use(chaiAsPromised);17 normalizeAccountId,
18const expect = chai.expect;18 waitNewBlocks,
19let Alice: IKeyringPair;19} from '../util/helpers';
20let Bob: IKeyringPair;20
2121chai.use(chaiAsPromised);
22before(async () => {22const expect = chai.expect;
23 await usingApi(async () => {23let Alice: IKeyringPair;
24 Alice = privateKey('//Alice');24let Bob: IKeyringPair;
25 Bob = privateKey('//Bob');25
26 });26before(async () => {
27});27 await usingApi(async () => {
2828 Alice = privateKey('//Alice');
29describe('Payment of commission if one block: ', () => {29 Bob = privateKey('//Bob');
30 // tslint:disable-next-line: max-line-length30 });
31 it('Payment of commission if one block contains transactions for payment from the sponsor\'s balance and his (sponsor\'s) exclusion from the collection ', async () => {31});
32 await usingApi(async (api) => {32
33 const collectionId = await createCollectionExpectSuccess();33describe('Payment of commission if one block: ', () => {
34 const changeAdminTxBob = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));34 // tslint:disable-next-line: max-line-length
35 await submitTransactionAsync(Alice, changeAdminTxBob);35 it('Payment of commission if one block contains transactions for payment from the sponsor\'s balance and his (sponsor\'s) exclusion from the collection ', async () => {
36 const itemId = await createItemExpectSuccess(Bob, collectionId, 'NFT');36 await usingApi(async (api) => {
37 await setCollectionSponsorExpectSuccess(collectionId, Bob.address);37 const collectionId = await createCollectionExpectSuccess();
38 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');38 const changeAdminTxBob = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
3939 await submitTransactionAsync(Alice, changeAdminTxBob);
40 const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);40 const itemId = await createItemExpectSuccess(Bob, collectionId, 'NFT');
41 const sendItem = api.tx.nft.transfer(normalizeAccountId(Alice.address), collectionId, itemId, 1);41 await setCollectionSponsorExpectSuccess(collectionId, Bob.address);
42 const revokeSponsor = api.tx.nft.removeCollectionSponsor(collectionId);42 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
43 await Promise.all([43
44 sendItem.signAndSend(Bob),44 const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
45 revokeSponsor.signAndSend(Alice),45 const sendItem = api.tx.nft.transfer(normalizeAccountId(Alice.address), collectionId, itemId, 1);
46 ]);46 const revokeSponsor = api.tx.nft.removeCollectionSponsor(collectionId);
47 const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);47 await Promise.all([
48 // tslint:disable-next-line:no-unused-expression48 sendItem.signAndSend(Bob),
49 expect(alicesBalanceAfter === alicesBalanceBefore).to.be.true;49 revokeSponsor.signAndSend(Alice),
50 // tslint:disable-next-line:no-unused-expression50 ]);
51 expect(bobsBalanceAfter === bobsBalanceBefore).to.be.true;51 const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
52 await waitNewBlocks(2);52 // tslint:disable-next-line:no-unused-expression
53 });53 expect(alicesBalanceAfter === alicesBalanceBefore).to.be.true;
54 });54 // tslint:disable-next-line:no-unused-expression
55});55 expect(bobsBalanceAfter === bobsBalanceBefore).to.be.true;
5656 await waitNewBlocks(2);
57 });
58 });
59});
60*/
modifiedtests/src/collision-tests/tokenLimitsOff.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import BN from 'bn.js';2// substrate transactions are sequential, not parallel
3import chai from 'chai';3// the order of execution is indeterminate
4import chaiAsPromised from 'chai-as-promised';4
5import privateKey from '../substrate/privateKey';5import { IKeyringPair } from '@polkadot/types/types';
6import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';6import BN from 'bn.js';
7import {7import chai from 'chai';
8 addToWhiteListExpectSuccess,8import chaiAsPromised from 'chai-as-promised';
9 createCollectionExpectSuccess,9import privateKey from '../substrate/privateKey';
10 getCreateItemResult,10import usingApi, { submitTransactionAsync } from '../substrate/substrate-api';
11 setMintPermissionExpectSuccess,11import {
12 normalizeAccountId,12 addToWhiteListExpectSuccess,
13 waitNewBlocks,13 createCollectionExpectSuccess,
14} from '../util/helpers';14 getCreateItemResult,
1515 setMintPermissionExpectSuccess,
16chai.use(chaiAsPromised);16 normalizeAccountId,
17const expect = chai.expect;17 waitNewBlocks,
18let Alice: IKeyringPair;18} from '../util/helpers';
19let Bob: IKeyringPair;19
20let Ferdie: IKeyringPair;20chai.use(chaiAsPromised);
2121const expect = chai.expect;
22const accountTokenOwnershipLimit = 4;22let Alice: IKeyringPair;
23const sponsoredMintSize = 4294967295;23let Bob: IKeyringPair;
24const tokenLimit = 4;24let Ferdie: IKeyringPair;
25const sponsorTimeout = 14400;25
26const ownerCanTransfer = false;26const accountTokenOwnershipLimit = 4;
27const ownerCanDestroy = false;27const sponsoredMintSize = 4294967295;
2828const tokenLimit = 4;
29before(async () => {29const sponsorTimeout = 14400;
30 await usingApi(async () => {30const ownerCanTransfer = false;
31 Alice = privateKey('//Alice');31const ownerCanDestroy = false;
32 Bob = privateKey('//Bob');32
33 Ferdie = privateKey('//Ferdie');33before(async () => {
34 });34 await usingApi(async () => {
35});35 Alice = privateKey('//Alice');
3636 Bob = privateKey('//Bob');
37describe('Token limit exceeded collection: ', () => {37 Ferdie = privateKey('//Ferdie');
38 // tslint:disable-next-line: max-line-length38 });
39 it('The number of tokens created in the collection from different addresses exceeds the allowed collection limit ', async () => {39});
40 await usingApi(async (api) => {40
41 const collectionId = await createCollectionExpectSuccess();41describe('Token limit exceeded collection: ', () => {
42 await setMintPermissionExpectSuccess(Alice, collectionId, true);42 // tslint:disable-next-line: max-line-length
43 await addToWhiteListExpectSuccess(Alice, collectionId, Ferdie.address);43 it('The number of tokens created in the collection from different addresses exceeds the allowed collection limit ', async () => {
44 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);44 await usingApi(async (api) => {
45 const setCollectionLim = api.tx.nft.setCollectionLimits(45 const collectionId = await createCollectionExpectSuccess();
46 collectionId,46 await setMintPermissionExpectSuccess(Alice, collectionId, true);
47 {47 await addToWhiteListExpectSuccess(Alice, collectionId, Ferdie.address);
48 accountTokenOwnershipLimit,48 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);
49 sponsoredMintSize,49 const setCollectionLim = api.tx.nft.setCollectionLimits(
50 tokenLimit,50 collectionId,
51 // tslint:disable-next-line: object-literal-sort-keys51 {
52 sponsorTimeout,52 accountTokenOwnershipLimit,
53 ownerCanTransfer,53 sponsoredMintSize,
54 ownerCanDestroy,54 tokenLimit,
55 },55 // tslint:disable-next-line: object-literal-sort-keys
56 );56 sponsorTimeout,
57 const subTx = await submitTransactionAsync(Alice, setCollectionLim);57 ownerCanTransfer,
58 const subTxTesult = getCreateItemResult(subTx);58 ownerCanDestroy,
59 // tslint:disable-next-line:no-unused-expression59 },
60 expect(subTxTesult.success).to.be.true;60 );
61 await waitNewBlocks(2);61 const subTx = await submitTransactionAsync(Alice, setCollectionLim);
6262 const subTxTesult = getCreateItemResult(subTx);
63 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];63 // tslint:disable-next-line:no-unused-expression
64 const mintItemOne = api.tx.nft64 expect(subTxTesult.success).to.be.true;
65 .createMultipleItems(collectionId, normalizeAccountId(Ferdie.address), args);65 await waitNewBlocks(2);
66 const mintItemTwo = api.tx.nft66
67 .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);67 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];
68 await Promise.all([68 const mintItemOne = api.tx.nft
69 mintItemOne.signAndSend(Ferdie),69 .createMultipleItems(collectionId, normalizeAccountId(Ferdie.address), args);
70 mintItemTwo.signAndSend(Bob),70 const mintItemTwo = api.tx.nft
71 ]);71 .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);
72 await waitNewBlocks(2);72 await Promise.all([
73 const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;73 mintItemOne.signAndSend(Ferdie),
74 expect(itemsListIndexAfter.toNumber()).to.be.equal(3);74 mintItemTwo.signAndSend(Bob),
75 // TokenLimit = 4. The first transaction is successful. The second should fail.75 ]);
76 await waitNewBlocks(2);76 await waitNewBlocks(2);
77 });77 const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
78 });78 expect(itemsListIndexAfter.toNumber()).to.be.equal(3);
79});79 // TokenLimit = 4. The first transaction is successful. The second should fail.
80 await waitNewBlocks(2);
81 });
82 });
83});
84*/
8085
modifiedtests/src/collision-tests/turnsOffMinting.test.tsdiffbeforeafterboth
1import { IKeyringPair } from '@polkadot/types/types';1/* broken by design
2import chai from 'chai';2// substrate transactions are sequential, not parallel
3import chaiAsPromised from 'chai-as-promised';3// the order of execution is indeterminate
4import privateKey from '../substrate/privateKey';4
5import usingApi from '../substrate/substrate-api';5import { IKeyringPair } from '@polkadot/types/types';
6import {6import chai from 'chai';
7 addToWhiteListExpectSuccess,7import chaiAsPromised from 'chai-as-promised';
8 createCollectionExpectSuccess,8import privateKey from '../substrate/privateKey';
9 setMintPermissionExpectSuccess,9import usingApi from '../substrate/substrate-api';
10 normalizeAccountId,10import {
11 waitNewBlocks,11 addToWhiteListExpectSuccess,
12} from '../util/helpers';12 createCollectionExpectSuccess,
1313 setMintPermissionExpectSuccess,
14chai.use(chaiAsPromised);14 normalizeAccountId,
15const expect = chai.expect;15 waitNewBlocks,
16let Alice: IKeyringPair;16} from '../util/helpers';
17let Ferdie: IKeyringPair;17
1818chai.use(chaiAsPromised);
19before(async () => {19const expect = chai.expect;
20 await usingApi(async () => {20let Alice: IKeyringPair;
21 Alice = privateKey('//Alice');21let Ferdie: IKeyringPair;
22 Ferdie = privateKey('//Ferdie');22
23 });23before(async () => {
24});24 await usingApi(async () => {
2525 Alice = privateKey('//Alice');
26describe('Turns off minting mode: ', () => {26 Ferdie = privateKey('//Ferdie');
27 // tslint:disable-next-line: max-line-length27 });
28 it('The collection owner turns off minting mode and there are minting transactions in the same block ', async () => {28});
29 await usingApi(async (api) => {29
30 const collectionId = await createCollectionExpectSuccess();30describe('Turns off minting mode: ', () => {
31 await setMintPermissionExpectSuccess(Alice, collectionId, true);31 // tslint:disable-next-line: max-line-length
32 await addToWhiteListExpectSuccess(Alice, collectionId, Ferdie.address);32 it('The collection owner turns off minting mode and there are minting transactions in the same block ', async () => {
3333 await usingApi(async (api) => {
34 const mintItem = api.tx.nft.createItem(collectionId, normalizeAccountId(Ferdie.address), 'NFT');34 const collectionId = await createCollectionExpectSuccess();
35 const offMinting = api.tx.nft.setMintPermission(collectionId, false);35 await setMintPermissionExpectSuccess(Alice, collectionId, true);
36 await Promise.all([36 await addToWhiteListExpectSuccess(Alice, collectionId, Ferdie.address);
37 mintItem.signAndSend(Ferdie),37
38 offMinting.signAndSend(Alice),38 const mintItem = api.tx.nft.createItem(collectionId, normalizeAccountId(Ferdie.address), 'NFT');
39 ]);39 const offMinting = api.tx.nft.setMintPermission(collectionId, false);
40 let itemList = false;40 await Promise.all([
41 itemList = (await (api.query.nft.nftItemList(collectionId, mintItem))).toJSON() as boolean;41 mintItem.signAndSend(Ferdie),
42 // tslint:disable-next-line: no-unused-expression42 offMinting.signAndSend(Alice),
43 expect(itemList).to.be.null;43 ]);
44 await waitNewBlocks(2);44 let itemList = false;
45 });45 itemList = (await (api.query.nft.nftItemList(collectionId, mintItem))).toJSON() as boolean;
46 });46 // tslint:disable-next-line: no-unused-expression
47});47 expect(itemList).to.be.null;
4848 await waitNewBlocks(2);
49 });
50 });
51});
52*/
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
23} from './util/helpers';23} from './util/helpers';
24import { Keyring } from '@polkadot/api';24import {Keyring} from '@polkadot/api';
25import { IKeyringPair } from '@polkadot/types/types';25import {IKeyringPair} from '@polkadot/types/types';
26import { BigNumber } from 'bignumber.js';
2726
28chai.use(chaiAsPromised);27chai.use(chaiAsPromised);
29const expect = chai.expect;28const expect = chai.expect;
67 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');66 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
6867
69 await usingApi(async (api) => {68 await usingApi(async (api) => {
70 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());69 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
7170
72 // Find unused address71 // Find unused address
73 const zeroBalance = await findUnusedAddress(api);72 const zeroBalance = await findUnusedAddress(api);
79 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 0);78 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 0);
80 const events = await submitTransactionAsync(zeroBalance, zeroToAlice);79 const events = await submitTransactionAsync(zeroBalance, zeroToAlice);
81 const result = getGenericResult(events);80 const result = getGenericResult(events);
81 expect(result.success).to.be.true;
8282
83 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());83 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
8484
85 expect(result.success).to.be.true;85 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
86 expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;
87 });86 });
8887
89 });88 });
94 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');93 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
9594
96 await usingApi(async (api) => {95 await usingApi(async (api) => {
97 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());96 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
9897
99 // Find unused address98 // Find unused address
100 const zeroBalance = await findUnusedAddress(api);99 const zeroBalance = await findUnusedAddress(api);
106 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);105 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);
107 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);106 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
108 const result1 = getGenericResult(events1);107 const result1 = getGenericResult(events1);
108 expect(result1.success).to.be.true;
109109
110 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());110 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
111111
112 expect(result1.success).to.be.true;112 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
113 expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;
114 });113 });
115 });114 });
116115
120 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');119 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
121120
122 await usingApi(async (api) => {121 await usingApi(async (api) => {
123 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());122 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
124123
125 // Find unused address124 // Find unused address
126 const zeroBalance = await findUnusedAddress(api);125 const zeroBalance = await findUnusedAddress(api);
133 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);132 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
134 const result1 = getGenericResult(events1);133 const result1 = getGenericResult(events1);
135134
136 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());135 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
137136
138 expect(result1.success).to.be.true;137 expect(result1.success).to.be.true;
139 expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;138 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
140 });139 });
141 });140 });
142141
145 await setCollectionSponsorExpectSuccess(collectionId, bob.address);144 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
146 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');145 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
147146
148 // Enable collection white list 147 // Enable collection white list
149 await enableWhiteListExpectSuccess(alice, collectionId);148 await enableWhiteListExpectSuccess(alice, collectionId);
150149
151 // Enable public minting150 // Enable public minting
152 await enablePublicMintingExpectSuccess(alice, collectionId);151 await enablePublicMintingExpectSuccess(alice, collectionId);
153152
154 // Create Item 153 // Create Item
155 await usingApi(async (api) => {154 await usingApi(async (api) => {
156 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());155 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
157156
158 // Find unused address157 // Find unused address
159 const zeroBalance = await findUnusedAddress(api);158 const zeroBalance = await findUnusedAddress(api);
164 // Mint token using unused address as signer163 // Mint token using unused address as signer
165 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);164 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
166165
167 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());166 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
168167
169 expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;168 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
170 });169 });
171 });170 });
172171
189 const result1 = getGenericResult(events1);188 const result1 = getGenericResult(events1);
190189
191 // Second transfer should fail190 // Second transfer should fail
192 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());191 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
193 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);192 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
194 const badTransaction = async function () { 193 const badTransaction = async function () {
195 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);194 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
196 };195 };
197 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');196 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
198 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());197 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
199198
200 // Try again after Zero gets some balance - now it should succeed199 // Try again after Zero gets some balance - now it should succeed
201 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);200 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
205204
206 expect(result1.success).to.be.true;205 expect(result1.success).to.be.true;
207 expect(result2.success).to.be.true;206 expect(result2.success).to.be.true;
208 expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;207 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
209 });208 });
210 });209 });
211210
225 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);224 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);
226 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);225 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
227 const result1 = getGenericResult(events1);226 const result1 = getGenericResult(events1);
227 expect(result1.success).to.be.true;
228228
229 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());229 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
230 await expect(submitTransactionExpectFailAsync(zeroBalance, zeroToAlice)).to.be.rejected;230 await expect(submitTransactionExpectFailAsync(zeroBalance, zeroToAlice)).to.be.rejected;
231 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());231 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
232232
233 // Try again after Zero gets some balance - now it should succeed233 // Try again after Zero gets some balance - now it should succeed
234 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);234 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
235 await submitTransactionAsync(alice, balancetx);235 await submitTransactionAsync(alice, balancetx);
236 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);236 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
237 const result2 = getGenericResult(events2);237 const result2 = getGenericResult(events2);
238
239 expect(result1.success).to.be.true;
240 expect(result2.success).to.be.true;238 expect(result2.success).to.be.true;
239
241 expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;240 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
242 });241 });
243 });242 });
244243
259 const aliceToZero = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);258 const aliceToZero = api.tx.nft.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);
260 const events1 = await submitTransactionAsync(alice, aliceToZero);259 const events1 = await submitTransactionAsync(alice, aliceToZero);
261 const result1 = getGenericResult(events1);260 const result1 = getGenericResult(events1);
261 expect(result1.success).to.be.true;
262262
263 // Second transfer should fail263 // Second transfer should fail
264 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());264 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
265 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(alice.address), collectionId, itemId, 1);265 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(alice.address), collectionId, itemId, 1);
266 const badTransaction = async function () { 266 const badTransaction = async function () {
267 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);267 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
268 };268 };
269 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');269 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
270 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());270 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
271271
272 // Try again after Zero gets some balance - now it should succeed272 // Try again after Zero gets some balance - now it should succeed
273 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);273 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
274 await submitTransactionAsync(alice, balancetx);274 await submitTransactionAsync(alice, balancetx);
275 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);275 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
276 const result2 = getGenericResult(events2);276 const result2 = getGenericResult(events2);
277
278 expect(result1.success).to.be.true;
279 expect(result2.success).to.be.true;277 expect(result2.success).to.be.true;
278
280 expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;279 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
281 });280 });
282 });281 });
283282
286 await setCollectionSponsorExpectSuccess(collectionId, bob.address);285 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
287 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');286 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
288287
289 // Enable collection white list 288 // Enable collection white list
290 await enableWhiteListExpectSuccess(alice, collectionId);289 await enableWhiteListExpectSuccess(alice, collectionId);
291290
292 // Enable public minting291 // Enable public minting
303 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);302 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
304303
305 // Second mint should fail304 // Second mint should fail
306 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());305 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
307 306
308 const consoleError = console.error;
309 const consoleLog = console.log;
310 console.error = () => {};
311 console.log = () => {};
312 const badTransaction = async function () { 307 const badTransaction = async function () {
313 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);308 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
314 };309 };
315 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');310 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
316 console.error = consoleError;
317 console.log = consoleLog;
318 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());311 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
319312
320 // Try again after Zero gets some balance - now it should succeed313 // Try again after Zero gets some balance - now it should succeed
321 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);314 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
322 await submitTransactionAsync(alice, balancetx);315 await submitTransactionAsync(alice, balancetx);
323 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);316 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
324317
325 expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;318 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
326 });319 });
327 });320 });
328321
342 // Find the collection that never existed335 // Find the collection that never existed
343 let collectionId = 0;336 let collectionId = 0;
344 await usingApi(async (api) => {337 await usingApi(async (api) => {
345 collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;338 collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
346 });339 });
347340
348 await confirmSponsorshipExpectFailure(collectionId, '//Bob');341 await confirmSponsorshipExpectFailure(collectionId, '//Bob');
369 it('(!negative test!) Confirm sponsorship by collection admin', async () => {362 it('(!negative test!) Confirm sponsorship by collection admin', async () => {
370 const collectionId = await createCollectionExpectSuccess();363 const collectionId = await createCollectionExpectSuccess();
371 await setCollectionSponsorExpectSuccess(collectionId, bob.address);364 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
372 await addCollectionAdminExpectSuccess(alice, collectionId, charlie);365 await addCollectionAdminExpectSuccess(alice, collectionId, charlie.address);
373 await confirmSponsorshipExpectFailure(collectionId, '//Charlie');366 await confirmSponsorshipExpectFailure(collectionId, '//Charlie');
374 });367 });
375368
modifiedtests/src/connection.test.tsdiffbeforeafterboth
21 });21 });
2222
23 it('Cannot connect to 255.255.255.255', async () => {23 it('Cannot connect to 255.255.255.255', async () => {
24 const log = console.log;
25 const error = console.error;
26 console.log = function () {};
27 console.error = function () {};
28
29 const neverConnectProvider = new WsProvider('ws://255.255.255.255:9944');24 const neverConnectProvider = new WsProvider('ws://255.255.255.255:9944');
30 await expect((async () => {25 await expect((async () => {
33 }, { provider: neverConnectProvider });28 }, {provider: neverConnectProvider});
34 })()).to.be.eventually.rejected;29 })()).to.be.eventually.rejected;
35
36 console.log = log;
37 console.error = error;
38 });30 });
39});31});
32
modifiedtests/src/contracts.test.tsdiffbeforeafterboth
26 normalizeAccountId,26 normalizeAccountId,
27 isWhitelisted,27 isWhitelisted,
28 transferFromExpectSuccess,28 transferFromExpectSuccess,
29 getTokenOwner,
29} from './util/helpers';30} from './util/helpers';
3031
3132
75 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, contract.address);76 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, contract.address);
76 await submitTransactionAsync(alice, changeAdminTx);77 await submitTransactionAsync(alice, changeAdminTx);
7778
78 const tokenBefore: any = (await api.query.nft.nftItemList(collectionId, tokenId) as any).toJSON();79 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(alice.address));
7980
80 // Transfer81 // Transfer
81 const transferTx = contract.tx.transfer(value, gasLimit, bob.address, collectionId, tokenId, 1);82 const transferTx = contract.tx.transfer(value, gasLimit, bob.address, collectionId, tokenId, 1);
82 const events = await submitTransactionAsync(alice, transferTx);83 const events = await submitTransactionAsync(alice, transferTx);
83 const result = getGenericResult(events);84 const result = getGenericResult(events);
84 const tokenAfter: any = (await api.query.nft.nftItemList(collectionId, tokenId) as any).toJSON();
85
86 // tslint:disable-next-line:no-unused-expression
87 expect(result.success).to.be.true;85 expect(result.success).to.be.true;
88 expect(tokenBefore.owner).to.be.deep.equal(normalizeAccountId(alice.address));86
89 expect(tokenAfter.owner).to.be.deep.equal(normalizeAccountId(bob.address));87 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));
90 });88 });
91 });89 });
9290
107 const result = getGenericResult(events);105 const result = getGenericResult(events);
108 expect(result.success).to.be.true;106 expect(result.success).to.be.true;
109107
110 const tokensAfter: any = (await api.query.nft.nftItemList.entries(collectionId) as any).map((kv: any) => kv[1].toJSON());108 const tokensAfter = (await api.query.nft.nftItemList.entries(collectionId)).map((kv: any) => kv[1].toJSON());
111 expect(tokensAfter).to.be.deep.equal([109 expect(tokensAfter).to.be.deep.equal([
112 {110 {
113 Owner: bob.address,111 owner: bob.address,
114 ConstData: '0x010203',112 constData: '0x010203',
115 VariableData: '0x020304',113 variableData: '0x020304',
116 },114 },
117 ]);115 ]);
118 });116 });
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
55
6import chai from 'chai';6import chai from 'chai';
7import chaiAsPromised from 'chai-as-promised';7import chaiAsPromised from 'chai-as-promised';
8import { default as usingApi } from './substrate/substrate-api';
9import { createCollectionExpectFailure, createCollectionExpectSuccess } from './util/helpers';8import {createCollectionExpectFailure, createCollectionExpectSuccess} from './util/helpers';
109
11chai.use(chaiAsPromised);10chai.use(chaiAsPromised);
12const expect = chai.expect;
1311
14describe('integration test: ext. createCollection():', () => {12describe('integration test: ext. createCollection():', () => {
15 it('Create new NFT collection', async () => {13 it('Create new NFT collection', async () => {
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
44 it('Create new item in NFT collection with collection admin permissions', async () => {44 it('Create new item in NFT collection with collection admin permissions', async () => {
45 const createMode = 'NFT';45 const createMode = 'NFT';
46 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});46 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
47 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob);47 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
48 await createItemExpectSuccess(bob, newCollectionID, createMode);48 await createItemExpectSuccess(bob, newCollectionID, createMode);
49 });49 });
50 it('Create new item in Fungible collection with collection admin permissions', async () => {50 it('Create new item in Fungible collection with collection admin permissions', async () => {
51 const createMode = 'Fungible';51 const createMode = 'Fungible';
52 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});52 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
53 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob);53 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
54 await createItemExpectSuccess(bob, newCollectionID, createMode);54 await createItemExpectSuccess(bob, newCollectionID, createMode);
55 });55 });
56 it('Create new item in ReFungible collection with collection admin permissions', async () => {56 it('Create new item in ReFungible collection with collection admin permissions', async () => {
57 const createMode = 'ReFungible';57 const createMode = 'ReFungible';
58 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});58 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
59 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob);59 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
60 await createItemExpectSuccess(bob, newCollectionID, createMode);60 await createItemExpectSuccess(bob, newCollectionID, createMode);
61 });61 });
62});62});
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
2// This file is subject to the terms and conditions defined in2// This file is subject to the terms and conditions defined in
3// file 'LICENSE', which is part of this source code package.3// file 'LICENSE', which is part of this source code package.
4//4//
5import { ApiPromise } from '@polkadot/api';5import {ApiPromise} from '@polkadot/api';
6import { IKeyringPair } from '@polkadot/types/types';6import {IKeyringPair} from '@polkadot/types/types';
7import BN from 'bn.js';
8import chai from 'chai';7import chai from 'chai';
9import chaiAsPromised from 'chai-as-promised';8import chaiAsPromised from 'chai-as-promised';
10import privateKey from './substrate/privateKey';9import privateKey from './substrate/privateKey';
11import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';10import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
12import {11import {
13 createCollectionExpectSuccess,12 createCollectionExpectSuccess,
14 destroyCollectionExpectSuccess,13 destroyCollectionExpectSuccess,
15 getGenericResult,14 getGenericResult,
16 IFungibleTokenDataType,
17 IReFungibleTokenDataType,
18 normalizeAccountId,15 normalizeAccountId,
19 setCollectionLimitsExpectSuccess,16 setCollectionLimitsExpectSuccess,
20 addCollectionAdminExpectSuccess,17 addCollectionAdminExpectSuccess,
18 getBalance,
19 getTokenOwner,
20 getLastTokenId,
21 getVariableMetadata,
22 getConstMetadata,
21} from './util/helpers';23} from './util/helpers';
2224
23chai.use(chaiAsPromised);25chai.use(chaiAsPromised);
24const expect = chai.expect;26const expect = chai.expect;
2527
26interface ITokenDataType {
27 owner: number[];
28 constData: number[];
29 variableData: number[];
30}
31
32describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {28describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
33 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {29 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
34 await usingApi(async (api: ApiPromise) => {30 await usingApi(async (api: ApiPromise) => {
35 const collectionId = await createCollectionExpectSuccess();31 const collectionId = await createCollectionExpectSuccess();
36 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;32 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
37 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);33 expect(itemsListIndexBefore).to.be.equal(0);
38 const Alice = privateKey('//Alice');34 const alice = privateKey('//Alice');
39 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];35 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
40 const createMultipleItemsTx = api.tx.nft36 const createMultipleItemsTx = api.tx.nft
41 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);37 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
42 await submitTransactionAsync(Alice, createMultipleItemsTx);38 await submitTransactionAsync(alice, createMultipleItemsTx);
43 const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;39 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
44 expect(itemsListIndexAfter.toNumber()).to.be.equal(3);40 expect(itemsListIndexAfter).to.be.equal(3);
45 const token1Data = (await api.query.nft.nftItemList(collectionId, 1)).toJSON() as unknown as ITokenDataType;
46 const token2Data = (await api.query.nft.nftItemList(collectionId, 2)).toJSON() as unknown as ITokenDataType;
47 const token3Data = (await api.query.nft.nftItemList(collectionId, 3)).toJSON() as unknown as ITokenDataType;
4841
49 expect(token1Data.owner).to.be.deep.equal(normalizeAccountId(Alice.address));42 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
50 expect(token2Data.owner).to.be.deep.equal(normalizeAccountId(Alice.address));43 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
51 expect(token3Data.owner).to.be.deep.equal(normalizeAccountId(Alice.address));44 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
5245
53 expect(token1Data.constData.toString()).to.be.equal('0x31');46 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
54 expect(token2Data.constData.toString()).to.be.equal('0x32');47 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
55 expect(token3Data.constData.toString()).to.be.equal('0x33');48 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
5649
57 expect(token1Data.variableData.toString()).to.be.equal('0x31');50 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
58 expect(token2Data.variableData.toString()).to.be.equal('0x32');51 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
59 expect(token3Data.variableData.toString()).to.be.equal('0x33');52 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
60 });53 });
61 });54 });
6255
63 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {56 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
64 await usingApi(async (api: ApiPromise) => {57 await usingApi(async (api: ApiPromise) => {
65 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});58 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
66 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;59 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
67 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);60 expect(itemsListIndexBefore).to.be.equal(0);
68 const Alice = privateKey('//Alice');61 const alice = privateKey('//Alice');
69 const args = [62 const args = [
70 {fungible: { value: 1 }},63 {Fungible: {value: 1}},
71 {fungible: { value: 2 }},64 {Fungible: {value: 2}},
72 {fungible: { value: 3 }},65 {Fungible: {value: 3}},
73 ];66 ];
74 const createMultipleItemsTx = api.tx.nft67 const createMultipleItemsTx = api.tx.nft
75 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);68 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
76 await submitTransactionAsync(Alice, createMultipleItemsTx);69 await submitTransactionAsync(alice, createMultipleItemsTx);
77 const token1Data = (await api.query.nft.fungibleItemList(collectionId, Alice.address) as any).toJSON() as unknown as IFungibleTokenDataType;70 const token1Data = await getBalance(api, collectionId, alice.address, 0);
7871
79 expect(token1Data.value).to.be.equal(6); // 1 + 2 + 372 expect(token1Data).to.be.equal(6n); // 1 + 2 + 3
80 });73 });
81 });74 });
8275
83 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {76 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
84 await usingApi(async (api: ApiPromise) => {77 await usingApi(async (api: ApiPromise) => {
85 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});78 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
86 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;79 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
87 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);80 expect(itemsListIndexBefore).to.be.equal(0);
88 const Alice = privateKey('//Alice');81 const alice = privateKey('//Alice');
89 const args = [82 const args = [
90 {refungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},83 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
91 {refungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},84 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
92 {refungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},85 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
93 ];86 ];
94 const createMultipleItemsTx = api.tx.nft87 const createMultipleItemsTx = api.tx.nft
95 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);88 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
96 await submitTransactionAsync(Alice, createMultipleItemsTx);89 await submitTransactionAsync(alice, createMultipleItemsTx);
97 const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;90 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
98 expect(itemsListIndexAfter.toNumber()).to.be.equal(3);91 expect(itemsListIndexAfter).to.be.equal(3);
99 const token1Data = (await api.query.nft.reFungibleItemList(collectionId, 1) as any).toJSON() as unknown as IReFungibleTokenDataType;
100 const token2Data = (await api.query.nft.reFungibleItemList(collectionId, 2) as any).toJSON() as unknown as IReFungibleTokenDataType;
101 const token3Data = (await api.query.nft.reFungibleItemList(collectionId, 3) as any).toJSON() as unknown as IReFungibleTokenDataType;
10292
103 expect(token1Data.owner[0].owner).to.be.deep.equal(normalizeAccountId(Alice.address));93 expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);
94 expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);
104 expect(token1Data.owner[0].fraction).to.be.equal(1);95 expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);
10596
106 expect(token2Data.owner[0].owner).to.be.deep.equal(normalizeAccountId(Alice.address));97 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
107 expect(token2Data.owner[0].fraction).to.be.equal(1);98 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
99 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
108100
109 expect(token3Data.owner[0].owner).to.be.deep.equal(normalizeAccountId(Alice.address));101 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
110 expect(token3Data.owner[0].fraction).to.be.equal(1);
111
112 expect(token1Data.constData.toString()).to.be.equal('0x31');
113 expect(token2Data.constData.toString()).to.be.equal('0x32');102 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
114 expect(token3Data.constData.toString()).to.be.equal('0x33');
115
116 expect(token1Data.variableData.toString()).to.be.equal('0x31');
117 expect(token2Data.variableData.toString()).to.be.equal('0x32');
118 expect(token3Data.variableData.toString()).to.be.equal('0x33');103 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
119 });104 });
120 });105 });
121106
128 tokenLimit: 2,113 tokenLimit: 2,
129 });114 });
130 const args = [115 const args = [
131 { nft: ['A', 'A'] },116 {NFT: ['A', 'A']},
132 { nft: ['B', 'B'] },117 {NFT: ['B', 'B']},
133 ];118 ];
134 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);119 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
135 const events = await submitTransactionAsync(alice, createMultipleItemsTx);120 const events = await submitTransactionAsync(alice, createMultipleItemsTx);
141126
142describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {127describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {
143128
144 let Alice: IKeyringPair;129 let alice: IKeyringPair;
145 let Bob: IKeyringPair;130 let bob: IKeyringPair;
146131
147 before(async () => {132 before(async () => {
148 await usingApi(async () => {133 await usingApi(async () => {
149 Alice = privateKey('//Alice');134 alice = privateKey('//Alice');
150 Bob = privateKey('//Bob');135 bob = privateKey('//Bob');
151 });136 });
152 });137 });
153138
154 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {139 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
155 await usingApi(async (api: ApiPromise) => {140 await usingApi(async (api: ApiPromise) => {
156 const collectionId = await createCollectionExpectSuccess();141 const collectionId = await createCollectionExpectSuccess();
157 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;142 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
158 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);143 expect(itemsListIndexBefore).to.be.equal(0);
159 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);144 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
160 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];145 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
161 const createMultipleItemsTx = api.tx.nft146 const createMultipleItemsTx = api.tx.nft
162 .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);147 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
163 await submitTransactionAsync(Bob, createMultipleItemsTx);148 await submitTransactionAsync(bob, createMultipleItemsTx);
164 const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;149 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
165 expect(itemsListIndexAfter.toNumber()).to.be.equal(3);150 expect(itemsListIndexAfter).to.be.equal(3);
166 const token1Data = (await api.query.nft.nftItemList(collectionId, 1)).toJSON() as unknown as ITokenDataType;
167 const token2Data = (await api.query.nft.nftItemList(collectionId, 2)).toJSON() as unknown as ITokenDataType;
168 const token3Data = (await api.query.nft.nftItemList(collectionId, 3)).toJSON() as unknown as ITokenDataType;
169151
170 expect(token1Data.owner).to.be.deep.equal(normalizeAccountId(Bob.address));152 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));
171 expect(token2Data.owner).to.be.deep.equal(normalizeAccountId(Bob.address));153 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));
172 expect(token3Data.owner).to.be.deep.equal(normalizeAccountId(Bob.address));154 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));
173155
174 expect(token1Data.constData.toString()).to.be.equal('0x31');156 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
175 expect(token2Data.constData.toString()).to.be.equal('0x32');157 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
176 expect(token3Data.constData.toString()).to.be.equal('0x33');158 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
177159
178 expect(token1Data.variableData.toString()).to.be.equal('0x31');160 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
179 expect(token2Data.variableData.toString()).to.be.equal('0x32');161 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
180 expect(token3Data.variableData.toString()).to.be.equal('0x33');162 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
181 });163 });
182 });164 });
183165
184 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {166 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
185 await usingApi(async (api: ApiPromise) => {167 await usingApi(async (api: ApiPromise) => {
186 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});168 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
187 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;169 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
188 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);170 expect(itemsListIndexBefore).to.be.equal(0);
189 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);171 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
190 const args = [172 const args = [
191 {fungible: { value: 1 }},173 {Fungible: {value: 1}},
192 {fungible: { value: 2 }},174 {Fungible: {value: 2}},
193 {fungible: { value: 3 }},175 {Fungible: {value: 3}},
194 ];176 ];
195 const createMultipleItemsTx = api.tx.nft177 const createMultipleItemsTx = api.tx.nft
196 .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);178 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
197 await submitTransactionAsync(Bob, createMultipleItemsTx);179 await submitTransactionAsync(bob, createMultipleItemsTx);
198 const token1Data = (await api.query.nft.fungibleItemList(collectionId, Bob.address) as any).toJSON() as unknown as IFungibleTokenDataType;180 const token1Data = await getBalance(api, collectionId, bob.address, 0);
199181
200 expect(token1Data.value).to.be.equal(6); // 1 + 2 + 3182 expect(token1Data).to.be.equal(6n); // 1 + 2 + 3
201 });183 });
202 });184 });
203185
204 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {186 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
205 await usingApi(async (api: ApiPromise) => {187 await usingApi(async (api: ApiPromise) => {
206 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});188 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
207 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;189 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
208 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);190 expect(itemsListIndexBefore).to.be.equal(0);
209 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);191 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
210 const args = [192 const args = [
211 {refungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},193 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
212 {refungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},194 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
213 {refungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},195 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
214 ];196 ];
215 const createMultipleItemsTx = api.tx.nft197 const createMultipleItemsTx = api.tx.nft
216 .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);198 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
217 await submitTransactionAsync(Bob, createMultipleItemsTx);199 await submitTransactionAsync(bob, createMultipleItemsTx);
218 const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;200 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
219 expect(itemsListIndexAfter.toNumber()).to.be.equal(3);201 expect(itemsListIndexAfter).to.be.equal(3);
220 const token1Data = (await api.query.nft.reFungibleItemList(collectionId, 1) as any).toJSON() as unknown as IReFungibleTokenDataType;
221 const token2Data = (await api.query.nft.reFungibleItemList(collectionId, 2) as any).toJSON() as unknown as IReFungibleTokenDataType;
222 const token3Data = (await api.query.nft.reFungibleItemList(collectionId, 3) as any).toJSON() as unknown as IReFungibleTokenDataType;
223202
224 expect(token1Data.owner[0].owner).to.be.deep.equal(normalizeAccountId(Bob.address));203 expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);
204 expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);
225 expect(token1Data.owner[0].fraction).to.be.equal(1);205 expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);
226206
227 expect(token2Data.owner[0].owner).to.be.deep.equal(normalizeAccountId(Bob.address));207 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
228 expect(token2Data.owner[0].fraction).to.be.equal(1);208 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
209 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
229210
230 expect(token3Data.owner[0].owner).to.be.deep.equal(normalizeAccountId(Bob.address));211 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
231 expect(token3Data.owner[0].fraction).to.be.equal(1);
232
233 expect(token1Data.constData.toString()).to.be.equal('0x31');
234 expect(token2Data.constData.toString()).to.be.equal('0x32');212 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
235 expect(token3Data.constData.toString()).to.be.equal('0x33');
236
237 expect(token1Data.variableData.toString()).to.be.equal('0x31');
238 expect(token2Data.variableData.toString()).to.be.equal('0x32');
239 expect(token3Data.variableData.toString()).to.be.equal('0x33');213 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
240 });214 });
241 });215 });
242});216});
243217
244describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {218describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
245219
246 let Alice: IKeyringPair;220 let alice: IKeyringPair;
247 let Bob: IKeyringPair;221 let bob: IKeyringPair;
248222
249 before(async () => {223 before(async () => {
250 await usingApi(async () => {224 await usingApi(async () => {
251 Alice = privateKey('//Alice');225 alice = privateKey('//Alice');
252 Bob = privateKey('//Bob');226 bob = privateKey('//Bob');
253 });227 });
254 });228 });
255229
256 it('Regular user cannot create items in active NFT collection', async () => {230 it('Regular user cannot create items in active NFT collection', async () => {
257 await usingApi(async (api: ApiPromise) => {231 await usingApi(async (api: ApiPromise) => {
258 const collectionId = await createCollectionExpectSuccess();232 const collectionId = await createCollectionExpectSuccess();
259 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;233 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
260 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);234 expect(itemsListIndexBefore).to.be.equal(0);
261 const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];235 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
262 const createMultipleItemsTx = api.tx.nft236 const createMultipleItemsTx = api.tx.nft
263 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);237 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
264 await expect(submitTransactionAsync(Bob, createMultipleItemsTx)).to.be.rejected;238 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
265 });239 });
266 });240 });
267241
268 it('Regular user cannot create items in active Fungible collection', async () => {242 it('Regular user cannot create items in active Fungible collection', async () => {
269 await usingApi(async (api: ApiPromise) => {243 await usingApi(async (api: ApiPromise) => {
270 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});244 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
271 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;245 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
272 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);246 expect(itemsListIndexBefore).to.be.equal(0);
273 const args = [247 const args = [
274 {fungible: { value: 1 }},248 {Fungible: {value: 1}},
275 {fungible: { value: 2 }},249 {Fungible: {value: 2}},
276 {fungible: { value: 3 }},250 {Fungible: {value: 3}},
277 ];251 ];
278 const createMultipleItemsTx = api.tx.nft252 const createMultipleItemsTx = api.tx.nft
279 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);253 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
280 await expect(submitTransactionAsync(Bob, createMultipleItemsTx)).to.be.rejected;254 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
281 });255 });
282 });256 });
283257
284 it('Regular user cannot create items in active ReFungible collection', async () => {258 it('Regular user cannot create items in active ReFungible collection', async () => {
285 await usingApi(async (api: ApiPromise) => {259 await usingApi(async (api: ApiPromise) => {
286 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});260 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
287 const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;261 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
288 expect(itemsListIndexBefore.toNumber()).to.be.equal(0);262 expect(itemsListIndexBefore).to.be.equal(0);
289 const args = [263 const args = [
290 {refungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},264 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
291 {refungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},265 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
292 {refungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},266 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
293 ];267 ];
294 const createMultipleItemsTx = api.tx.nft268 const createMultipleItemsTx = api.tx.nft
295 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);269 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
296 await expect(submitTransactionAsync(Bob, createMultipleItemsTx)).to.be.rejected;270 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
297 });271 });
298 });272 });
299273
300 it('Create token with not existing type', async () => {
301 await usingApi(async (api: ApiPromise) => {
302 const collectionId = await createCollectionExpectSuccess();
303 try {
304 const args = [{ invalid: null }, { invalid: null }, { invalid: null }];
305 const createMultipleItemsTx = await api.tx.nft
306 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);
307 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;
308 } catch (e) {
309 // tslint:disable-next-line:no-unused-expression
310 expect(e).to.be.exist;
311 }
312 });
313 });
314
315 it('Create token in not existing collection', async () => {274 it('Create token in not existing collection', async () => {
316 await usingApi(async (api: ApiPromise) => {275 await usingApi(async (api: ApiPromise) => {
317 const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;276 const collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
318 const createMultipleItemsTx = api.tx.nft277 const createMultipleItemsTx = api.tx.nft
319 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), ['NFT', 'NFT', 'NFT']);278 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);
320 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;279 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
321 });280 });
322 });281 });
323282
324 it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {283 it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {
325 await usingApi(async (api: ApiPromise) => {284 await usingApi(async (api: ApiPromise) => {
326 // NFT285 // NFT
327 const collectionId = await createCollectionExpectSuccess();286 const collectionId = await createCollectionExpectSuccess();
328 const Alice = privateKey('//Alice');287 const alice = privateKey('//Alice');
329 const args = [288 const args = [
330 { nft: ['A'.repeat(2049), 'A'.repeat(2049)] },289 {NFT: ['A'.repeat(2049), 'A'.repeat(2049)]},
331 { nft: ['B'.repeat(2049), 'B'.repeat(2049)] },290 {NFT: ['B'.repeat(2049), 'B'.repeat(2049)]},
332 { nft: ['C'.repeat(2049), 'C'.repeat(2049)] },291 {NFT: ['C'.repeat(2049), 'C'.repeat(2049)]},
333 ];292 ];
334 const createMultipleItemsTx = api.tx.nft293 const createMultipleItemsTx = api.tx.nft
335 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);294 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
336 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;295 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
337296
338 // ReFungible297 // ReFungible
339 const collectionIdReFungible =298 const collectionIdReFungible =
340 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});299 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
341 const argsReFungible = [300 const argsReFungible = [
342 { ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10] },301 {ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10]},
343 { ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10] },302 {ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10]},
344 { ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10] },303 {ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10]},
345 ];304 ];
346 const createMultipleItemsTxFungible = api.tx.nft305 const createMultipleItemsTxFungible = api.tx.nft
347 .createMultipleItems(collectionIdReFungible, normalizeAccountId(Alice.address), argsReFungible);306 .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);
348 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTxFungible)).to.be.rejected;307 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;
349 });308 });
350 });309 });
351310
352 it('Create tokens with different types', async () => {311 it('Create tokens with different types', async () => {
353 await usingApi(async (api: ApiPromise) => {312 await usingApi(async (api: ApiPromise) => {
354 const collectionId = await createCollectionExpectSuccess();313 const collectionId = await createCollectionExpectSuccess();
355 const createMultipleItemsTx = api.tx.nft314 const createMultipleItemsTx = api.tx.nft
356 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), ['NFT', 'Fungible', 'ReFungible']);315 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);
357 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;316 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
358 // garbage collection :-D317 // garbage collection :-D
359 await destroyCollectionExpectSuccess(collectionId);318 await destroyCollectionExpectSuccess(collectionId);
360 });319 });
364 await usingApi(async (api: ApiPromise) => {323 await usingApi(async (api: ApiPromise) => {
365 const collectionId = await createCollectionExpectSuccess();324 const collectionId = await createCollectionExpectSuccess();
366 const args = [325 const args = [
367 { nft: ['A', 'A'] },326 {NFT: ['A', 'A']},
368 { nft: ['B', 'B'.repeat(2049)] },327 {NFT: ['B', 'B'.repeat(2049)]},
369 { nft: ['C'.repeat(2049), 'C'] },328 {NFT: ['C'.repeat(2049), 'C']},
370 ];329 ];
371 const createMultipleItemsTx = await api.tx.nft330 const createMultipleItemsTx = await api.tx.nft
372 .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);331 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
373 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;332 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
374 });333 });
375 });334 });
376335
377 it('Fails when minting tokens exceeds collectionLimits amount', async () => {336 it('Fails when minting tokens exceeds collectionLimits amount', async () => {
378 await usingApi(async (api) => {337 await usingApi(async (api) => {
379338
380 const collectionId = await createCollectionExpectSuccess();339 const collectionId = await createCollectionExpectSuccess();
381 await setCollectionLimitsExpectSuccess(Alice, collectionId, {340 await setCollectionLimitsExpectSuccess(alice, collectionId, {
382 tokenLimit: 1,341 tokenLimit: 1,
383 });342 });
384 const args = [343 const args = [
385 { nft: ['A', 'A'] },344 {NFT: ['A', 'A']},
386 { nft: ['B', 'B'] },345 {NFT: ['B', 'B']},
387 ];346 ];
388 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);347 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
389 await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;348 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
390 });349 });
391 });350 });
392});351});
modifiedtests/src/creditFeesToTreasury.test.tsdiffbeforeafterboth
8import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';8import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
9import { alicesPublicKey, bobsPublicKey } from './accounts';9import {alicesPublicKey, bobsPublicKey} from './accounts';
10import privateKey from './substrate/privateKey';10import privateKey from './substrate/privateKey';
11import { BigNumber } from 'bignumber.js';
12import { IKeyringPair } from '@polkadot/types/types';11import {IKeyringPair} from '@polkadot/types/types';
13import { 12import {
14 createCollectionExpectSuccess, 13 createCollectionExpectSuccess,
23chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
24const expect = chai.expect;23const expect = chai.expect;
2524
26const Treasury = '5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z';25const TREASURY = '5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z';
27const saneMinimumFee = 0.05;26const saneMinimumFee = 0.05;
28const saneMaximumFee = 0.5;27const saneMaximumFee = 0.5;
29const createCollectionDeposit = 100;28const createCollectionDeposit = 100;
3029
31let alice: IKeyringPair;30let alice: IKeyringPair;
32let bob: IKeyringPair;31let bob: IKeyringPair;
3332
34// Skip the inflation block pauses if the block is close to inflation block 33// Skip the inflation block pauses if the block is close to inflation block
35// until the inflation happens34// until the inflation happens
36/*eslint no-async-promise-executor: "off"*/35/*eslint no-async-promise-executor: "off"*/
37function skipInflationBlock(api: ApiPromise): Promise<void> {36function skipInflationBlock(api: ApiPromise): Promise<void> {
38 const promise = new Promise<void>(async (resolve) => {37 const promise = new Promise<void>(async (resolve) => {
39 const blockInterval = parseInt((await api.consts.inflation.inflationBlockInterval).toString());38 const blockInterval = (await api.consts.inflation.inflationBlockInterval).toNumber();
40 const unsubscribe = await api.rpc.chain.subscribeNewHeads(head => {39 const unsubscribe = await api.rpc.chain.subscribeNewHeads(head => {
41 const currentBlock = parseInt(head.number.toString());40 const currentBlock = head.number.toNumber();
42 if (currentBlock % blockInterval < blockInterval - 10) {41 if (currentBlock % blockInterval < blockInterval - 10) {
43 unsubscribe();42 unsubscribe();
44 resolve();43 resolve();
64 await skipInflationBlock(api);63 await skipInflationBlock(api);
65 await waitNewBlocks(api, 1);64 await waitNewBlocks(api, 1);
6665
67 const totalBefore = new BigNumber((await api.query.balances.totalIssuance()).toString());66 const totalBefore = (await api.query.balances.totalIssuance()).toBigInt();
6867
69 const alicePrivateKey = privateKey('//Alice');68 const alicePrivateKey = privateKey('//Alice');
70 const amount = new BigNumber(1);69 const amount = 1n;
71 const transfer = api.tx.balances.transfer(bobsPublicKey, amount.toFixed());70 const transfer = api.tx.balances.transfer(bobsPublicKey, amount);
7271
73 const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));72 const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));
7473
75 const totalAfter = new BigNumber((await api.query.balances.totalIssuance()).toString());74 const totalAfter = (await api.query.balances.totalIssuance()).toBigInt();
7675
77 expect(result.success).to.be.true;76 expect(result.success).to.be.true;
78 expect(totalAfter.toFixed()).to.be.equal(totalBefore.toFixed());77 expect(totalAfter).to.be.equal(totalBefore);
79 });78 });
80 });79 });
8180
85 await waitNewBlocks(api, 1);84 await waitNewBlocks(api, 1);
8685
87 const alicePrivateKey = privateKey('//Alice');86 const alicePrivateKey = privateKey('//Alice');
88 const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());87 const treasuryBalanceBefore: bigint = (await api.query.system.account(TREASURY)).data.free.toBigInt();
89 const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());88 const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
9089
91 const amount = new BigNumber(1);90 const amount = 1n;
92 const transfer = api.tx.balances.transfer(bobsPublicKey, amount.toFixed());91 const transfer = api.tx.balances.transfer(bobsPublicKey, amount);
93 const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));92 const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));
9493
95 const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());94 const treasuryBalanceAfter: bigint = (await api.query.system.account(TREASURY)).data.free.toBigInt();
96 const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());95 const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
97 const fee = aliceBalanceBefore.minus(aliceBalanceAfter).minus(amount);96 const fee = aliceBalanceBefore - aliceBalanceAfter - amount;
98 const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);97 const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;
9998
100 expect(result.success).to.be.true;99 expect(result.success).to.be.true;
101 expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed());100 expect(treasuryIncrease).to.be.equal(fee);
102 });101 });
103 });102 });
104103
108 await waitNewBlocks(api, 1);107 await waitNewBlocks(api, 1);
109108
110 const bobPrivateKey = privateKey('//Bob');109 const bobPrivateKey = privateKey('//Bob');
111 const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());110 const treasuryBalanceBefore = (await api.query.system.account(TREASURY)).data.free.toBigInt();
112 const bobBalanceBefore = new BigNumber((await api.query.system.account(bobsPublicKey)).data.free.toString());111 const bobBalanceBefore = (await api.query.system.account(bobsPublicKey)).data.free.toBigInt();
113112
114 const badTx = api.tx.balances.setBalance(alicesPublicKey, 0, 0);113 const badTx = api.tx.balances.setBalance(alicesPublicKey, 0, 0);
115 await expect(submitTransactionExpectFailAsync(bobPrivateKey, badTx)).to.be.rejected;114 await expect(submitTransactionExpectFailAsync(bobPrivateKey, badTx)).to.be.rejected;
116115
117 const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());116 const treasuryBalanceAfter = (await api.query.system.account(TREASURY)).data.free.toBigInt();
118 const bobBalanceAfter = new BigNumber((await api.query.system.account(bobsPublicKey)).data.free.toString());117 const bobBalanceAfter = (await api.query.system.account(bobsPublicKey)).data.free.toBigInt();
119 const fee = bobBalanceBefore.minus(bobBalanceAfter);118 const fee = bobBalanceBefore - bobBalanceAfter;
120 const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);119 const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;
121120
122 expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed());121 expect(treasuryIncrease).to.be.equal(fee);
123 });122 });
124 });123 });
125124
128 await skipInflationBlock(api);127 await skipInflationBlock(api);
129 await waitNewBlocks(api, 1);128 await waitNewBlocks(api, 1);
130129
131 const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());130 const treasuryBalanceBefore = (await api.query.system.account(TREASURY)).data.free.toBigInt();
132 const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());131 const aliceBalanceBefore = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
133132
134 await createCollectionExpectSuccess();133 await createCollectionExpectSuccess();
135134
136 const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());135 const treasuryBalanceAfter = (await api.query.system.account(TREASURY)).data.free.toBigInt();
137 const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());136 const aliceBalanceAfter = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
138 const fee = aliceBalanceBefore.minus(aliceBalanceAfter);137 const fee = aliceBalanceBefore - aliceBalanceAfter;
139 const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);138 const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;
140139
141 expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed());140 expect(treasuryIncrease).to.be.equal(fee);
142 });141 });
143 });142 });
144143
147 await skipInflationBlock(api);146 await skipInflationBlock(api);
148 await waitNewBlocks(api, 1);147 await waitNewBlocks(api, 1);
149148
150 const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());149 const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
151150
152 await createCollectionExpectSuccess();151 await createCollectionExpectSuccess();
153152
154 const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());153 const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
155 const fee = aliceBalanceBefore.minus(aliceBalanceAfter);154 const fee = aliceBalanceBefore - aliceBalanceAfter;
156155
157 expect(fee.dividedBy(1e15).toNumber()).to.be.lessThan(saneMaximumFee + createCollectionDeposit);156 expect(fee / 10n ** 15n < BigInt(Math.ceil(saneMaximumFee + createCollectionDeposit))).to.be.true;
158 expect(fee.dividedBy(1e15).toNumber()).to.be.greaterThan(saneMinimumFee + createCollectionDeposit);157 expect(fee / 10n ** 15n < BigInt(Math.ceil(saneMinimumFee + createCollectionDeposit))).to.be.true;
159 });158 });
160 });159 });
161160
167 const collectionId = await createCollectionExpectSuccess();166 const collectionId = await createCollectionExpectSuccess();
168 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');167 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
169168
170 const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());169 const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
171 await transferExpectSuccess(collectionId, tokenId, alice, bob, 1, 'NFT');170 await transferExpectSuccess(collectionId, tokenId, alice, bob, 1, 'NFT');
172 const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());171 const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
173 const fee = aliceBalanceBefore.minus(aliceBalanceAfter);172 const fee = aliceBalanceBefore - aliceBalanceAfter;
174173
175 // console.log(fee.toString());174 // console.log(fee.toString());
176 const expectedTransferFee = 0.1;175 const expectedTransferFee = 0.1;
177 const tolerance = 0.001;176 const tolerance = 0.001;
178 expect(fee.dividedBy(1e15).minus(expectedTransferFee).abs().toNumber()).to.be.lessThan(tolerance);177 expect(Number(fee) / 1e15 - expectedTransferFee).to.be.lessThan(tolerance);
179 });178 });
180 });179 });
181180
modifiedtests/src/destroyCollection.test.tsdiffbeforeafterboth
46 it('(!negative test!) Destroy a collection that never existed', async () => {46 it('(!negative test!) Destroy a collection that never existed', async () => {
47 await usingApi(async (api) => {47 await usingApi(async (api) => {
48 // Find the collection that never existed48 // Find the collection that never existed
49 const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;49 const collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
50 await destroyCollectionExpectFailure(collectionId);50 await destroyCollectionExpectFailure(collectionId);
51 });51 });
52 });52 });
62 });62 });
63 it('(!negative test!) Destroy a collection using collection admin account', async () => {63 it('(!negative test!) Destroy a collection using collection admin account', async () => {
64 const collectionId = await createCollectionExpectSuccess();64 const collectionId = await createCollectionExpectSuccess();
65 await addCollectionAdminExpectSuccess(alice, collectionId, bob);65 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
66 await destroyCollectionExpectFailure(collectionId, '//Bob');66 await destroyCollectionExpectFailure(collectionId, '//Bob');
67 });67 });
68 it('fails when OwnerCanDestroy == false', async () => {68 it('fails when OwnerCanDestroy == false', async () => {
modifiedtests/src/enableContractSponsoring.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/enableDisableTransfer.test.tsdiffbeforeafterboth
21describe('Enable/Disable Transfers', () => {21describe('Enable/Disable Transfers', () => {
22 it('User can transfer token with enabled transfer flag', async () => {22 it('User can transfer token with enabled transfer flag', async () => {
23 await usingApi(async () => {23 await usingApi(async () => {
24 const Alice = privateKey('//Alice');24 const alice = privateKey('//Alice');
25 const Bob = privateKey('//Bob');25 const bob = privateKey('//Bob');
26 // nft26 // nft
27 const nftCollectionId = await createCollectionExpectSuccess();27 const nftCollectionId = await createCollectionExpectSuccess();
28 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');28 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
2929
30 // explicitely set transfer flag30 // explicitely set transfer flag
31 await setTransferFlagExpectSuccess(Alice, nftCollectionId, true);31 await setTransferFlagExpectSuccess(alice, nftCollectionId, true);
3232
33 await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1);33 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1);
34 });34 });
35 });35 });
3636
37 it('User can\'n transfer token with disabled transfer flag', async () => {37 it('User can\'n transfer token with disabled transfer flag', async () => {
38 await usingApi(async () => {38 await usingApi(async () => {
39 const Alice = privateKey('//Alice');39 const alice = privateKey('//Alice');
40 const Bob = privateKey('//Bob');40 const bob = privateKey('//Bob');
41 // nft41 // nft
42 const nftCollectionId = await createCollectionExpectSuccess();42 const nftCollectionId = await createCollectionExpectSuccess();
43 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');43 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
4444
45 // explicitely set transfer flag45 // explicitely set transfer flag
46 await setTransferFlagExpectSuccess(Alice, nftCollectionId, false);46 await setTransferFlagExpectSuccess(alice, nftCollectionId, false);
4747
48 await transferExpectFailure(nftCollectionId, newNftTokenId, Alice, Bob, 1);48 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
49 });49 });
50 });50 });
51});51});
5252
53describe('Negative Enable/Disable Transfers', () => {53describe('Negative Enable/Disable Transfers', () => {
54 it('Non-owner cannot change transfer flag', async () => {54 it('Non-owner cannot change transfer flag', async () => {
55 await usingApi(async () => {55 await usingApi(async () => {
56 const Bob = privateKey('//Bob');56 const bob = privateKey('//Bob');
57 // nft57 // nft
58 const nftCollectionId = await createCollectionExpectSuccess();58 const nftCollectionId = await createCollectionExpectSuccess();
5959
60 // Change transfer flag60 // Change transfer flag
61 await setTransferFlagExpectFailure(Bob, nftCollectionId, false);61 await setTransferFlagExpectFailure(bob, nftCollectionId, false);
62 });62 });
63 });63 });
64});64});
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
1import { expect } from 'chai';1import {expect} from 'chai';
2import waitNewBlocks from '../substrate/wait-new-blocks';
3import { contractHelpers, createEthAccount, createEthAccountWithBalance, deployFlipper, itWeb3, usingWeb3Http } from './util/helpers';2import {contractHelpers, createEthAccount, createEthAccountWithBalance, deployFlipper, itWeb3} from './util/helpers';
43
5describe('EVM allowlist', () => {4describe('EVM allowlist', () => {
6 itWeb3('Contract allowlist can be toggled', async ({ api }) => {5 itWeb3('Contract allowlist can be toggled', async ({api, web3}) => {
7 await usingWeb3Http(async web3Http => {6 const owner = await createEthAccountWithBalance(api, web3);
8 const owner = await createEthAccountWithBalance(api, web3Http);7 const flipper = await deployFlipper(web3, owner);
9 const flipper = await deployFlipper(web3Http, owner);8 const randomUser = createEthAccount(web3);
10 await waitNewBlocks(api, 1);9
11 const randomUser = createEthAccount(web3Http);10 const helpers = contractHelpers(web3, owner);
12
13 const helpers = contractHelpers(web3Http, owner);
1411
15 // Any user is allowed by default12 // Any user is allowed by default
16 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;13 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;
17 expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.true;14 expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.true;
18 await waitNewBlocks(api, 1);
1915
20 // Enable16 // Enable
21 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });17 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});
22 await waitNewBlocks(api, 1);
23 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.true;18 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.true;
24 expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.false;19 expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.false;
2520
26 // Disable21 // Disable
27 await helpers.methods.toggleAllowlist(flipper.options.address, false).send({ from: owner });22 await helpers.methods.toggleAllowlist(flipper.options.address, false).send({from: owner});
28 await waitNewBlocks(api, 1);
29 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;23 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;
30 expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.true;24 expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.true;
31 });
32 });25 });
3326
34 itWeb3('Non-whitelisted user can\'t call contract with allowlist enabled', async ({ api }) => {27 itWeb3('Non-whitelisted user can\'t call contract with allowlist enabled', async ({api, web3}) => {
35 await usingWeb3Http(async web3Http => {28 const owner = await createEthAccountWithBalance(api, web3);
36 const owner = await createEthAccountWithBalance(api, web3Http);29 const flipper = await deployFlipper(web3, owner);
37 const flipper = await deployFlipper(web3Http, owner);30 const caller = await createEthAccountWithBalance(api, web3);
38 await waitNewBlocks(api, 1);31
39 const caller = await createEthAccountWithBalance(api, web3Http);32 const helpers = contractHelpers(web3, owner);
40
41 const helpers = contractHelpers(web3Http, owner);
4233
43 // User can flip with allowlist disabled34 // User can flip with allowlist disabled
44 await flipper.methods.flip().send({ from: caller });35 await flipper.methods.flip().send({from: caller});
45 await waitNewBlocks(api, 1);
46 expect(await flipper.methods.getValue().call()).to.be.true;36 expect(await flipper.methods.getValue().call()).to.be.true;
4737
48 // Tx will be reverted if user is not in whitelist38 // Tx will be reverted if user is not in whitelist
49 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });39 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});
50 await expect(flipper.methods.flip().send({ from: caller })).to.rejected;40 await expect(flipper.methods.flip().send({from: caller})).to.rejected;
51 await waitNewBlocks(api, 1);
52 expect(await flipper.methods.getValue().call()).to.be.true;41 expect(await flipper.methods.getValue().call()).to.be.true;
5342
54 // Adding caller to allowlist will make contract callable again43 // Adding caller to allowlist will make contract callable again
55 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});44 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});
56 await flipper.methods.flip().send({ from: caller });45 await flipper.methods.flip().send({from: caller});
57 await waitNewBlocks(api, 1);
58 expect(await flipper.methods.getValue().call()).to.be.false;46 expect(await flipper.methods.getValue().call()).to.be.false;
59 });
60 });47 });
61});48});
49
modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
6describe('Contract calls', () => {6describe('Contract calls', () => {
7 itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({ web3, api }) => {7 itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => {
8 const deployer = await createEthAccountWithBalance(api, web3);8 const deployer = await createEthAccountWithBalance(api, web3);
9 const flipper = await deployFlipper(web3 as any, deployer);9 const flipper = await deployFlipper(web3, deployer);
1010
11 const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer}));11 const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer}));
12 expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;12 expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
11 transferBalanceToEth,11 transferBalanceToEth,
12 deployFlipper,12 deployFlipper,
13 itWeb3 } from './util/helpers';13 itWeb3} from './util/helpers';
14import waitNewBlocks from '../substrate/wait-new-blocks';
1514
16describe('Sponsoring EVM contracts', () => {15describe('Sponsoring EVM contracts', () => {
17 itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3}) => {16 itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3}) => {
18 const owner = await createEthAccountWithBalance(api, web3);17 const owner = await createEthAccountWithBalance(api, web3);
19 const flipper = await deployFlipper(web3, owner);18 const flipper = await deployFlipper(web3, owner);
20 await waitNewBlocks(api, 1);
21 const helpers = contractHelpers(web3, owner);19 const helpers = contractHelpers(web3, owner);
22 await waitNewBlocks(api, 1);
23 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;20 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
24 await waitNewBlocks(api, 1);
25 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});21 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
26 await waitNewBlocks(api, 1);
27 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;22 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
28 });23 });
2924
30 itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3}) => {25 itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3}) => {
31 const owner = await createEthAccountWithBalance(api, web3);26 const owner = await createEthAccountWithBalance(api, web3);
32 const notOwner = await createEthAccountWithBalance(api, web3);27 const notOwner = await createEthAccountWithBalance(api, web3);
33 const flipper = await deployFlipper(web3, owner);28 const flipper = await deployFlipper(web3, owner);
34 await waitNewBlocks(api, 1);
35 const helpers = contractHelpers(web3, owner);29 const helpers = contractHelpers(web3, owner);
36 await waitNewBlocks(api, 1);
37 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;30 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
38 await waitNewBlocks(api, 1);
39 await expect(helpers.methods.toggleSponsoring(notOwner, true).send({from: notOwner})).to.rejected;31 await expect(helpers.methods.toggleSponsoring(notOwner, true).send({from: notOwner})).to.rejected;
40 await waitNewBlocks(api, 1);
41 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;32 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
42 });33 });
4334
48 const caller = await createEthAccountWithBalance(api, web3);39 const caller = await createEthAccountWithBalance(api, web3);
4940
50 const flipper = await deployFlipper(web3, owner);41 const flipper = await deployFlipper(web3, owner);
51 await waitNewBlocks(api, 1);42
52
53 const helpers = contractHelpers(web3, owner);43 const helpers = contractHelpers(web3, owner);
54 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });44 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});
55 await waitNewBlocks(api, 1);
56 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner });45 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});
57 await waitNewBlocks(api, 1);
5846
59 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;47 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
60 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});48 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
61 await waitNewBlocks(api, 1);
62 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});49 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});
63 await waitNewBlocks(api, 1);
64 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;50 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
6551
66 await transferBalanceToEth(api, alice, flipper.options.address);52 await transferBalanceToEth(api, alice, flipper.options.address);
67 await waitNewBlocks(api, 2);
6853
69 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);54 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
70 expect(originalFlipperBalance).to.be.not.equal('0');55 expect(originalFlipperBalance).to.be.not.equal('0');
7156
72 await flipper.methods.flip().send({ from: caller });57 await flipper.methods.flip().send({from: caller});
73 await waitNewBlocks(api, 1);
74 expect(await flipper.methods.getValue().call()).to.be.true;58 expect(await flipper.methods.getValue().call()).to.be.true;
7559
76 // Balance should be taken from flipper instead of caller60 // Balance should be taken from flipper instead of caller
85 const caller = await createEthAccountWithBalance(api, web3);69 const caller = await createEthAccountWithBalance(api, web3);
8670
87 const flipper = await deployFlipper(web3, owner);71 const flipper = await deployFlipper(web3, owner);
88 await waitNewBlocks(api, 1);72
89
90 const helpers = contractHelpers(web3, owner);73 const helpers = contractHelpers(web3, owner);
9174
92 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;75 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
93 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});76 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
94 await waitNewBlocks(api, 1);
95 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});77 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});
96 await waitNewBlocks(api, 1);
97 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;78 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
9879
99 await transferBalanceToEth(api, alice, flipper.options.address);80 await transferBalanceToEth(api, alice, flipper.options.address);
100 await waitNewBlocks(api, 2);
10181
102 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);82 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
103 expect(originalFlipperBalance).to.be.not.equal('0');83 expect(originalFlipperBalance).to.be.not.equal('0');
10484
105 await flipper.methods.flip().send({ from: caller });85 await flipper.methods.flip().send({from: caller});
106 await waitNewBlocks(api, 1);
107 expect(await flipper.methods.getValue().call()).to.be.true;86 expect(await flipper.methods.getValue().call()).to.be.true;
10887
109 // Balance should be taken from flipper instead of caller88 // Balance should be taken from flipper instead of caller
119 const originalCallerBalance = await web3.eth.getBalance(caller);98 const originalCallerBalance = await web3.eth.getBalance(caller);
12099
121 const flipper = await deployFlipper(web3, owner);100 const flipper = await deployFlipper(web3, owner);
122 await waitNewBlocks(api, 1);101
123
124 const helpers = contractHelpers(web3, owner);102 const helpers = contractHelpers(web3, owner);
125 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });103 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});
126 await waitNewBlocks(api, 1);
127 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner });104 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});
128 await waitNewBlocks(api, 1);
129105
130 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;106 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
131 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});107 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
132 await waitNewBlocks(api, 1);
133 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});108 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});
134 await waitNewBlocks(api, 1);
135 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;109 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
136110
137 await transferBalanceToEth(api, alice, flipper.options.address);111 await transferBalanceToEth(api, alice, flipper.options.address);
138 await waitNewBlocks(api, 2);
139112
140 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);113 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
141 expect(originalFlipperBalance).to.be.not.equal('0');114 expect(originalFlipperBalance).to.be.not.equal('0');
142115
143 await flipper.methods.flip().send({ from: caller });116 await flipper.methods.flip().send({from: caller});
144 await waitNewBlocks(api, 1);
145 expect(await flipper.methods.getValue().call()).to.be.true;117 expect(await flipper.methods.getValue().call()).to.be.true;
146118
147 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);119 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);
155 const originalCallerBalance = await web3.eth.getBalance(caller);127 const originalCallerBalance = await web3.eth.getBalance(caller);
156128
157 const flipper = await deployFlipper(web3, owner);129 const flipper = await deployFlipper(web3, owner);
158 await waitNewBlocks(api, 1);130
159
160 const helpers = contractHelpers(web3, owner);131 const helpers = contractHelpers(web3, owner);
161 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });132 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});
162 await waitNewBlocks(api, 1);
163 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner });133 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});
164 await waitNewBlocks(api, 1);
165134
166 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;135 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
167 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});136 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
168 await waitNewBlocks(api, 1);
169 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});137 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});
170 await waitNewBlocks(api, 1);
171 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;138 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
172139
173 await transferBalanceToEth(api, alice, flipper.options.address);140 await transferBalanceToEth(api, alice, flipper.options.address);
174 await waitNewBlocks(api, 2);
175141
176 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);142 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
177 expect(originalFlipperBalance).to.be.not.equal('0');143 expect(originalFlipperBalance).to.be.not.equal('0');
178144
179 await flipper.methods.flip().send({ from: caller });145 await flipper.methods.flip().send({from: caller});
180 await waitNewBlocks(api, 1);
181 expect(await flipper.methods.getValue().call()).to.be.true;146 expect(await flipper.methods.getValue().call()).to.be.true;
182 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);147 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);
183148
184 await flipper.methods.flip().send({ from: caller });149 await flipper.methods.flip().send({from: caller});
185 await waitNewBlocks(api, 1);
186 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);150 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);
187 });151 });
188152
189 // TODO: Find a way to calculate default rate limit 153 // TODO: Find a way to calculate default rate limit
190 itWeb3('Default rate limit equals 7200', async ({api, web3}) => {154 itWeb3('Default rate limit equals 7200', async ({api, web3}) => {
191 const owner = await createEthAccountWithBalance(api, web3);155 const owner = await createEthAccountWithBalance(api, web3);
192 const flipper = await deployFlipper(web3, owner);156 const flipper = await deployFlipper(web3, owner);
193 await waitNewBlocks(api, 1);
194 const helpers = contractHelpers(web3, owner);157 const helpers = contractHelpers(web3, owner);
195 await waitNewBlocks(api, 1);
196 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');158 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');
197 });159 });
198160
203 const caller = await createEthAccountWithBalance(api, web3);165 const caller = await createEthAccountWithBalance(api, web3);
204166
205 const flipper = await deployFlipper(web3, owner);167 const flipper = await deployFlipper(web3, owner);
206 await waitNewBlocks(api, 1);168
207
208 const helpers = contractHelpers(web3, owner);169 const helpers = contractHelpers(web3, owner);
209170
210 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;171 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
211 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});172 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
212 await waitNewBlocks(api, 1);
213 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});173 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});
214 await waitNewBlocks(api, 1);
215 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;174 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
216175
217 await transferBalanceToEth(api, alice, flipper.options.address);176 await transferBalanceToEth(api, alice, flipper.options.address);
218 await waitNewBlocks(api, 2);
219177
220 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);178 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
221 expect(originalFlipperBalance).to.be.not.equal('0');179 expect(originalFlipperBalance).to.be.not.equal('0');
222180
223 await flipper.methods.flip().send({ from: caller });181 await flipper.methods.flip().send({from: caller});
224 await waitNewBlocks(api, 1);
225 expect(await flipper.methods.getValue().call()).to.be.true;182 expect(await flipper.methods.getValue().call()).to.be.true;
226183
227 // Balance should be taken from flipper instead of caller184 // Balance should be taken from flipper instead of caller
modifiedtests/src/eth/crossTransfer.test.tsdiffbeforeafterboth
25 const alice = privateKey('//Alice');25 const alice = privateKey('//Alice');
26 const bob = privateKey('//Bob');26 const bob = privateKey('//Bob');
27 const charlie = privateKey('//Charlie');27 const charlie = privateKey('//Charlie');
28 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { substrate: alice.address });28 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});
29 await transferExpectSuccess(collection, 0, alice, {ethereum: subToEth(charlie.address)} , 200, 'Fungible');29 await transferExpectSuccess(collection, 0, alice, {Ethereum: subToEth(charlie.address)} , 200, 'Fungible');
30 await transferFromExpectSuccess(collection, 0, alice, {ethereum: subToEth(charlie.address)}, charlie, 50, 'Fungible');30 await transferFromExpectSuccess(collection, 0, alice, {Ethereum: subToEth(charlie.address)}, charlie, 50, 'Fungible');
31 await transferExpectSuccess(collection, 0, charlie, bob, 50, 'Fungible');31 await transferExpectSuccess(collection, 0, charlie, bob, 50, 'Fungible');
32 });32 });
3333
42 const aliceProxy = await createEthAccountWithBalance(api, web3);42 const aliceProxy = await createEthAccountWithBalance(api, web3);
4343
44 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, alice.address);44 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, alice.address);
45 await transferExpectSuccess(collection, 0, alice, { ethereum: aliceProxy } , 200, 'Fungible');45 await transferExpectSuccess(collection, 0, alice, {Ethereum: aliceProxy} , 200, 'Fungible');
46 const address = collectionIdToAddress(collection);46 const address = collectionIdToAddress(collection);
47 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: aliceProxy, ...GAS_ARGS});47 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: aliceProxy, ...GAS_ARGS});
4848
49 await contract.methods.transfer(bobProxy, 50).send({ from: aliceProxy });49 await contract.methods.transfer(bobProxy, 50).send({from: aliceProxy});
50 await transferFromExpectSuccess(collection, 0, alice, {ethereum: bobProxy}, bob, 50, 'Fungible');50 await transferFromExpectSuccess(collection, 0, alice, {Ethereum: bobProxy}, bob, 50, 'Fungible');
51 await transferExpectSuccess(collection, 0, bob, alice, 50, 'Fungible');51 await transferExpectSuccess(collection, 0, bob, alice, 50, 'Fungible');
52 });52 });
53});53});
61 const alice = privateKey('//Alice');61 const alice = privateKey('//Alice');
62 const bob = privateKey('//Bob');62 const bob = privateKey('//Bob');
63 const charlie = privateKey('//Charlie');63 const charlie = privateKey('//Charlie');
64 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });64 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
65 await transferExpectSuccess(collection, tokenId, alice, { ethereum: subToEth(charlie.address) }, 1, 'NFT');65 await transferExpectSuccess(collection, tokenId, alice, {Ethereum: subToEth(charlie.address)}, 1, 'NFT');
66 await transferFromExpectSuccess(collection, tokenId, alice, {ethereum: subToEth(charlie.address)}, charlie, 1, 'NFT');66 await transferFromExpectSuccess(collection, tokenId, alice, {Ethereum: subToEth(charlie.address)}, charlie, 1, 'NFT');
67 await transferExpectSuccess(collection, tokenId, charlie, bob, 1, 'NFT');67 await transferExpectSuccess(collection, tokenId, charlie, bob, 1, 'NFT');
68 });68 });
6969
77 const charlie = privateKey('//Charlie');77 const charlie = privateKey('//Charlie');
78 const bobProxy = await createEthAccountWithBalance(api, web3);78 const bobProxy = await createEthAccountWithBalance(api, web3);
79 const aliceProxy = await createEthAccountWithBalance(api, web3);79 const aliceProxy = await createEthAccountWithBalance(api, web3);
80 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });80 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
81 await transferExpectSuccess(collection, tokenId, alice, { ethereum: aliceProxy } , 1, 'NFT');81 await transferExpectSuccess(collection, tokenId, alice, {Ethereum: aliceProxy} , 1, 'NFT');
82 const address = collectionIdToAddress(collection);82 const address = collectionIdToAddress(collection);
83 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: aliceProxy, ...GAS_ARGS});83 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: aliceProxy, ...GAS_ARGS});
84 await contract.methods.transfer(bobProxy, 1).send({ from: aliceProxy });84 await contract.methods.transfer(bobProxy, 1).send({from: aliceProxy});
85 await transferFromExpectSuccess(collection, tokenId, alice, {ethereum: bobProxy}, bob, 1, 'NFT');85 await transferFromExpectSuccess(collection, tokenId, alice, {Ethereum: bobProxy}, bob, 1, 'NFT');
86 await transferExpectSuccess(collection, tokenId, bob, charlie, 1, 'NFT');86 await transferExpectSuccess(collection, tokenId, bob, charlie, 1, 'NFT');
87 });87 });
88});88});
modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
1919
20 const caller = await createEthAccountWithBalance(api, web3);20 const caller = await createEthAccountWithBalance(api, web3);
21 21
22 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { substrate: alice.address });22 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});
2323
24 const address = collectionIdToAddress(collection);24 const address = collectionIdToAddress(collection);
25 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});25 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
26 const totalSupply = await contract.methods.totalSupply().call();26 const totalSupply = await contract.methods.totalSupply().call();
2727
28 // FIXME: always equals to 0, because this method is not implemented
29 expect(totalSupply).to.equal('0');28 expect(totalSupply).to.equal('200');
30 });29 });
3130
32 itWeb3('balanceOf', async ({ api, web3 }) => {31 itWeb3('balanceOf', async ({api, web3}) => {
3837
39 const caller = await createEthAccountWithBalance(api, web3);38 const caller = await createEthAccountWithBalance(api, web3);
4039
41 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: caller });40 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller});
4241
43 const address = collectionIdToAddress(collection);42 const address = collectionIdToAddress(collection);
44 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});43 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
5857
59 const owner = await createEthAccountWithBalance(api, web3);58 const owner = await createEthAccountWithBalance(api, web3);
6059
61 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });60 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
6261
63 const spender = createEthAccount(web3);62 const spender = createEthAccount(web3);
6463
98 const owner = createEthAccount(web3);97 const owner = createEthAccount(web3);
99 await transferBalanceToEth(api, alice, owner, 999999999999999);98 await transferBalanceToEth(api, alice, owner, 999999999999999);
10099
101 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });100 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
102101
103 const spender = createEthAccount(web3);102 const spender = createEthAccount(web3);
104 await transferBalanceToEth(api, alice, spender, 999999999999999);103 await transferBalanceToEth(api, alice, spender, 999999999999999);
156 const owner = createEthAccount(web3);155 const owner = createEthAccount(web3);
157 await transferBalanceToEth(api, alice, owner, 999999999999999);156 await transferBalanceToEth(api, alice, owner, 999999999999999);
158157
159 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });158 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
160159
161 const receiver = createEthAccount(web3);160 const receiver = createEthAccount(web3);
162 await transferBalanceToEth(api, alice, receiver, 999999999999999);161 await transferBalanceToEth(api, alice, receiver, 999999999999999);
202 const owner = await createEthAccountWithBalance(api, web3);201 const owner = await createEthAccountWithBalance(api, web3);
203 const spender = createEthAccount(web3);202 const spender = createEthAccount(web3);
204203
205 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });204 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
206205
207 const address = collectionIdToAddress(collection);206 const address = collectionIdToAddress(collection);
208 const contract = new web3.eth.Contract(fungibleAbi as any, address, { from: owner, ...GAS_ARGS });207 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
220 const owner = await createEthAccountWithBalance(api, web3);219 const owner = await createEthAccountWithBalance(api, web3);
221 const spender = await createEthAccountWithBalance(api, web3);220 const spender = await createEthAccountWithBalance(api, web3);
222221
223 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });222 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
224223
225 const address = collectionIdToAddress(collection);224 const address = collectionIdToAddress(collection);
226 const contract = new web3.eth.Contract(fungibleAbi as any, address, { from: owner, ...GAS_ARGS });225 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
240 const owner = await createEthAccountWithBalance(api, web3);239 const owner = await createEthAccountWithBalance(api, web3);
241 const receiver = createEthAccount(web3);240 const receiver = createEthAccount(web3);
242241
243 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });242 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
244243
245 const address = collectionIdToAddress(collection);244 const address = collectionIdToAddress(collection);
246 const contract = new web3.eth.Contract(fungibleAbi as any, address, { from: owner, ...GAS_ARGS });245 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
265 const contract = new web3.eth.Contract(fungibleAbi as any, address);264 const contract = new web3.eth.Contract(fungibleAbi as any, address);
266265
267 const events = await recordEvents(contract, async () => {266 const events = await recordEvents(contract, async () => {
268 await approveExpectSuccess(collection, 1, alice, { ethereum: receiver }, 100);267 await approveExpectSuccess(collection, 0, alice, {Ethereum: receiver}, 100);
269 });268 });
270269
271 expect(events).to.be.deep.equal([270 expect(events).to.be.deep.equal([
291 const receiver = createEthAccount(web3);290 const receiver = createEthAccount(web3);
292291
293 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n });292 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});
294 await approveExpectSuccess(collection, 1, alice, bob, 100);293 await approveExpectSuccess(collection, 0, alice, bob.address, 100);
295294
296 const address = collectionIdToAddress(collection);295 const address = collectionIdToAddress(collection);
297 const contract = new web3.eth.Contract(fungibleAbi as any, address);296 const contract = new web3.eth.Contract(fungibleAbi as any, address);
298297
299 const events = await recordEvents(contract, async () => {298 const events = await recordEvents(contract, async () => {
300 await transferFromExpectSuccess(collection, 1, bob, alice, { ethereum: receiver }, 51, 'Fungible');299 await transferFromExpectSuccess(collection, 0, bob, alice, {Ethereum: receiver}, 51, 'Fungible');
301 });300 });
302301
303 expect(events).to.be.deep.equal([302 expect(events).to.be.deep.equal([
336 const contract = new web3.eth.Contract(fungibleAbi as any, address);335 const contract = new web3.eth.Contract(fungibleAbi as any, address);
337336
338 const events = await recordEvents(contract, async () => {337 const events = await recordEvents(contract, async () => {
339 await transferExpectSuccess(collection, 1, alice, { ethereum: receiver }, 51, 'Fungible');338 await transferExpectSuccess(collection, 0, alice, {Ethereum:receiver}, 51, 'Fungible');
340 });339 });
341340
342 expect(events).to.be.deep.equal([341 expect(events).to.be.deep.equal([
modifiedtests/src/eth/helpersSmoke.test.tsdiffbeforeafterboth
1import { expect } from 'chai';1import {expect} from 'chai';
2import waitNewBlocks from '../substrate/wait-new-blocks';
3import { createEthAccountWithBalance, deployFlipper, itWeb3, contractHelpers } from './util/helpers';2import {createEthAccountWithBalance, deployFlipper, itWeb3, contractHelpers} from './util/helpers';
43
5describe('Helpers sanity check', () => {4describe('Helpers sanity check', () => {
6 itWeb3('Contract owner is recorded', async ({ api, web3 }) => {5 itWeb3('Contract owner is recorded', async ({api, web3}) => {
7 const owner = await createEthAccountWithBalance(api, web3);6 const owner = await createEthAccountWithBalance(api, web3);
87
9 const flipper = await deployFlipper(web3, owner);8 const flipper = await deployFlipper(web3, owner);
10 await waitNewBlocks(api, 1);
119
12 expect(await contractHelpers(web3, owner).methods.contractOwner(flipper.options.address).call()).to.be.equal(owner);10 expect(await contractHelpers(web3, owner).methods.contractOwner(flipper.options.address).call()).to.be.equal(owner);
13 });11 });
1412
15 itWeb3('Flipper is working', async ({ api, web3 }) => {13 itWeb3('Flipper is working', async ({api, web3}) => {
16 const owner = await createEthAccountWithBalance(api, web3);14 const owner = await createEthAccountWithBalance(api, web3);
17 const flipper = await deployFlipper(web3, owner);15 const flipper = await deployFlipper(web3, owner);
18 await waitNewBlocks(api, 1);
1916
20 expect(await flipper.methods.getValue().call()).to.be.false;17 expect(await flipper.methods.getValue().call()).to.be.false;
21 await flipper.methods.flip().send({ from: owner });18 await flipper.methods.flip().send({from: owner});
22 await waitNewBlocks(api, 1);
23 expect(await flipper.methods.getValue().call()).to.be.true;19 expect(await flipper.methods.getValue().call()).to.be.true;
24 });20 });
25});21});
modifiedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
1import { readFile } from 'fs/promises';1import {readFile} from 'fs/promises';
2import { getBalanceSingle, transferBalanceExpectSuccess } from '../../substrate/get-balance';2import {getBalanceSingle, transferBalanceExpectSuccess} from '../../substrate/get-balance';
3import privateKey from '../../substrate/privateKey';3import privateKey from '../../substrate/privateKey';
4import { createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, queryNftOwner, transferExpectSuccess, transferFromExpectSuccess } from '../../util/helpers';4import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, getTokenOwner, transferExpectSuccess, transferFromExpectSuccess} from '../../util/helpers';
5import { collectionIdToAddress, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase } from '../util/helpers';5import {collectionIdToAddress, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase} from '../util/helpers';
6import { evmToAddress } from '@polkadot/util-crypto';6import {evmToAddress} from '@polkadot/util-crypto';
7import nonFungibleAbi from '../nonFungibleAbi.json';7import nonFungibleAbi from '../nonFungibleAbi.json';
8import fungibleAbi from '../fungibleAbi.json';8import fungibleAbi from '../fungibleAbi.json';
9import waitNewBlocks from '../../substrate/wait-new-blocks';
10import { expect } from 'chai';9import {expect} from 'chai';
1110
12const PRICE = 2000n;11const PRICE = 2000n;
1312
14describe('Matcher contract usage', () => {13describe('Matcher contract usage', () => {
15 itWeb3('With UNQ', async ({api, web3}) => {14 itWeb3('With UNQ', async ({api, web3}) => {
16 const matcherOwner = await createEthAccountWithBalance(api, web3);15 const matcherOwner = await createEthAccountWithBalance(api, web3);
17 const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {16 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {
18 from: matcherOwner,17 from: matcherOwner,
19 ...GAS_ARGS,18 ...GAS_ARGS,
20 });19 });
21 const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString() }).send({ from: matcherOwner });20 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString()}).send({from: matcherOwner});
2221
23 const alice = privateKey('//Alice');22 const alice = privateKey('//Alice');
24 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});23 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
29 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);28 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
3029
31 // To transfer item to matcher it first needs to be transfered to EVM account of bob30 // To transfer item to matcher it first needs to be transfered to EVM account of bob
32 await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});31 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});
33 // Fees will be paid from EVM account, so we should have some balance here32 // Fees will be paid from EVM account, so we should have some balance here
34 await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);33 await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
35 await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);34 await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
36 await waitNewBlocks(api, 1);
3735
38 // Token is owned by seller initially36 // Token is owned by seller initially
39 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });37 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});
4038
41 // Ask39 // Ask
42 {40 {
45 }43 }
46 44
47 // Token is transferred to matcher45 // Token is transferred to matcher
48 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });46 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});
4947
50 // Buy48 // Buy
51 {49 {
56 }54 }
5755
58 // Token is transferred to evm account of alice56 // Token is transferred to evm account of alice
59 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });57 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});
6058
61 59
62 // Transfer token to substrate side of alice60 // Transfer token to substrate side of alice
63 await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });61 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});
64 62
65 // Token is transferred to substrate account of alice, seller received funds63 // Token is transferred to substrate account of alice, seller received funds
66 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });64 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});
67 });65 });
6866
69 itWeb3('With custom ERC20', async ({api, web3}) => {67 itWeb3('With custom ERC20', async ({api, web3}) => {
70 const matcherOwner = await createEthAccountWithBalance(api, web3);68 const matcherOwner = await createEthAccountWithBalance(api, web3);
71 const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {69 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {
72 from: matcherOwner,70 from: matcherOwner,
73 ...GAS_ARGS,71 ...GAS_ARGS,
74 });72 });
75 const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString() }).send({ from: matcherOwner });73 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString()}).send({from: matcherOwner});
7674
77 const alice = privateKey('//Alice');75 const alice = privateKey('//Alice');
78 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});76 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
79 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });77 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});
8078
81 const fungibleId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });79 const fungibleId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
82 const evmFungible = new web3.eth.Contract(fungibleAbi as any, collectionIdToAddress(fungibleId), { from: matcherOwner, ...GAS_ARGS });80 const evmFungible = new web3.eth.Contract(fungibleAbi as any, collectionIdToAddress(fungibleId), {from: matcherOwner, ...GAS_ARGS});
83 await createFungibleItemExpectSuccess(alice, fungibleId, { Value: PRICE }, { ethereum: subToEth(alice.address) });81 await createFungibleItemExpectSuccess(alice, fungibleId, {Value: PRICE}, {Ethereum: subToEth(alice.address)});
8482
85 const seller = privateKey('//Bob');83 const seller = privateKey('//Bob');
86 84
87 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);85 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
8886
89 // To transfer item to matcher it first needs to be transfered to EVM account of bob87 // To transfer item to matcher it first needs to be transfered to EVM account of bob
90 await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});88 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});
91 // Fees will be paid from EVM account, so we should have some balance here89 // Fees will be paid from EVM account, so we should have some balance here
92 await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);90 await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
93 await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);91 await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
94 await waitNewBlocks(api, 1);
9592
96 // Token is owned by seller initially93 // Token is owned by seller initially
97 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });94 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});
9895
99 // Ask96 // Ask
100 {97 {
103 }100 }
104 101
105 // Token is transferred to matcher102 // Token is transferred to matcher
106 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });103 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});
107104
108 // Buy105 // Buy
109 {106 {
121 }118 }
122119
123 // Token is transferred to evm account of alice120 // Token is transferred to evm account of alice
124 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });121 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});
125122
126 123
127 // Transfer token to substrate side of alice124 // Transfer token to substrate side of alice
128 await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });125 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});
129 126
130 // Token is transferred to substrate account of alice127 // Token is transferred to substrate account of alice
131 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });128 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});
132 });129 });
133130
134 itWeb3('With escrow', async ({ api, web3 }) => {131 itWeb3('With escrow', async ({api, web3}) => {
135 const matcherOwner = await createEthAccountWithBalance(api, web3);132 const matcherOwner = await createEthAccountWithBalance(api, web3);
136 const escrow = await createEthAccountWithBalance(api, web3);133 const escrow = await createEthAccountWithBalance(api, web3);
137 const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceKSM.abi`)).toString()), undefined, {134 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceKSM.abi`)).toString()), undefined, {
138 from: matcherOwner,135 from: matcherOwner,
139 ...GAS_ARGS,136 ...GAS_ARGS,
140 });137 });
141 const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceKSM.bin`)).toString(), arguments: [escrow] }).send({ from: matcherOwner });138 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlaceKSM.bin`)).toString(), arguments: [escrow]}).send({from: matcherOwner});
142 139
143 const ksmToken = 11;140 const ksmToken = 11;
144141
151 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);148 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
152149
153 // To transfer item to matcher it first needs to be transfered to EVM account of bob150 // To transfer item to matcher it first needs to be transfered to EVM account of bob
154 await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});151 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});
155 // Fees will be paid from EVM account, so we should have some balance here152 // Fees will be paid from EVM account, so we should have some balance here
156 await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);153 await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
157 await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);154 await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
158 await waitNewBlocks(api, 1);
159155
160 // Token is owned by seller initially156 // Token is owned by seller initially
161 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });157 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});
162158
163 // Ask159 // Ask
164 {160 {
167 }163 }
168 164
169 // Token is transferred to matcher165 // Token is transferred to matcher
170 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });166 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});
171167
172 // Give buyer KSM168 // Give buyer KSM
173 await matcher.methods.deposit(PRICE, ksmToken, subToEth(alice.address)).send({ from: escrow });169 await matcher.methods.deposit(PRICE, ksmToken, subToEth(alice.address)).send({from: escrow});
174 await waitNewBlocks(api, 1);170
175
176 // Buy171 // Buy
177 {172 {
178 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');173 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');
179 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());174 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());
180175
181 await executeEthTxOnSub(api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));176 await executeEthTxOnSub(api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));
182 await waitNewBlocks(api, 1);
183177
184 // Price is removed from buyer balance, and added to seller178 // Price is removed from buyer balance, and added to seller
185 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');179 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');
186 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal(PRICE.toString());180 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal(PRICE.toString());
187 }181 }
188182
189 // Token is transferred to evm account of alice183 // Token is transferred to evm account of alice
190 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });184 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});
191 185
192 // Transfer token to substrate side of alice186 // Transfer token to substrate side of alice
193 await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });187 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});
194 188
195 // Token is transferred to substrate account of alice, seller received funds189 // Token is transferred to substrate account of alice, seller received funds
196 expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });190 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});
197 });191 });
198});192});
199193
modifiedtests/src/eth/metadata.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/eth/migration.test.tsdiffbeforeafterboth
41 const alice = privateKey('//Alice');41 const alice = privateKey('//Alice');
42 const caller = await createEthAccountWithBalance(api, web3);42 const caller = await createEthAccountWithBalance(api, web3);
4343
44 await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.begin(ADDRESS)));44 await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.begin(ADDRESS) as any));
45 await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.setData(ADDRESS, DATA)));45 await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.setData(ADDRESS, DATA as any) as any));
46 await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.finish(ADDRESS, CODE)));46 await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.finish(ADDRESS, CODE) as any));
4747
48 const contract = new web3.eth.Contract([48 const contract = new web3.eth.Contract([
49 {49 {
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
8import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth } from './util/helpers';8import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';
9import nonFungibleAbi from './nonFungibleAbi.json';9import nonFungibleAbi from './nonFungibleAbi.json';
10import { expect } from 'chai';10import {expect} from 'chai';
11import waitNewBlocks from '../substrate/wait-new-blocks';
12import { submitTransactionAsync } from '../substrate/substrate-api';11import {submitTransactionAsync} from '../substrate/substrate-api';
1312
14describe('NFT: Information getting', () => {13describe('NFT: Information getting', () => {
19 const alice = privateKey('//Alice');18 const alice = privateKey('//Alice');
20 const caller = await createEthAccountWithBalance(api, web3);19 const caller = await createEthAccountWithBalance(api, web3);
2120
22 await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });21 await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
2322
24 const address = collectionIdToAddress(collection);23 const address = collectionIdToAddress(collection);
25 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});24 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
26 const totalSupply = await contract.methods.totalSupply().call();25 const totalSupply = await contract.methods.totalSupply().call();
2726
28 // FIXME: always equals to 0, because this method is not implemented
29 expect(totalSupply).to.equal('0');27 expect(totalSupply).to.equal('1');
30 });28 });
3129
32 itWeb3('balanceOf', async ({ api, web3 }) => {30 itWeb3('balanceOf', async ({api, web3}) => {
36 const alice = privateKey('//Alice');34 const alice = privateKey('//Alice');
3735
38 const caller = await createEthAccountWithBalance(api, web3);36 const caller = await createEthAccountWithBalance(api, web3);
39 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });37 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum:caller});
40 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });38 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
41 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });39 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
4240
43 const address = collectionIdToAddress(collection);41 const address = collectionIdToAddress(collection);
44 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});42 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
54 const alice = privateKey('//Alice');52 const alice = privateKey('//Alice');
5553
56 const caller = await createEthAccountWithBalance(api, web3);54 const caller = await createEthAccountWithBalance(api, web3);
57 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });55 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
5856
59 const address = collectionIdToAddress(collection);57 const address = collectionIdToAddress(collection);
60 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});58 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
72 const alice = privateKey('//Alice');70 const alice = privateKey('//Alice');
7371
74 const caller = await createEthAccountWithBalance(api, web3);72 const caller = await createEthAccountWithBalance(api, web3);
75 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: caller });73 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, {Ethereum: caller});
76 await submitTransactionAsync(alice, changeAdminTx);74 await submitTransactionAsync(alice, changeAdminTx);
77 const receiver = createEthAccount(web3);75 const receiver = createEthAccount(web3);
7876
101 },99 },
102 ]);100 ]);
103101
104 await waitNewBlocks(api, 1);
105 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');102 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
106 }103 }
107 });104 });
112 const alice = privateKey('//Alice');109 const alice = privateKey('//Alice');
113110
114 const caller = await createEthAccountWithBalance(api, web3);111 const caller = await createEthAccountWithBalance(api, web3);
115 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: caller });112 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, {Ethereum: caller});
116 await submitTransactionAsync(alice, changeAdminTx);113 await submitTransactionAsync(alice, changeAdminTx);
117 const receiver = createEthAccount(web3);114 const receiver = createEthAccount(web3);
118115
162 },159 },
163 ]);160 ]);
164161
165 await waitNewBlocks(api, 1);
166 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');162 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');
167 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');163 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');
168 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');164 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');
177173
178 const owner = await createEthAccountWithBalance(api, web3);174 const owner = await createEthAccountWithBalance(api, web3);
179175
180 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });176 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
181 177
182 const address = collectionIdToAddress(collection);178 const address = collectionIdToAddress(collection);
183 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});179 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
209 const owner = createEthAccount(web3);205 const owner = createEthAccount(web3);
210 await transferBalanceToEth(api, alice, owner, 999999999999999);206 await transferBalanceToEth(api, alice, owner, 999999999999999);
211207
212 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });208 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
213209
214 const spender = createEthAccount(web3);210 const spender = createEthAccount(web3);
215211
243 const owner = createEthAccount(web3);239 const owner = createEthAccount(web3);
244 await transferBalanceToEth(api, alice, owner, 999999999999999);240 await transferBalanceToEth(api, alice, owner, 999999999999999);
245241
246 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });242 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
247243
248 const spender = createEthAccount(web3);244 const spender = createEthAccount(web3);
249 await transferBalanceToEth(api, alice, spender, 999999999999999);245 await transferBalanceToEth(api, alice, spender, 999999999999999);
291 const owner = createEthAccount(web3);287 const owner = createEthAccount(web3);
292 await transferBalanceToEth(api, alice, owner, 999999999999999);288 await transferBalanceToEth(api, alice, owner, 999999999999999);
293289
294 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });290 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
295291
296 const receiver = createEthAccount(web3);292 const receiver = createEthAccount(web3);
297 await transferBalanceToEth(api, alice, receiver, 999999999999999);293 await transferBalanceToEth(api, alice, receiver, 999999999999999);
301297
302 {298 {
303 const result = await contract.methods.transfer(receiver, tokenId).send({ from: owner });299 const result = await contract.methods.transfer(receiver, tokenId).send({from: owner});
304 await waitNewBlocks(api, 1);
305 const events = normalizeEvents(result.events);300 const events = normalizeEvents(result.events);
306 expect(events).to.be.deep.equal([301 expect(events).to.be.deep.equal([
307 {302 {
335330
336 const owner = await createEthAccountWithBalance(api, web3);331 const owner = await createEthAccountWithBalance(api, web3);
337332
338 const item = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });333 const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
339 await setMetadataUpdatePermissionFlagExpectSuccess(alice, collection, 'Admin');334 await setMetadataUpdatePermissionFlagExpectSuccess(alice, collection, 'Admin');
340 await setVariableMetaDataExpectSuccess(alice, collection, item, [1, 2, 3]);335 await setVariableMetaDataExpectSuccess(alice, collection, item, [1, 2, 3]);
341336
353348
354 const owner = await createEthAccountWithBalance(api, web3);349 const owner = await createEthAccountWithBalance(api, web3);
355350
356 const item = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });351 const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
357352
358 const address = collectionIdToAddress(collection);353 const address = collectionIdToAddress(collection);
359 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });354 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
360 355
361 expect(await contract.methods.setVariableMetadata(item, '0x010203').send({ from: owner }));356 expect(await contract.methods.setVariableMetadata(item, '0x010203').send({from: owner}));
362 await waitNewBlocks(api, 1);
363 expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');357 expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');
364 });358 });
365});359});
374 const owner = await createEthAccountWithBalance(api, web3);368 const owner = await createEthAccountWithBalance(api, web3);
375 const spender = createEthAccount(web3);369 const spender = createEthAccount(web3);
376370
377 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });371 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
378372
379 const address = collectionIdToAddress(collection);373 const address = collectionIdToAddress(collection);
380 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });374 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
392 const owner = await createEthAccountWithBalance(api, web3);386 const owner = await createEthAccountWithBalance(api, web3);
393 const spender = await createEthAccountWithBalance(api, web3);387 const spender = await createEthAccountWithBalance(api, web3);
394388
395 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });389 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
396390
397 const address = collectionIdToAddress(collection);391 const address = collectionIdToAddress(collection);
398 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });392 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
412 const owner = await createEthAccountWithBalance(api, web3);406 const owner = await createEthAccountWithBalance(api, web3);
413 const receiver = createEthAccount(web3);407 const receiver = createEthAccount(web3);
414408
415 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });409 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
416410
417 const address = collectionIdToAddress(collection);411 const address = collectionIdToAddress(collection);
418 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });412 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
491 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);485 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
492486
493 const events = await recordEvents(contract, async () => {487 const events = await recordEvents(contract, async () => {
494 await approveExpectSuccess(collection, tokenId, alice, { ethereum: receiver }, 1);488 await approveExpectSuccess(collection, tokenId, alice, {Ethereum: receiver}, 1);
495 });489 });
496490
497 expect(events).to.be.deep.equal([491 expect(events).to.be.deep.equal([
517 const receiver = createEthAccount(web3);511 const receiver = createEthAccount(web3);
518512
519 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');513 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
520 await approveExpectSuccess(collection, tokenId, alice, bob, 1);514 await approveExpectSuccess(collection, tokenId, alice, bob.address, 1);
521515
522 const address = collectionIdToAddress(collection);516 const address = collectionIdToAddress(collection);
523 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);517 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
524518
525 const events = await recordEvents(contract, async () => {519 const events = await recordEvents(contract, async () => {
526 await transferFromExpectSuccess(collection, tokenId, bob, alice, { ethereum: receiver }, 1, 'NFT');520 await transferFromExpectSuccess(collection, tokenId, bob, alice, {Ethereum: receiver}, 1, 'NFT');
527 });521 });
528522
529 expect(events).to.be.deep.equal([523 expect(events).to.be.deep.equal([
553 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);547 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
554548
555 const events = await recordEvents(contract, async () => {549 const events = await recordEvents(contract, async () => {
556 await transferExpectSuccess(collection, tokenId, alice, { ethereum: receiver }, 1, 'NFT');550 await transferExpectSuccess(collection, tokenId, alice, {Ethereum: receiver}, 1, 'NFT');
557 });551 });
558552
559 expect(events).to.be.deep.equal([553 expect(events).to.be.deep.equal([
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
1import { expect } from 'chai';1import {expect} from 'chai';
2import privateKey from '../substrate/privateKey';2import privateKey from '../substrate/privateKey';
3import { submitTransactionAsync } from '../substrate/substrate-api';3import {submitTransactionAsync} from '../substrate/substrate-api';
4import waitNewBlocks from '../substrate/wait-new-blocks';
5import { createEthAccountWithBalance, deployCollector, GAS_ARGS, itWeb3, subToEth } from './util/helpers';4import {createEthAccountWithBalance, deployCollector, GAS_ARGS, itWeb3, subToEth} from './util/helpers';
6import {evmToAddress} from '@polkadot/util-crypto';5import {evmToAddress} from '@polkadot/util-crypto';
7import { getGenericResult } from '../util/helpers';6import {getGenericResult} from '../util/helpers';
13 const contract = await deployCollector(web3, deployer);12 const contract = await deployCollector(web3, deployer);
1413
15 await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: '10000', ...GAS_ARGS});14 await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: '10000', ...GAS_ARGS});
16 await waitNewBlocks(api, 1);
1715
18 expect(await contract.methods.getCollected().call()).to.be.equal('10000');16 expect(await contract.methods.getCollected().call()).to.be.equal('10000');
19 });17 });
65 const alice = privateKey('//Alice');63 const alice = privateKey('//Alice');
6664
67 await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: CONTRACT_BALANCE.toString(), ...GAS_ARGS});65 await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: CONTRACT_BALANCE.toString(), ...GAS_ARGS});
68 await waitNewBlocks(api, 1);
6966
70 const receiver = privateKey(`//Receiver${Date.now()}`);67 const receiver = privateKey(`//Receiver${Date.now()}`);
7168
modifiedtests/src/eth/proxy/fungibleProxy.test.tsdiffbeforeafterboth
15async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {15async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {
16 // Proxy owner has no special privilegies, we don't need to reuse them16 // Proxy owner has no special privilegies, we don't need to reuse them
17 const owner = await createEthAccountWithBalance(api, web3);17 const owner = await createEthAccountWithBalance(api, web3);
18 const Proxy = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, {18 const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, {
19 from: owner,19 from: owner,
20 ...GAS_ARGS,20 ...GAS_ARGS,
21 });21 });
22 const proxy = await Proxy.deploy({ data: (await readFile(`${__dirname}/UniqueFungibleProxy.bin`)).toString(), arguments: [wrapped.options.address] }).send({ from: owner });22 const proxy = await proxyContract.deploy({data: (await readFile(`${__dirname}/UniqueFungibleProxy.bin`)).toString(), arguments: [wrapped.options.address]}).send({from: owner});
23 return proxy;23 return proxy;
24}24}
2525
32 const alice = privateKey('//Alice');32 const alice = privateKey('//Alice');
33 const caller = await createEthAccountWithBalance(api, web3);33 const caller = await createEthAccountWithBalance(api, web3);
34 34
35 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { substrate: alice.address });35 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});
3636
37 const address = collectionIdToAddress(collection);37 const address = collectionIdToAddress(collection);
38 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));38 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
39 const totalSupply = await contract.methods.totalSupply().call();39 const totalSupply = await contract.methods.totalSupply().call();
4040
41 // FIXME: always equals to 0, because this method is not implemented
42 expect(totalSupply).to.equal('0');41 expect(totalSupply).to.equal('200');
43 });42 });
4443
45 itWeb3('balanceOf', async ({ api, web3 }) => {44 itWeb3('balanceOf', async ({api, web3}) => {
50 const alice = privateKey('//Alice');49 const alice = privateKey('//Alice');
51 const caller = await createEthAccountWithBalance(api, web3);50 const caller = await createEthAccountWithBalance(api, web3);
5251
53 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: caller });52 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller});
5453
55 const address = collectionIdToAddress(collection);54 const address = collectionIdToAddress(collection);
56 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));55 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
7271
73 const address = collectionIdToAddress(collection);72 const address = collectionIdToAddress(collection);
74 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));73 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
75 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: contract.options.address });74 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: contract.options.address});
7675
77 {76 {
78 const result = await contract.methods.approve(spender, 100).send({from: caller});77 const result = await contract.methods.approve(spender, 100).send({from: caller});
106 const caller = await createEthAccountWithBalance(api, web3);105 const caller = await createEthAccountWithBalance(api, web3);
107 const owner = await createEthAccountWithBalance(api, web3);106 const owner = await createEthAccountWithBalance(api, web3);
108107
109 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });108 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
110109
111 const receiver = createEthAccount(web3);110 const receiver = createEthAccount(web3);
112111
163162
164 const address = collectionIdToAddress(collection);163 const address = collectionIdToAddress(collection);
165 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));164 const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
166 await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: contract.options.address });165 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: contract.options.address});
167166
168 {167 {
169 const result = await contract.methods.transfer(receiver, 50).send({ from: caller});168 const result = await contract.methods.transfer(receiver, 50).send({from: caller});
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
8import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents } from '../util/helpers';8import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents} from '../util/helpers';
9import nonFungibleAbi from '../nonFungibleAbi.json';9import nonFungibleAbi from '../nonFungibleAbi.json';
10import { expect } from 'chai';10import {expect} from 'chai';
11import waitNewBlocks from '../../substrate/wait-new-blocks';
12import { submitTransactionAsync } from '../../substrate/substrate-api';11import {submitTransactionAsync} from '../../substrate/substrate-api';
13import Web3 from 'web3';12import Web3 from 'web3';
14import { readFile } from 'fs/promises';13import {readFile} from 'fs/promises';
17async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {16async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {
18 // Proxy owner has no special privilegies, we don't need to reuse them17 // Proxy owner has no special privilegies, we don't need to reuse them
19 const owner = await createEthAccountWithBalance(api, web3);18 const owner = await createEthAccountWithBalance(api, web3);
20 const Proxy = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {19 const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {
21 from: owner,20 from: owner,
22 ...GAS_ARGS,21 ...GAS_ARGS,
23 });22 });
24 const proxy = await Proxy.deploy({ data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address] }).send({ from: owner });23 const proxy = await proxyContract.deploy({data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address]}).send({from: owner});
25 return proxy;24 return proxy;
26}25}
2726
33 const alice = privateKey('//Alice');32 const alice = privateKey('//Alice');
34 const caller = await createEthAccountWithBalance(api, web3);33 const caller = await createEthAccountWithBalance(api, web3);
3534
36 await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });35 await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
3736
38 const address = collectionIdToAddress(collection);37 const address = collectionIdToAddress(collection);
39 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));38 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
40 const totalSupply = await contract.methods.totalSupply().call();39 const totalSupply = await contract.methods.totalSupply().call();
4140
42 // FIXME: always equals to 0, because this method is not implemented
43 expect(totalSupply).to.equal('0');41 expect(totalSupply).to.equal('1');
44 });42 });
4543
46 itWeb3('balanceOf', async ({ api, web3 }) => {44 itWeb3('balanceOf', async ({api, web3}) => {
50 const alice = privateKey('//Alice');48 const alice = privateKey('//Alice');
5149
52 const caller = await createEthAccountWithBalance(api, web3);50 const caller = await createEthAccountWithBalance(api, web3);
53 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });51 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
54 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });52 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
55 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });53 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
5654
57 const address = collectionIdToAddress(collection);55 const address = collectionIdToAddress(collection);
58 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));56 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
68 const alice = privateKey('//Alice');66 const alice = privateKey('//Alice');
6967
70 const caller = await createEthAccountWithBalance(api, web3);68 const caller = await createEthAccountWithBalance(api, web3);
71 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });69 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
7270
73 const address = collectionIdToAddress(collection);71 const address = collectionIdToAddress(collection);
74 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));72 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
90 const address = collectionIdToAddress(collection);88 const address = collectionIdToAddress(collection);
91 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS }));89 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
9290
93 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });91 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, {Ethereum: contract.options.address});
94 await submitTransactionAsync(alice, changeAdminTx);92 await submitTransactionAsync(alice, changeAdminTx);
9593
96 {94 {
115 },113 },
116 ]);114 ]);
117115
118 await waitNewBlocks(api, 1);
119 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');116 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
120 }117 }
121 });118 });
130127
131 const address = collectionIdToAddress(collection);128 const address = collectionIdToAddress(collection);
132 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS }));129 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
133 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });130 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, {Ethereum: contract.options.address});
134 await submitTransactionAsync(alice, changeAdminTx);131 await submitTransactionAsync(alice, changeAdminTx);
135132
136 {133 {
176 },173 },
177 ]);174 ]);
178175
179 await waitNewBlocks(api, 1);
180 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');176 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');
181 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');177 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');
182 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');178 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');
192 188
193 const address = collectionIdToAddress(collection);189 const address = collectionIdToAddress(collection);
194 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));190 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
195 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });191 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
196192
197 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });193 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, {Ethereum: contract.options.address});
198 await submitTransactionAsync(alice, changeAdminTx);194 await submitTransactionAsync(alice, changeAdminTx);
199195
200 {196 {
225221
226 const address = collectionIdToAddress(collection);222 const address = collectionIdToAddress(collection);
227 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));223 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));
228 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });224 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
229225
230 {226 {
231 const result = await contract.methods.approve(spender, tokenId).send({ from: caller, gas: '0x1000000', gasPrice: '0x01' });227 const result = await contract.methods.approve(spender, tokenId).send({from: caller, gas: '0x1000000', gasPrice: '0x01'});
258 const address = collectionIdToAddress(collection);254 const address = collectionIdToAddress(collection);
259 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS });255 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
260 const contract = await proxyWrap(api, web3, evmCollection);256 const contract = await proxyWrap(api, web3, evmCollection);
261 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });257 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
262258
263 await evmCollection.methods.approve(contract.options.address, tokenId).send({ from: owner });259 await evmCollection.methods.approve(contract.options.address, tokenId).send({from: owner});
264260
299295
300 const address = collectionIdToAddress(collection);296 const address = collectionIdToAddress(collection);
301 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));297 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
302 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });298 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
303299
304 {300 {
305 const result = await contract.methods.transfer(receiver, tokenId).send({ from: caller });301 const result = await contract.methods.transfer(receiver, tokenId).send({from: caller});
306 await waitNewBlocks(api, 1);
307 const events = normalizeEvents(result.events);302 const events = normalizeEvents(result.events);
308 expect(events).to.be.deep.equal([303 expect(events).to.be.deep.equal([
309 {304 {
338333
339 const address = collectionIdToAddress(collection);334 const address = collectionIdToAddress(collection);
340 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS }));335 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
341 const item = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });336 const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
342 await setMetadataUpdatePermissionFlagExpectSuccess(alice, collection, 'Admin');337 await setMetadataUpdatePermissionFlagExpectSuccess(alice, collection, 'Admin');
343 await setVariableMetaDataExpectSuccess(alice, collection, item, [1, 2, 3]);338 await setVariableMetaDataExpectSuccess(alice, collection, item, [1, 2, 3]);
344 339
354349
355 const address = collectionIdToAddress(collection);350 const address = collectionIdToAddress(collection);
356 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS }));351 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
357 const item = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });352 const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
358 353
359 expect(await contract.methods.setVariableMetadata(item, '0x010203').send({ from: caller }));354 expect(await contract.methods.setVariableMetadata(item, '0x010203').send({from: caller}));
360 await waitNewBlocks(api, 1);
361 expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');355 expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');
362 });356 });
363});357});
modifiedtests/src/eth/sponsoring.test.tsdiffbeforeafterboth
1import { expect } from 'chai';1import {expect} from 'chai';
2import privateKey from '../substrate/privateKey';2import privateKey from '../substrate/privateKey';
3import waitNewBlocks from '../substrate/wait-new-blocks';
4import { contractHelpers, createEthAccount, createEthAccountWithBalance, deployCollector, deployFlipper, itWeb3, transferBalanceToEth, usingWeb3Http } from './util/helpers';3import {contractHelpers, createEthAccount, createEthAccountWithBalance, deployCollector, deployFlipper, itWeb3, transferBalanceToEth} from './util/helpers';
54
6describe('EVM sponsoring', () => {5describe('EVM sponsoring', () => {
7 itWeb3('Fee is deducted from contract if sponsoring is enabled', async ({api, web3}) => {6 itWeb3('Fee is deducted from contract if sponsoring is enabled', async ({api, web3}) => {
8 await usingWeb3Http(async web3Http => {
9 const alice = privateKey('//Alice');7 const alice = privateKey('//Alice');
108
11 const owner = await createEthAccountWithBalance(api, web3Http);9 const owner = await createEthAccountWithBalance(api, web3);
12 const caller = createEthAccount(web3Http);10 const caller = createEthAccount(web3);
13 const originalCallerBalance = await web3.eth.getBalance(caller);11 const originalCallerBalance = await web3.eth.getBalance(caller);
14 expect(originalCallerBalance).to.be.equal('0');12 expect(originalCallerBalance).to.be.equal('0');
1513
16 const flipper = await deployFlipper(web3Http, owner);14 const flipper = await deployFlipper(web3, owner);
17 await waitNewBlocks(api, 1);15
18
19 const helpers = contractHelpers(web3Http, owner);16 const helpers = contractHelpers(web3, owner);
20 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });17 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});
21 await waitNewBlocks(api, 1);
22 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner });18 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});
23 await waitNewBlocks(api, 1);
2419
25 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;20 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
26 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});21 await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
27 await waitNewBlocks(api, 1);
28 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});22 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});
29 await waitNewBlocks(api, 1);
30 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;23 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
3124
32 await transferBalanceToEth(api, alice, flipper.options.address);25 await transferBalanceToEth(api, alice, flipper.options.address);
33 await waitNewBlocks(api, 2);
3426
35 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);27 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
36 expect(originalFlipperBalance).to.be.not.equal('0');28 expect(originalFlipperBalance).to.be.not.equal('0');
3729
38 await flipper.methods.flip().send({ from: caller });30 await flipper.methods.flip().send({from: caller});
39 await waitNewBlocks(api, 1);
40 expect(await flipper.methods.getValue().call()).to.be.true;31 expect(await flipper.methods.getValue().call()).to.be.true;
4132
42 // Balance should be taken from flipper instead of caller33 // Balance should be taken from flipper instead of caller
43 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);34 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);
44 expect(await web3.eth.getBalance(flipper.options.address)).to.be.not.equals(originalFlipperBalance);35 expect(await web3.eth.getBalance(flipper.options.address)).to.be.not.equals(originalFlipperBalance);
45 });
46 });36 });
47 itWeb3('...but this doesn\'t applies to payable value', async ({api, web3}) => {37 itWeb3('...but this doesn\'t applies to payable value', async ({api, web3}) => {
48 await usingWeb3Http(async web3Http => {
49 const alice = privateKey('//Alice');38 const alice = privateKey('//Alice');
5039
51 const owner = await createEthAccountWithBalance(api, web3Http);40 const owner = await createEthAccountWithBalance(api, web3);
52 const caller = await createEthAccountWithBalance(api, web3Http);41 const caller = await createEthAccountWithBalance(api, web3);
53 await waitNewBlocks(api, 1);
54 const originalCallerBalance = await web3.eth.getBalance(caller);42 const originalCallerBalance = await web3.eth.getBalance(caller);
55 expect(originalCallerBalance).to.be.not.equal('0');43 expect(originalCallerBalance).to.be.not.equal('0');
5644
57 const collector = await deployCollector(web3Http, owner);45 const collector = await deployCollector(web3, owner);
58 await waitNewBlocks(api, 1);46
59
60 const helpers = contractHelpers(web3Http, owner);47 const helpers = contractHelpers(web3, owner);
61 await helpers.methods.toggleAllowlist(collector.options.address, true).send({ from: owner });48 await helpers.methods.toggleAllowlist(collector.options.address, true).send({from: owner});
62 await waitNewBlocks(api, 1);
63 await helpers.methods.toggleAllowed(collector.options.address, caller, true).send({ from: owner });49 await helpers.methods.toggleAllowed(collector.options.address, caller, true).send({from: owner});
64 await waitNewBlocks(api, 1);
6550
66 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.false;51 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.false;
67 await helpers.methods.toggleSponsoring(collector.options.address, true).send({ from: owner });52 await helpers.methods.toggleSponsoring(collector.options.address, true).send({from: owner});
68 await waitNewBlocks(api, 1);
69 await helpers.methods.setSponsoringRateLimit(collector.options.address, 0).send({ from: owner });53 await helpers.methods.setSponsoringRateLimit(collector.options.address, 0).send({from: owner});
70 await waitNewBlocks(api, 1);
71 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.true;54 expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.true;
7255
73 await transferBalanceToEth(api, alice, collector.options.address);56 await transferBalanceToEth(api, alice, collector.options.address);
74 await waitNewBlocks(api, 2);
7557
76 const originalCollectorBalance = await web3.eth.getBalance(collector.options.address);58 const originalCollectorBalance = await web3.eth.getBalance(collector.options.address);
77 expect(originalCollectorBalance).to.be.not.equal('0');59 expect(originalCollectorBalance).to.be.not.equal('0');
7860
79 await collector.methods.giveMoney().send({ from: caller, value: '10000' });61 await collector.methods.giveMoney().send({from: caller, value: '10000'});
80 await waitNewBlocks(api, 1);
8162
82 // Balance will be taken from both caller (value) and from collector (fee)63 // Balance will be taken from both caller (value) and from collector (fee)
83 expect(await web3.eth.getBalance(caller)).to.be.equals((BigInt(originalCallerBalance) - 10000n).toString());64 expect(await web3.eth.getBalance(caller)).to.be.equals((BigInt(originalCallerBalance) - 10000n).toString());
84 expect(await web3.eth.getBalance(collector.options.address)).to.be.not.equals(originalCollectorBalance);65 expect(await web3.eth.getBalance(collector.options.address)).to.be.not.equals(originalCollectorBalance);
85 expect(await collector.methods.getCollected().call()).to.be.equal('10000');66 expect(await collector.methods.getCollected().call()).to.be.equal('10000');
86 });
87 });67 });
88});68});
69
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
18import privateKey from '../../substrate/privateKey';18import privateKey from '../../substrate/privateKey';
19import contractHelpersAbi from './contractHelpersAbi.json';19import contractHelpersAbi from './contractHelpersAbi.json';
20import getBalance from '../../substrate/get-balance';20import getBalance from '../../substrate/get-balance';
21import waitNewBlocks from '../../substrate/wait-new-blocks';
2221
23export const GAS_ARGS = { gas: 0x1000000, gasPrice: '0x01' };22export const GAS_ARGS = {gas: 0x1000000, gasPrice: '0x01'};
2423
39 }38 }
40}39}
41
42/**
43 * @deprecated Web3 update solved issue with deployment over ws provider
44 */
45export async function usingWeb3Http<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {
46 const provider = new Web3.providers.HttpProvider(config.frontierUrl);
47 const web3: Web3 = new Web3(provider);
48
49 return await cb(web3);
50}
5140
52export function collectionIdToAddress(address: number): string {41export function collectionIdToAddress(address: number): string {
53 if (address >= 0xffffffff || address < 0) throw new Error('id overflow');42 if (address >= 0xffffffff || address < 0) throw new Error('id overflow');
192 }181 }
193 }182 }
194 `);183 `);
195 const Flipper = new web3.eth.Contract(compiled.abi, undefined, {184 const flipperContract = new web3.eth.Contract(compiled.abi, undefined, {
196 data: compiled.object,185 data: compiled.object,
197 from: deployer,186 from: deployer,
198 ...GAS_ARGS,187 ...GAS_ARGS,
199 });188 });
200 const flipper = await Flipper.deploy({ data: compiled.object }).send({from: deployer});189 const flipper = await flipperContract.deploy({data: compiled.object}).send({from: deployer});
201190
202 return flipper;191 return flipper;
203}192}
225 }214 }
226 }215 }
227 `);216 `);
228 const Collector = new web3.eth.Contract(compiled.abi, undefined, {217 const collectorContract = new web3.eth.Contract(compiled.abi, undefined, {
229 data: compiled.object,218 data: compiled.object,
230 from: deployer,219 from: deployer,
231 ...GAS_ARGS,220 ...GAS_ARGS,
232 });221 });
233 const collector = await Collector.deploy({ data: compiled.object }).send({ from: deployer });222 const collector = await collectorContract.deploy({data: compiled.object}).send({from: deployer});
234223
235 return collector;224 return collector;
236}225}
250 null,239 null,
251 );240 );
252 const events = await submitTransactionAsync(from, tx);241 const events = await submitTransactionAsync(from, tx);
253 expect(events.find(({ event: {section, method}})=>section === 'evm' && method === 'Executed')).to.be.not.undefined;242 expect(events.some(({event: {section, method}}) => section == 'evm' && method == 'Executed')).to.be.true;
254}243}
255244
256export async function ethBalanceViaSub(api: ApiPromise, address: string): Promise<bigint> {245export async function ethBalanceViaSub(api: ApiPromise, address: string): Promise<bigint> {
261 const before = await ethBalanceViaSub(api, user);250 const before = await ethBalanceViaSub(api, user);
262251
263 await call();252 await call();
264 await waitNewBlocks(api, 1);
265253
266 const after = await ethBalanceViaSub(api, user);254 const after = await ethBalanceViaSub(api, user);
267255
modifiedtests/src/inflation.test.tsdiffbeforeafterboth
6import chai from 'chai';6import chai from 'chai';
7import chaiAsPromised from 'chai-as-promised';7import chaiAsPromised from 'chai-as-promised';
8import { default as usingApi } from './substrate/substrate-api';8import {default as usingApi} from './substrate/substrate-api';
9import { BigNumber } from 'bignumber.js';
109
11chai.use(chaiAsPromised);10chai.use(chaiAsPromised);
12const expect = chai.expect;11const expect = chai.expect;
15 it('First year inflation is 10%', async () => {14 it('First year inflation is 10%', async () => {
16 await usingApi(async (api) => {15 await usingApi(async (api) => {
1716
18 const blockInterval = parseInt((await api.consts.inflation.inflationBlockInterval).toString());17 const blockInterval = (api.consts.inflation.inflationBlockInterval).toBigInt();
19 const totalIssuanceStart = new BigNumber((await api.query.inflation.startingYearTotalIssuance()).toString());18 const totalIssuanceStart = (await api.query.inflation.startingYearTotalIssuance()).toBigInt();
20 const blockInflation = new BigNumber((await api.query.inflation.blockInflation()).toString());19 const blockInflation = (await api.query.inflation.blockInflation()).toBigInt();
2120
22 const YEAR = 5259600; // Blocks in one year21 const YEAR = 5259600n; // Blocks in one year
23 const totalExpectedInflation = totalIssuanceStart.multipliedBy(0.1);22 const totalExpectedInflation = totalIssuanceStart / 10n;
24 const totalActualInflation = blockInflation.multipliedBy(YEAR / blockInterval);23 const totalActualInflation = blockInflation * YEAR / blockInterval;
2524
26 const tolerance = 0.00001; // Relative difference per year between theoretical and actual inflation25 const tolerance = 0.00001; // Relative difference per year between theoretical and actual inflation
26 let abs = totalExpectedInflation / totalActualInflation - 1n;
27 if (abs < 0n) {
28 abs = -abs;
29 }
27 expect(totalExpectedInflation.dividedBy(totalActualInflation).minus(1).abs().toNumber()).to.be.lessThan(tolerance);30 expect(abs <= tolerance).to.be.true;
28 });31 });
29 });32 });
3033
addedtests/src/interfaces/augment-api-consts.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-api-events.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-api.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/augment-types.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/definitions.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/ethereum/definitions.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/ethereum/index.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/ethereum/types.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/index.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/nft/definitions.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/nft/index.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/nft/types.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/polkadot/definitions.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/polkadot/index.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/polkadot/types.tsdiffbeforeafterboth

no changes

addedtests/src/interfaces/types.tsdiffbeforeafterboth

no changes

modifiedtests/src/limits.test.tsdiffbeforeafterboth
3// file 'LICENSE', which is part of this source code package.3// file 'LICENSE', which is part of this source code package.
4//4//
55
6import { IKeyringPair } from '@polkadot/types/types';6import {IKeyringPair} from '@polkadot/types/types';
7import privateKey from './substrate/privateKey';7import privateKey from './substrate/privateKey';
8import usingApi from './substrate/substrate-api';8import usingApi from './substrate/substrate-api';
9import {9import {
18 getFreeBalance,18 getFreeBalance,
19 waitNewBlocks,19 waitNewBlocks,
20} from './util/helpers';20} from './util/helpers';
21import { expect } from 'chai';21import {expect} from 'chai';
2222
23describe('Number of tokens per address (NFT)', () => {23describe('Number of tokens per address (NFT)', () => {
24 let Alice: IKeyringPair;24 let alice: IKeyringPair;
2525
26 before(async () => {26 before(async () => {
27 await usingApi(async () => {27 await usingApi(async () => {
28 Alice = privateKey('//Alice');28 alice = privateKey('//Alice');
29 });29 });
30 });30 });
3131
32 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {32 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {
3333
34 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });34 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
35 await setCollectionLimitsExpectSuccess(Alice, collectionId, { accountTokenOwnershipLimit: 20 });35 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});
36 for(let i = 0; i < 10; i++){36 for(let i = 0; i < 10; i++){
37 await createItemExpectSuccess(Alice, collectionId, 'NFT');37 await createItemExpectSuccess(alice, collectionId, 'NFT');
38 }38 }
39 await createItemExpectFailure(Alice, collectionId, 'NFT');39 await createItemExpectFailure(alice, collectionId, 'NFT');
40 await destroyCollectionExpectSuccess(collectionId);40 await destroyCollectionExpectSuccess(collectionId);
41 });41 });
4242
43 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {43 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {
4444
45 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });45 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
46 await setCollectionLimitsExpectSuccess(Alice, collectionId, { accountTokenOwnershipLimit: 1 });46 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});
47 await createItemExpectSuccess(Alice, collectionId, 'NFT');47 await createItemExpectSuccess(alice, collectionId, 'NFT');
48 await createItemExpectFailure(Alice, collectionId, 'NFT');48 await createItemExpectFailure(alice, collectionId, 'NFT');
49 await destroyCollectionExpectSuccess(collectionId);49 await destroyCollectionExpectSuccess(collectionId);
50 });50 });
51});51});
5252
53describe('Number of tokens per address (ReFungible)', () => {53describe('Number of tokens per address (ReFungible)', () => {
54 let Alice: IKeyringPair;54 let alice: IKeyringPair;
5555
56 before(async () => {56 before(async () => {
57 await usingApi(async () => {57 await usingApi(async () => {
58 Alice = privateKey('//Alice');58 alice = privateKey('//Alice');
59 });59 });
60 });60 });
6161
62 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {62 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {
63 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});63 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
64 await setCollectionLimitsExpectSuccess(Alice, collectionId, { accountTokenOwnershipLimit: 20 });64 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});
65 for(let i = 0; i < 10; i++){65 for(let i = 0; i < 10; i++){
66 await createItemExpectSuccess(Alice, collectionId, 'ReFungible');66 await createItemExpectSuccess(alice, collectionId, 'ReFungible');
67 }67 }
68 await createItemExpectFailure(Alice, collectionId, 'ReFungible');68 await createItemExpectFailure(alice, collectionId, 'ReFungible');
69 await destroyCollectionExpectSuccess(collectionId);69 await destroyCollectionExpectSuccess(collectionId);
70 });70 });
7171
72 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {72 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {
73 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});73 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
74 await setCollectionLimitsExpectSuccess(Alice, collectionId, { accountTokenOwnershipLimit: 1 });74 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});
75 await createItemExpectSuccess(Alice, collectionId, 'ReFungible');75 await createItemExpectSuccess(alice, collectionId, 'ReFungible');
76 await createItemExpectFailure(Alice, collectionId, 'ReFungible');76 await createItemExpectFailure(alice, collectionId, 'ReFungible');
77 await destroyCollectionExpectSuccess(collectionId);77 await destroyCollectionExpectSuccess(collectionId);
78 });78 });
79});79});
8080
81describe('Sponsor timeout (NFT)', () => {81describe('Sponsor timeout (NFT)', () => {
82 let Alice: IKeyringPair;82 let alice: IKeyringPair;
83 let Bob: IKeyringPair;83 let bob: IKeyringPair;
84 let Charlie: IKeyringPair;84 let charlie: IKeyringPair;
8585
86 before(async () => {86 before(async () => {
87 await usingApi(async () => {87 await usingApi(async () => {
88 Alice = privateKey('//Alice');88 alice = privateKey('//Alice');
89 Bob = privateKey('//Bob');89 bob = privateKey('//Bob');
90 Charlie = privateKey('//Charlie');90 charlie = privateKey('//Charlie');
91 });91 });
92 });92 });
9393
94 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {94 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {
95 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });95 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
96 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 7 });96 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
97 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');97 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
98 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);98 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
99 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');99 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
100 await transferExpectSuccess(collectionId, tokenId, Alice, Bob);100 await transferExpectSuccess(collectionId, tokenId, alice, bob);
101 const aliceBalanceBefore = await getFreeBalance(Alice);101 const aliceBalanceBefore = await getFreeBalance(alice);
102102
103 // check setting SponsorTimeout = 5, fail103 // check setting SponsorTimeout = 5, fail
104 await waitNewBlocks(5);104 await waitNewBlocks(5);
105 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);105 await transferExpectSuccess(collectionId, tokenId, bob, charlie);
106 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(Alice);106 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);
107 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);107 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
108108
109 // check setting SponsorTimeout = 7, success109 // check setting SponsorTimeout = 7, success
110 await waitNewBlocks(2); // 5 + 2110 await waitNewBlocks(2); // 5 + 2
111 await transferExpectSuccess(collectionId, tokenId, Charlie, Bob);111 await transferExpectSuccess(collectionId, tokenId, charlie, bob);
112 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(Alice);112 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);
113 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;113 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
114 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);114 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
115 await destroyCollectionExpectSuccess(collectionId);115 await destroyCollectionExpectSuccess(collectionId);
116 });116 });
117117
118 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {118 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
119119
120 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });120 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
121 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 1 });121 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
122 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');122 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
123 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);123 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
124 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');124 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
125 await transferExpectSuccess(collectionId, tokenId, Alice, Bob);125 await transferExpectSuccess(collectionId, tokenId, alice, bob);
126 const aliceBalanceBefore = await getFreeBalance(Alice);126 const aliceBalanceBefore = await getFreeBalance(alice);
127127
128 // check setting SponsorTimeout = 1, fail128 // check setting SponsorTimeout = 1, fail
129 await waitNewBlocks(1);129 await waitNewBlocks(1);
130 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);130 await transferExpectSuccess(collectionId, tokenId, bob, charlie);
131 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(Alice);131 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);
132 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);132 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
133133
134 // check setting SponsorTimeout = 5, success134 // check setting SponsorTimeout = 5, success
135 await waitNewBlocks(4);135 await waitNewBlocks(4);
136 await transferExpectSuccess(collectionId, tokenId, Charlie, Bob);136 await transferExpectSuccess(collectionId, tokenId, charlie, bob);
137 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(Alice);137 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);
138 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;138 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
139 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);139 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
140 await destroyCollectionExpectSuccess(collectionId);140 await destroyCollectionExpectSuccess(collectionId);
141 });141 });
142});142});
143143
144describe('Sponsor timeout (Fungible)', () => {144describe('Sponsor timeout (Fungible)', () => {
145 let Alice: IKeyringPair;145 let alice: IKeyringPair;
146 let Bob: IKeyringPair;146 let bob: IKeyringPair;
147 let Charlie: IKeyringPair;147 let charlie: IKeyringPair;
148148
149 before(async () => {149 before(async () => {
150 await usingApi(async () => {150 await usingApi(async () => {
151 Alice = privateKey('//Alice');151 alice = privateKey('//Alice');
152 Bob = privateKey('//Bob');152 bob = privateKey('//Bob');
153 Charlie = privateKey('//Charlie');153 charlie = privateKey('//Charlie');
154 });154 });
155 });155 });
156156
157 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {157 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {
158 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});158 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
159 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 7 });159 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
160 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'Fungible');160 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');
161 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);161 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
162 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');162 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
163 await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 10, 'Fungible');163 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');
164 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');164 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
165 const aliceBalanceBefore = await getFreeBalance(Alice);165 const aliceBalanceBefore = await getFreeBalance(alice);
166166
167 // check setting SponsorTimeout = 5, fail167 // check setting SponsorTimeout = 5, fail
168 await waitNewBlocks(5);168 await waitNewBlocks(5);
169 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');169 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
170 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(Alice);170 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);
171 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);171 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
172172
173 // check setting SponsorTimeout = 7, success173 // check setting SponsorTimeout = 7, success
174 await waitNewBlocks(2); // 5 + 2174 await waitNewBlocks(2); // 5 + 2
175 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');175 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
176 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(Alice);176 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);
177 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;177 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
178 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);178 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
179179
183 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {183 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
184184
185 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});185 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
186 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 1 });186 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
187 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'Fungible');187 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');
188 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);188 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
189 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');189 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
190 await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 10, 'Fungible');190 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');
191 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');191 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
192 const aliceBalanceBefore = await getFreeBalance(Alice);192 const aliceBalanceBefore = await getFreeBalance(alice);
193193
194 // check setting SponsorTimeout = 1, fail194 // check setting SponsorTimeout = 1, fail
195 await waitNewBlocks(1);195 await waitNewBlocks(1);
196 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');196 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
197 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(Alice);197 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);
198 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);198 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
199199
200 // check setting SponsorTimeout = 5, success200 // check setting SponsorTimeout = 5, success
201 await waitNewBlocks(4);201 await waitNewBlocks(4);
202 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');202 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
203 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(Alice);203 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);
204 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;204 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
205 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);205 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
206206
209});209});
210210
211describe('Sponsor timeout (ReFungible)', () => {211describe('Sponsor timeout (ReFungible)', () => {
212 let Alice: IKeyringPair;212 let alice: IKeyringPair;
213 let Bob: IKeyringPair;213 let bob: IKeyringPair;
214 let Charlie: IKeyringPair;214 let charlie: IKeyringPair;
215215
216 before(async () => {216 before(async () => {
217 await usingApi(async () => {217 await usingApi(async () => {
218 Alice = privateKey('//Alice');218 alice = privateKey('//Alice');
219 Bob = privateKey('//Bob');219 bob = privateKey('//Bob');
220 Charlie = privateKey('//Charlie');220 charlie = privateKey('//Charlie');
221 });221 });
222 });222 });
223223
224 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {224 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {
225 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});225 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
226 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 7 });226 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
227 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible');227 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');
228 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);228 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
229 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');229 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
230 await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 100, 'ReFungible');230 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');
231 const aliceBalanceBefore = await getFreeBalance(Alice);231 const aliceBalanceBefore = await getFreeBalance(alice);
232232
233 // check setting SponsorTimeout = 5, fail233 // check setting SponsorTimeout = 5, fail
234 await waitNewBlocks(5);234 await waitNewBlocks(5);
235 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');235 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
236 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(Alice);236 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);
237 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);237 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
238238
239 // check setting SponsorTimeout = 7, success239 // check setting SponsorTimeout = 7, success
240 await waitNewBlocks(2); // 5 + 2240 await waitNewBlocks(2); // 5 + 2
241 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');241 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
242 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(Alice);242 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);
243 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;243 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
244 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);244 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
245 await destroyCollectionExpectSuccess(collectionId);245 await destroyCollectionExpectSuccess(collectionId);
246 });246 });
247247
248 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {248 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
249249
250 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });250 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
251 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 1 });251 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
252 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');252 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
253 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);253 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
254 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');254 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
255 await transferExpectSuccess(collectionId, tokenId, Alice, Bob);255 await transferExpectSuccess(collectionId, tokenId, alice, bob);
256 const aliceBalanceBefore = await getFreeBalance(Alice);256 const aliceBalanceBefore = await getFreeBalance(alice);
257257
258 // check setting SponsorTimeout = 1, fail258 // check setting SponsorTimeout = 1, fail
259 await waitNewBlocks(1);259 await waitNewBlocks(1);
260 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);260 await transferExpectSuccess(collectionId, tokenId, bob, charlie);
261 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(Alice);261 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);
262 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);262 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
263263
264 // check setting SponsorTimeout = 5, success264 // check setting SponsorTimeout = 5, success
265 await waitNewBlocks(4);265 await waitNewBlocks(4);
266 await transferExpectSuccess(collectionId, tokenId, Charlie, Bob);266 await transferExpectSuccess(collectionId, tokenId, charlie, bob);
267 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(Alice);267 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);
268 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;268 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
269 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);269 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
270 await destroyCollectionExpectSuccess(collectionId);270 await destroyCollectionExpectSuccess(collectionId);
271 });271 });
272});272});
273273
274describe('Collection zero limits (NFT)', () => {274describe('Collection zero limits (NFT)', () => {
275 let Alice: IKeyringPair;275 let alice: IKeyringPair;
276 let Bob: IKeyringPair;276 let bob: IKeyringPair;
277 let Charlie: IKeyringPair;277 let charlie: IKeyringPair;
278278
279 before(async () => {279 before(async () => {
280 await usingApi(async () => {280 await usingApi(async () => {
281 Alice = privateKey('//Alice');281 alice = privateKey('//Alice');
282 Bob = privateKey('//Bob');282 bob = privateKey('//Bob');
283 Charlie = privateKey('//Charlie');283 charlie = privateKey('//Charlie');
284 });284 });
285 });285 });
286286
287 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {287 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {
288 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });288 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
289 await setCollectionLimitsExpectSuccess(Alice, collectionId, { accountTokenOwnershipLimit: 0 });289 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});
290 for(let i = 0; i < 10; i++){290 for(let i = 0; i < 10; i++){
291 await createItemExpectSuccess(Alice, collectionId, 'NFT');291 await createItemExpectSuccess(alice, collectionId, 'NFT');
292 }292 }
293 await createItemExpectFailure(Alice, collectionId, 'NFT');293 await createItemExpectFailure(alice, collectionId, 'NFT');
294 });294 });
295295
296 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {296 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
297297
298 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });298 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
299 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 0 });299 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
300 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');300 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
301 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);301 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
302 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');302 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
303 await transferExpectSuccess(collectionId, tokenId, Alice, Bob);303 await transferExpectSuccess(collectionId, tokenId, alice, bob);
304 const aliceBalanceBefore = await getFreeBalance(Alice);304 const aliceBalanceBefore = await getFreeBalance(alice);
305305
306 // check setting SponsorTimeout = 0, success with next block306 // check setting SponsorTimeout = 0, success with next block
307 await waitNewBlocks(1);307 await waitNewBlocks(1);
308 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);308 await transferExpectSuccess(collectionId, tokenId, bob, charlie);
309 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(Alice);309 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);
310 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;310 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
311 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);311 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
312 });312 });
313});313});
314314
315describe('Collection zero limits (Fungible)', () => {315describe('Collection zero limits (Fungible)', () => {
316 let Alice: IKeyringPair;316 let alice: IKeyringPair;
317 let Bob: IKeyringPair;317 let bob: IKeyringPair;
318 let Charlie: IKeyringPair;318 let charlie: IKeyringPair;
319319
320 before(async () => {320 before(async () => {
321 await usingApi(async () => {321 await usingApi(async () => {
322 Alice = privateKey('//Alice');322 alice = privateKey('//Alice');
323 Bob = privateKey('//Bob');323 bob = privateKey('//Bob');
324 Charlie = privateKey('//Charlie');324 charlie = privateKey('//Charlie');
325 });325 });
326 });326 });
327327
328 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {328 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
329 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});329 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
330 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 0 });330 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
331 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'Fungible');331 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');
332 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);332 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
333 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');333 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
334 await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 10, 'Fungible');334 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');
335 const aliceBalanceBefore = await getFreeBalance(Alice);335 const aliceBalanceBefore = await getFreeBalance(alice);
336 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');336 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
337337
338 // check setting SponsorTimeout = 0, success with next block338 // check setting SponsorTimeout = 0, success with next block
339 await waitNewBlocks(1);339 await waitNewBlocks(1);
340 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');340 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
341 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(Alice);341 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);
342 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;342 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
343 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);343 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
344 });344 });
345});345});
346346
347describe('Collection zero limits (ReFungible)', () => {347describe('Collection zero limits (ReFungible)', () => {
348 let Alice: IKeyringPair;348 let alice: IKeyringPair;
349 let Bob: IKeyringPair;349 let bob: IKeyringPair;
350 let Charlie: IKeyringPair;350 let charlie: IKeyringPair;
351351
352 before(async () => {352 before(async () => {
353 await usingApi(async () => {353 await usingApi(async () => {
354 Alice = privateKey('//Alice');354 alice = privateKey('//Alice');
355 Bob = privateKey('//Bob');355 bob = privateKey('//Bob');
356 Charlie = privateKey('//Charlie');356 charlie = privateKey('//Charlie');
357 });357 });
358 });358 });
359359
360 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {360 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {
361 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});361 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
362 await setCollectionLimitsExpectSuccess(Alice, collectionId, { accountTokenOwnershipLimit: 0 });362 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});
363 for(let i = 0; i < 10; i++){363 for(let i = 0; i < 10; i++){
364 await createItemExpectSuccess(Alice, collectionId, 'ReFungible');364 await createItemExpectSuccess(alice, collectionId, 'ReFungible');
365 }365 }
366 await createItemExpectFailure(Alice, collectionId, 'ReFungible');366 await createItemExpectFailure(alice, collectionId, 'ReFungible');
367 });367 });
368368
369 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {369 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
370370
371 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'ReFungible' } });371 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
372 await setCollectionLimitsExpectSuccess(Alice, collectionId, { sponsorTimeout: 0 });372 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
373 const tokenId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible');373 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');
374 await setCollectionSponsorExpectSuccess(collectionId, Alice.address);374 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
375 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');375 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
376 await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 100, 'ReFungible');376 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');
377 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');377 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
378 const aliceBalanceBefore = await getFreeBalance(Alice);378 const aliceBalanceBefore = await getFreeBalance(alice);
379379
380 // check setting SponsorTimeout = 0, success with next block380 // check setting SponsorTimeout = 0, success with next block
381 await waitNewBlocks(1);381 await waitNewBlocks(1);
382 await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');382 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
383 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(Alice);383 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);
384 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;384 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
385 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);385 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
386 });386 });
modifiedtests/src/metadataUpdate.test.tsdiffbeforeafterboth
27describe('Metadata update permissions with ItemOwner flag', () => {27describe('Metadata update permissions with ItemOwner flag', () => {
28 it('ItemOwner can set variable metadata with ItemOwner permission flag', async () => {28 it('ItemOwner can set variable metadata with ItemOwner permission flag', async () => {
29 await usingApi(async () => {29 await usingApi(async () => {
30 const Alice = privateKey('//Alice');30 const alice = privateKey('//Alice');
3131
32 const data = [1, 2, 254, 255];32 const data = [1, 2, 254, 255];
3333
34 // nft34 // nft
35 const nftCollectionId = await createCollectionExpectSuccess();35 const nftCollectionId = await createCollectionExpectSuccess();
36 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');36 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
37 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'ItemOwner');37 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'ItemOwner');
3838
39 await setVariableMetaDataExpectSuccess(Alice, nftCollectionId, newNftTokenId, data);39 await setVariableMetaDataExpectSuccess(alice, nftCollectionId, newNftTokenId, data);
40 });40 });
41 });41 });
4242
43 it('Admin can\'n set variable metadata with ItemOwner permission flag', async () => {43 it('Admin can\'n set variable metadata with ItemOwner permission flag', async () => {
44 await usingApi(async () => {44 await usingApi(async () => {
45 const Alice = privateKey('//Alice');45 const alice = privateKey('//Alice');
46 const Bob = privateKey('//Bob');46 const bob = privateKey('//Bob');
47 47
48 const data = [1, 2, 254, 255];48 const data = [1, 2, 254, 255];
49 49
50 // nft50 // nft
51 const nftCollectionId = await createCollectionExpectSuccess();51 const nftCollectionId = await createCollectionExpectSuccess();
52 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');52 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
53 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'ItemOwner');53 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'ItemOwner');
5454
55 await setMintPermissionExpectSuccess(Alice, nftCollectionId, true);55 await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
56 await addToWhiteListExpectSuccess(Alice, nftCollectionId, Bob.address);56 await addToWhiteListExpectSuccess(alice, nftCollectionId, bob.address);
57 await addCollectionAdminExpectSuccess(Alice, nftCollectionId, Bob);57 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
58 58
59 await setVariableMetaDataExpectFailure(Bob, nftCollectionId, newNftTokenId, data);59 await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
60 });60 });
61 });61 });
6262
63 it('User can\'n set variable metadata with ItemOwner permission flag', async () => {63 it('User can\'n set variable metadata with ItemOwner permission flag', async () => {
64 await usingApi(async () => {64 await usingApi(async () => {
65 const Alice = privateKey('//Alice');65 const alice = privateKey('//Alice');
66 const Bob = privateKey('//Bob');66 const bob = privateKey('//Bob');
67 67
68 const data = [1, 2, 254, 255];68 const data = [1, 2, 254, 255];
69 69
70 // nft70 // nft
71 const nftCollectionId = await createCollectionExpectSuccess();71 const nftCollectionId = await createCollectionExpectSuccess();
72 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');72 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
73 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'ItemOwner');73 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'ItemOwner');
7474
75 await setMintPermissionExpectSuccess(Alice, nftCollectionId, true); 75 await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
76 await setVariableMetaDataExpectFailure(Bob, nftCollectionId, newNftTokenId, data);76 await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
77 });77 });
78 });78 });
79});79});
8080
81describe('Metadata update permissions with Admin flag', () => {81describe('Metadata update permissions with Admin flag', () => {
82 it('Admin can set variable metadata with Admin permission flag', async () => {82 it('Admin can set variable metadata with Admin permission flag', async () => {
83 await usingApi(async () => {83 await usingApi(async () => {
84 const Alice = privateKey('//Alice');84 const alice = privateKey('//Alice');
85 const Bob = privateKey('//Bob');85 const bob = privateKey('//Bob');
86 86
87 const data = [1, 2, 254, 255];87 const data = [1, 2, 254, 255];
88 88
89 // nft89 // nft
90 const nftCollectionId = await createCollectionExpectSuccess();90 const nftCollectionId = await createCollectionExpectSuccess();
91 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');91 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
92 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'Admin');92 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'Admin');
9393
94 await setMintPermissionExpectSuccess(Alice, nftCollectionId, true);94 await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
95 await addToWhiteListExpectSuccess(Alice, nftCollectionId, Bob.address);95 await addToWhiteListExpectSuccess(alice, nftCollectionId, bob.address);
96 await addCollectionAdminExpectSuccess(Alice, nftCollectionId, Bob);96 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
97 97
98 await setVariableMetaDataExpectSuccess(Bob, nftCollectionId, newNftTokenId, data);98 await setVariableMetaDataExpectSuccess(bob, nftCollectionId, newNftTokenId, data);
99 });99 });
100 });100 });
101101
102 it('User can\'n can set variable metadata with Admin permission flag', async () => {102 it('User can\'n can set variable metadata with Admin permission flag', async () => {
103 await usingApi(async () => {103 await usingApi(async () => {
104 const Alice = privateKey('//Alice');104 const alice = privateKey('//Alice');
105 const Bob = privateKey('//Bob');105 const bob = privateKey('//Bob');
106 106
107 const data = [1, 2, 254, 255];107 const data = [1, 2, 254, 255];
108 108
109 // nft109 // nft
110 const nftCollectionId = await createCollectionExpectSuccess();110 const nftCollectionId = await createCollectionExpectSuccess();
111 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');111 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
112 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'Admin');112 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'Admin');
113113
114 await setMintPermissionExpectSuccess(Alice, nftCollectionId, true);114 await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
115 await addToWhiteListExpectSuccess(Alice, nftCollectionId, Bob.address);115 await addToWhiteListExpectSuccess(alice, nftCollectionId, bob.address);
116 await addCollectionAdminExpectSuccess(Alice, nftCollectionId, Bob);116 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
117 117
118 await setVariableMetaDataExpectSuccess(Bob, nftCollectionId, newNftTokenId, data);118 await setVariableMetaDataExpectSuccess(bob, nftCollectionId, newNftTokenId, data);
119 });119 });
120 });120 });
121121
122 it('ItemOwner can\'n can set variable metadata with Admin permission flag', async () => {122 it('ItemOwner can\'n can set variable metadata with Admin permission flag', async () => {
123 await usingApi(async () => {123 await usingApi(async () => {
124 const Alice = privateKey('//Alice');124 const alice = privateKey('//Alice');
125 const Bob = privateKey('//Bob');125 const bob = privateKey('//Bob');
126 126
127 const data = [1, 2, 254, 255];127 const data = [1, 2, 254, 255];
128 128
129 // nft129 // nft
130 const nftCollectionId = await createCollectionExpectSuccess();130 const nftCollectionId = await createCollectionExpectSuccess();
131 await enablePublicMintingExpectSuccess(Alice, nftCollectionId);131 await enablePublicMintingExpectSuccess(alice, nftCollectionId);
132 await addToWhiteListExpectSuccess(Alice, nftCollectionId, Bob.address);132 await addToWhiteListExpectSuccess(alice, nftCollectionId, bob.address);
133 await enableWhiteListExpectSuccess(Alice, nftCollectionId);133 await enableWhiteListExpectSuccess(alice, nftCollectionId);
134 const newNftTokenId = await createItemExpectSuccess(Bob, nftCollectionId, 'NFT');134 const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT');
135 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'Admin');135 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'Admin');
136 136
137 await setVariableMetaDataExpectFailure(Bob, nftCollectionId, newNftTokenId, data);137 await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
138 });138 });
139 });139 });
140});140});
141141
142describe('Metadata update permissions with None flag', () => {142describe('Metadata update permissions with None flag', () => {
143 it('Nobody can set variable metadata with None flag (Regular)', async () => {143 it('Nobody can set variable metadata with None flag (Regular)', async () => {
144 await usingApi(async () => {144 await usingApi(async () => {
145 const Alice = privateKey('//Alice');145 const alice = privateKey('//Alice');
146 const Bob = privateKey('//Bob');146 const bob = privateKey('//Bob');
147 147
148 const data = [1, 2, 254, 255];148 const data = [1, 2, 254, 255];
149 149
150 // nft150 // nft
151 const nftCollectionId = await createCollectionExpectSuccess();151 const nftCollectionId = await createCollectionExpectSuccess();
152 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');152 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
153 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'None');153 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
154 154
155 await setVariableMetaDataExpectFailure(Bob, nftCollectionId, newNftTokenId, data);155 await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
156 });156 });
157 });157 });
158158
159 it('Nobody can set variable metadata with None flag (Admin)', async () => {159 it('Nobody can set variable metadata with None flag (Admin)', async () => {
160 await usingApi(async () => {160 await usingApi(async () => {
161 const Alice = privateKey('//Alice');161 const alice = privateKey('//Alice');
162 const Bob = privateKey('//Bob');162 const bob = privateKey('//Bob');
163 163
164 const data = [1, 2, 254, 255];164 const data = [1, 2, 254, 255];
165 165
166 // nft166 // nft
167 const nftCollectionId = await createCollectionExpectSuccess();167 const nftCollectionId = await createCollectionExpectSuccess();
168 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');168 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
169 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'None');169 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
170 170
171 await setMintPermissionExpectSuccess(Alice, nftCollectionId, true);171 await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
172 await addToWhiteListExpectSuccess(Alice, nftCollectionId, Bob.address);172 await addToWhiteListExpectSuccess(alice, nftCollectionId, bob.address);
173 await addCollectionAdminExpectSuccess(Alice, nftCollectionId, Bob);173 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
174 174
175 await setVariableMetaDataExpectFailure(Bob, nftCollectionId, newNftTokenId, data);175 await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
176 });176 });
177 });177 });
178178
179 it('Nobody can set variable metadata with None flag (ItemOwner)', async () => {179 it('Nobody can set variable metadata with None flag (ItemOwner)', async () => {
180 await usingApi(async () => {180 await usingApi(async () => {
181 const Alice = privateKey('//Alice');181 const alice = privateKey('//Alice');
182 182
183 const data = [1, 2, 254, 255];183 const data = [1, 2, 254, 255];
184 184
185 // nft185 // nft
186 const nftCollectionId = await createCollectionExpectSuccess();186 const nftCollectionId = await createCollectionExpectSuccess();
187 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');187 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
188 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'None');188 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
189 189
190 await setVariableMetaDataExpectFailure(Alice, nftCollectionId, newNftTokenId, data);190 await setVariableMetaDataExpectFailure(alice, nftCollectionId, newNftTokenId, data);
191 });191 });
192 });192 });
193193
194 it('Nobody can set variable metadata flag after freeze', async () => {194 it('Nobody can set variable metadata flag after freeze', async () => {
195 await usingApi(async () => {195 await usingApi(async () => {
196 const Alice = privateKey('//Alice');196 const alice = privateKey('//Alice');
197 197
198 // nft198 // nft
199 const nftCollectionId = await createCollectionExpectSuccess();199 const nftCollectionId = await createCollectionExpectSuccess();
200 await setMetadataUpdatePermissionFlagExpectSuccess(Alice, nftCollectionId, 'None');200 await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
201 await setMetadataUpdatePermissionFlagExpectFailure(Alice, nftCollectionId, 'Admin'); 201 await setMetadataUpdatePermissionFlagExpectFailure(alice, nftCollectionId, 'Admin');
202 });202 });
203 });203 });
204});204});
modifiedtests/src/mintModes.test.tsdiffbeforeafterboth
53 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });53 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
54 await enableWhiteListExpectSuccess(alice, collectionId);54 await enableWhiteListExpectSuccess(alice, collectionId);
55 await setMintPermissionExpectSuccess(alice, collectionId, true);55 await setMintPermissionExpectSuccess(alice, collectionId, true);
56 await addCollectionAdminExpectSuccess(alice, collectionId, bob);56 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
57 await createItemExpectSuccess(bob, collectionId, 'NFT');57 await createItemExpectSuccess(bob, collectionId, 'NFT');
58 });58 });
59 });59 });
81 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });81 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
82 await disableWhiteListExpectSuccess(alice, collectionId);82 await disableWhiteListExpectSuccess(alice, collectionId);
83 await setMintPermissionExpectSuccess(alice, collectionId, true);83 await setMintPermissionExpectSuccess(alice, collectionId, true);
84 await addCollectionAdminExpectSuccess(alice, collectionId, bob);84 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
85 await createItemExpectSuccess(bob, collectionId, 'NFT');85 await createItemExpectSuccess(bob, collectionId, 'NFT');
86 });86 });
87 });87 });
131 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });131 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
132 await disableWhiteListExpectSuccess(alice, collectionId);132 await disableWhiteListExpectSuccess(alice, collectionId);
133 await setMintPermissionExpectSuccess(alice, collectionId, false);133 await setMintPermissionExpectSuccess(alice, collectionId, false);
134 await addCollectionAdminExpectSuccess(alice, collectionId, bob);134 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
135 await createItemExpectSuccess(bob, collectionId, 'NFT');135 await createItemExpectSuccess(bob, collectionId, 'NFT');
136 });136 });
137 });137 });
modifiedtests/src/overflow.test.tsdiffbeforeafterboth
8import chaiAsPromised from 'chai-as-promised';8import chaiAsPromised from 'chai-as-promised';
9import privateKey from './substrate/privateKey';9import privateKey from './substrate/privateKey';
10import usingApi from './substrate/substrate-api';10import usingApi from './substrate/substrate-api';
11import { approveExpectFail, approveExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, getAllowance, getFungibleBalance, transferExpectFailure, transferExpectSuccess, transferFromExpectFail, transferFromExpectSuccess, U128_MAX } from './util/helpers';11import {approveExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, getAllowance, getBalance, transferExpectFailure, transferExpectSuccess, transferFromExpectFail, transferFromExpectSuccess, U128_MAX} from './util/helpers';
1212
13chai.use(chaiAsPromised);13chai.use(chaiAsPromised);
14const expect = chai.expect;14const expect = chai.expect;
27 });27 });
2828
29 it('fails when overflows on transfer', async () => {29 it('fails when overflows on transfer', async () => {
30 await usingApi(async api => {
30 const fungibleCollectionId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });31 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
3132
32 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, { Value: U128_MAX });33 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: U128_MAX});
35 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, { Value: 1n });36 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 1n});
36 await transferExpectFailure(fungibleCollectionId, 0, alice, bob, 1);37 await transferExpectFailure(fungibleCollectionId, 0, alice, bob, 1);
3738
38 expect(await getFungibleBalance(fungibleCollectionId, alice.address)).to.equal(1n);39 expect(await getBalance(api, fungibleCollectionId, alice.address, 0)).to.equal(1n);
39 expect(await getFungibleBalance(fungibleCollectionId, bob.address)).to.equal(U128_MAX);40 expect(await getBalance(api, fungibleCollectionId, bob.address, 0)).to.equal(U128_MAX);
41 });
40 });42 });
41
42 it('fails on allowance overflow', async () => {
43 const fungibleCollectionId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });
44
45 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, { Value: U128_MAX });
46 await approveExpectSuccess(fungibleCollectionId, 0, alice, bob, U128_MAX);
47 await approveExpectFail(fungibleCollectionId, 0, alice, bob, U128_MAX);
48 });
4943
50 it('fails when overflows on transferFrom', async () => {44 it('fails when overflows on transferFrom', async () => {
45 await usingApi(async api => {
51 const fungibleCollectionId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });46 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
52
53 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, { Value: U128_MAX });47 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: U128_MAX});
54 await approveExpectSuccess(fungibleCollectionId, 0, alice, bob, U128_MAX);48 await approveExpectSuccess(fungibleCollectionId, 0, alice, bob.address, U128_MAX);
55 await transferFromExpectSuccess(fungibleCollectionId, 0, bob, alice, charlie, U128_MAX, 'Fungible');49 await transferFromExpectSuccess(fungibleCollectionId, 0, bob, alice, charlie, U128_MAX, 'Fungible');
5650
57 expect(await getFungibleBalance(fungibleCollectionId, charlie.address)).to.equal(U128_MAX);51 expect(await getBalance(api, fungibleCollectionId, charlie.address, 0)).to.equal(U128_MAX);
58 expect((await getAllowance(fungibleCollectionId, 0, alice.address, bob.address)).toString()).to.equal('0');52 expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, 0)).to.equal(0n);
5953
60 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, { Value: U128_MAX });54 await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: U128_MAX});
61 await approveExpectSuccess(fungibleCollectionId, 0, alice, bob, 1n);55 await approveExpectSuccess(fungibleCollectionId, 0, alice, bob.address, 1n);
62 await transferFromExpectFail(fungibleCollectionId, 0, bob, alice, charlie, 1);56 await transferFromExpectFail(fungibleCollectionId, 0, bob, alice, charlie, 1);
6357
64 expect(await getFungibleBalance(fungibleCollectionId, charlie.address)).to.equal(U128_MAX);58 expect(await getBalance(api, fungibleCollectionId, charlie.address, 0)).to.equal(U128_MAX);
65 expect((await getAllowance(fungibleCollectionId, 0, alice.address, bob.address)).toString()).to.equal('1');59 expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, 0)).to.equal(1n);
60 });
66 });61 });
67});62});
6863
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
14// Pallets that must always be present14// Pallets that must always be present
15const requiredPallets = [15const requiredPallets = [
16 'balances',16 'balances',
17 'common',
17 'randomnesscollectiveflip',18 'randomnesscollectiveflip',
18 'timestamp',19 'timestamp',
19 'transactionpayment',20 'transactionpayment',
28 'evmmigration',29 'evmmigration',
29 'evmtransactionpayment',30 'evmtransactionpayment',
30 'ethereum',31 'ethereum',
32 'fungible',
31 'xcmpqueue',33 'xcmpqueue',
32 'polkadotxcm',34 'polkadotxcm',
33 'cumulusxcm',35 'cumulusxcm',
34 'dmpqueue',36 'dmpqueue',
35 'inflation',37 'inflation',
36 'nft',38 'nft',
39 'nonfungible',
40 'refungible',
37 'scheduler',41 'scheduler',
38 'nftpayment',42 'nftpayment',
39 'charging',43 'charging',
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
8import chaiAsPromised from 'chai-as-promised';8import chaiAsPromised from 'chai-as-promised';
9import privateKey from './substrate/privateKey';9import privateKey from './substrate/privateKey';
10import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';10import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
11import {createCollectionExpectSuccess, destroyCollectionExpectSuccess, normalizeAccountId} from './util/helpers';11import {createCollectionExpectSuccess, destroyCollectionExpectSuccess, getAdminList, normalizeAccountId} from './util/helpers';
1212
13chai.use(chaiAsPromised);13chai.use(chaiAsPromised);
14const expect = chai.expect;14const expect = chai.expect;
17 it('Remove collection admin.', async () => {17 it('Remove collection admin.', async () => {
18 await usingApi(async (api: ApiPromise) => {18 await usingApi(async (api: ApiPromise) => {
19 const collectionId = await createCollectionExpectSuccess();19 const collectionId = await createCollectionExpectSuccess();
20 const Alice = privateKey('//Alice');20 const alice = privateKey('//Alice');
21 const Bob = privateKey('//Bob');21 const bob = privateKey('//Bob');
22 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();22 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
23 expect(collection.owner).to.be.deep.eq(Alice.address);23 expect(collection.owner.toString()).to.be.deep.eq(alice.address);
24 // first - add collection admin Bob24 // first - add collection admin Bob
25 const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));25 const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
26 await submitTransactionAsync(Alice, addAdminTx);26 await submitTransactionAsync(alice, addAdminTx);
2727
28 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId)).toJSON();28 const adminListAfterAddAdmin = await getAdminList(api, collectionId);
29 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(Bob.address));29 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
3030
31 // then remove bob from admins of collection31 // then remove bob from admins of collection
32 const removeAdminTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));32 const removeAdminTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
33 await submitTransactionAsync(Alice, removeAdminTx);33 await submitTransactionAsync(alice, removeAdminTx);
3434
35 const adminListAfterRemoveAdmin: any = (await api.query.nft.adminList(collectionId)).toJSON;35 const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);
36 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(Bob.address));36 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(bob.address));
37 });37 });
38 });38 });
3939
40 it('Remove collection admin by admin.', async () => {40 it('Remove collection admin by admin.', async () => {
41 await usingApi(async (api: ApiPromise) => {41 await usingApi(async (api: ApiPromise) => {
42 const collectionId = await createCollectionExpectSuccess();42 const collectionId = await createCollectionExpectSuccess();
43 const Alice = privateKey('//Alice');43 const alice = privateKey('//Alice');
44 const Bob = privateKey('//Bob');44 const bob = privateKey('//Bob');
45 const Charlie = privateKey('//Charlie');45 const charlie = privateKey('//Charlie');
46 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();46 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
47 expect(collection.owner).to.be.deep.eq(Alice.address);47 expect(collection.owner.toString()).to.be.eq(alice.address);
48 // first - add collection admin Bob48 // first - add collection admin Bob
49 const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));49 const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
50 await submitTransactionAsync(Alice, addAdminTx);50 await submitTransactionAsync(alice, addAdminTx);
5151
52 const addAdminTx2 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Charlie.address));52 const addAdminTx2 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(charlie.address));
53 await submitTransactionAsync(Alice, addAdminTx2);53 await submitTransactionAsync(alice, addAdminTx2);
5454
55 const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId)).toJSON();55 const adminListAfterAddAdmin = await getAdminList(api, collectionId);
56 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(Bob.address));56 expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(bob.address));
5757
58 // then remove bob from admins of collection58 // then remove bob from admins of collection
59 const removeAdminTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));59 const removeAdminTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
60 await submitTransactionAsync(Charlie, removeAdminTx);60 await submitTransactionAsync(charlie, removeAdminTx);
6161
62 const adminListAfterRemoveAdmin: any = (await api.query.nft.adminList(collectionId)).toJSON;62 const adminListAfterRemoveAdmin = await getAdminList(api, collectionId);
63 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(Bob.address));63 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(bob.address));
64 });64 });
65 });65 });
6666
67 it('Remove admin from collection that has no admins', async () => {67 it('Remove admin from collection that has no admins', async () => {
68 await usingApi(async (api: ApiPromise) => {68 await usingApi(async (api: ApiPromise) => {
69 const Alice = privateKey('//Alice');69 const alice = privateKey('//Alice');
70 const collectionId = await createCollectionExpectSuccess();70 const collectionId = await createCollectionExpectSuccess();
7171
72 const adminListBeforeAddAdmin: any = (await api.query.nft.adminList(collectionId));72 const adminListBeforeAddAdmin = await getAdminList(api, collectionId);
73 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);73 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
7474
75 const tx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Alice.address));75 const tx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(alice.address));
76 await submitTransactionAsync(Alice, tx);76 await submitTransactionAsync(alice, tx);
77 });77 });
78 });78 });
79});79});
98 await usingApi(async (api: ApiPromise) => {98 await usingApi(async (api: ApiPromise) => {
99 // tslint:disable-next-line: no-bitwise99 // tslint:disable-next-line: no-bitwise
100 const collectionId = await createCollectionExpectSuccess();100 const collectionId = await createCollectionExpectSuccess();
101 const Alice = privateKey('//Alice');101 const alice = privateKey('//Alice');
102 const Bob = privateKey('//Bob');102 const bob = privateKey('//Bob');
103103
104 await destroyCollectionExpectSuccess(collectionId);104 await destroyCollectionExpectSuccess(collectionId);
105105
106 const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));106 const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
107 await expect(submitTransactionExpectFailAsync(Alice, changeOwnerTx)).to.be.rejected;107 await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;
108108
109 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)109 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
110 await createCollectionExpectSuccess();110 await createCollectionExpectSuccess();
114 it('Regular user Can\'t remove collection admin', async () => {114 it('Regular user Can\'t remove collection admin', async () => {
115 await usingApi(async (api: ApiPromise) => {115 await usingApi(async (api: ApiPromise) => {
116 const collectionId = await createCollectionExpectSuccess();116 const collectionId = await createCollectionExpectSuccess();
117 const Alice = privateKey('//Alice');117 const alice = privateKey('//Alice');
118 const Bob = privateKey('//Bob');118 const bob = privateKey('//Bob');
119 const Charlie = privateKey('//Charlie');119 const charlie = privateKey('//Charlie');
120120
121 const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));121 const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(bob.address));
122 await submitTransactionAsync(Alice, addAdminTx);122 await submitTransactionAsync(alice, addAdminTx);
123123
124 const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));124 const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(bob.address));
125 await expect(submitTransactionExpectFailAsync(Charlie, changeOwnerTx)).to.be.rejected;125 await expect(submitTransactionExpectFailAsync(charlie, changeOwnerTx)).to.be.rejected;
126126
127 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)127 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
128 await createCollectionExpectSuccess();128 await createCollectionExpectSuccess();
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
21} from './util/helpers';21} from './util/helpers';
22import { Keyring } from '@polkadot/api';22import {Keyring} from '@polkadot/api';
23import { IKeyringPair } from '@polkadot/types/types';23import {IKeyringPair} from '@polkadot/types/types';
24import { BigNumber } from 'bignumber.js';
2524
26chai.use(chaiAsPromised);25chai.use(chaiAsPromised);
27const expect = chai.expect;26const expect = chai.expect;
53 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);52 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
5453
55 // Transfer this tokens from unused address to Alice - should fail54 // Transfer this tokens from unused address to Alice - should fail
56 const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());55 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
57 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);56 const zeroToAlice = api.tx.nft.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
58 const badTransaction = async function () { 57 const badTransaction = async function () {
59 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);58 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
60 };59 };
61 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');60 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
62 const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());61 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
6362
64 expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;63 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
65 });64 });
66 });65 });
6766
99 // Find the collection that never existed98 // Find the collection that never existed
100 let collectionId = 0;99 let collectionId = 0;
101 await usingApi(async (api) => {100 await usingApi(async (api) => {
102 collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;101 collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
103 });102 });
104103
105 await removeCollectionSponsorExpectFailure(collectionId);104 await removeCollectionSponsorExpectFailure(collectionId);
108 it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {107 it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {
109 const collectionId = await createCollectionExpectSuccess();108 const collectionId = await createCollectionExpectSuccess();
110 await setCollectionSponsorExpectSuccess(collectionId, bob.address);109 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
111 await addCollectionAdminExpectSuccess(alice, collectionId, bob);110 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
112 await removeCollectionSponsorExpectFailure(collectionId, '//Bob');111 await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
113 });112 });
114113
modifiedtests/src/removeFromContractWhiteList.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/removeFromWhiteList.test.tsdiffbeforeafterboth
107 await usingApi(async () => {107 await usingApi(async () => {
108 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });108 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
109 await enableWhiteListExpectSuccess(alice, collectionId);109 await enableWhiteListExpectSuccess(alice, collectionId);
110 await addCollectionAdminExpectSuccess(alice, collectionId, bob);110 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
111 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);111 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
112 await removeFromWhiteListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));112 await removeFromWhiteListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));
113 expect(await isWhitelisted(collectionId, charlie.address)).to.be.false;113 expect(await isWhitelisted(collectionId, charlie.address)).to.be.false;
118 await usingApi(async () => {118 await usingApi(async () => {
119 const collectionWithoutWhitelistId = await createCollectionExpectSuccess();119 const collectionWithoutWhitelistId = await createCollectionExpectSuccess();
120 await enableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);120 await enableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);
121 await addCollectionAdminExpectSuccess(alice, collectionWithoutWhitelistId, bob);121 await addCollectionAdminExpectSuccess(alice, collectionWithoutWhitelistId, bob.address);
122 await addToWhiteListExpectSuccess(alice, collectionWithoutWhitelistId, charlie.address);122 await addToWhiteListExpectSuccess(alice, collectionWithoutWhitelistId, charlie.address);
123 await disableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);123 await disableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);
124 await removeFromWhiteListExpectSuccess(bob, collectionWithoutWhitelistId, normalizeAccountId(charlie.address));124 await removeFromWhiteListExpectSuccess(bob, collectionWithoutWhitelistId, normalizeAccountId(charlie.address));
modifiedtests/src/rpc.load.tsdiffbeforeafterboth
7import { IKeyringPair } from '@polkadot/types/types';7import {IKeyringPair} from '@polkadot/types/types';
8import { Abi, BlueprintPromise as Blueprint, CodePromise, ContractPromise as Contract } from '@polkadot/api-contract';8import {Abi, BlueprintPromise as Blueprint, CodePromise, ContractPromise as Contract} from '@polkadot/api-contract';
9import { ApiPromise, Keyring } from '@polkadot/api';9import {ApiPromise, Keyring} from '@polkadot/api';
10import { BigNumber } from 'bignumber.js';
11import { findUnusedAddress } from './util/helpers';10import {findUnusedAddress} from './util/helpers';
12import fs from 'fs';11import fs from 'fs';
13import privateKey from './substrate/privateKey';12import privateKey from './substrate/privateKey';
52 // Transfer balance to it51 // Transfer balance to it
53 const keyring = new Keyring({ type: 'sr25519' });52 const keyring = new Keyring({type: 'sr25519'});
54 const alice = keyring.addFromUri('//Alice');53 const alice = keyring.addFromUri('//Alice');
55 let amount = new BigNumber(endowment);54 const amount = BigInt(endowment) + 10n**15n;
56 amount = amount.plus(1e15);
57 const tx = api.tx.balances.transfer(deployer.address, amount.toFixed());55 const tx = api.tx.balances.transfer(deployer.address, amount);
58 await submitTransactionAsync(alice, tx);56 await submitTransactionAsync(alice, tx);
5957
60 return deployer;58 return deployer;
modifiedtests/src/scheduler.test.tsdiffbeforeafterboth
20describe('Integration Test scheduler base transaction', () => {20describe('Integration Test scheduler base transaction', () => {
21 it('User can transfer owned token with delay (scheduler)', async () => {21 it('User can transfer owned token with delay (scheduler)', async () => {
22 await usingApi(async () => {22 await usingApi(async () => {
23 const Alice = privateKey('//Alice');23 const alice = privateKey('//Alice');
24 const Bob = privateKey('//Bob');24 const bob = privateKey('//Bob');
25 // nft25 // nft
26 const nftCollectionId = await createCollectionExpectSuccess();26 const nftCollectionId = await createCollectionExpectSuccess();
27 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');27 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
28 await setCollectionSponsorExpectSuccess(nftCollectionId, Alice.address);28 await setCollectionSponsorExpectSuccess(nftCollectionId, alice.address);
29 await confirmSponsorshipExpectSuccess(nftCollectionId);29 await confirmSponsorshipExpectSuccess(nftCollectionId);
3030
31 await scheduleTransferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1, 12000, 4);31 await scheduleTransferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 4);
32 });32 });
33 });33 });
34});34});
modifiedtests/src/setChainLimits.test.tsdiffbeforeafterboth
4646
47 it('Collection admin cannot set chain limits', async () => {47 it('Collection admin cannot set chain limits', async () => {
48 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });48 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
49 await addCollectionAdminExpectSuccess(alice, collectionId, bob);49 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
50 await setChainLimitsExpectFailure(bob, limits);50 await setChainLimitsExpectFailure(bob, limits);
51 });51 });
52 52
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
9import chai from 'chai';9import chai from 'chai';
10import chaiAsPromised from 'chai-as-promised';10import chaiAsPromised from 'chai-as-promised';
11import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';11import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
12import { ICollectionInterface } from './types';
13import {12import {
14 createCollectionExpectSuccess, getCreatedCollectionCount,13 createCollectionExpectSuccess, getCreatedCollectionCount,
15 getCreateItemResult,14 getCreateItemResult,
16 getDetailedCollectionInfo,
17 setCollectionLimitsExpectFailure,15 setCollectionLimitsExpectFailure,
18 setCollectionLimitsExpectSuccess,16 setCollectionLimitsExpectSuccess,
19 addCollectionAdminExpectSuccess,17 addCollectionAdminExpectSuccess,
18 queryCollectionExpectSuccess,
20} from './util/helpers';19} from './util/helpers';
2120
22chai.use(chaiAsPromised);21chai.use(chaiAsPromised);
2827
29const accountTokenOwnershipLimit = 0;28const accountTokenOwnershipLimit = 0;
30const sponsoredDataSize = 0;29const sponsoredDataSize = 0;
31const sponsoredMintSize = 0;
32const sponsorTimeout = 1;30const sponsorTransferTimeout = 1;
33const tokenLimit = 10;31const tokenLimit = 10;
3432
35describe('setCollectionLimits positive', () => {33describe('setCollectionLimits positive', () => {
47 collectionIdForTesting,45 collectionIdForTesting,
48 {46 {
49 accountTokenOwnershipLimit: accountTokenOwnershipLimit,47 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
50 sponsoredMintSize: sponsoredDataSize,48 sponsoredDataSize: sponsoredDataSize,
51 tokenLimit: tokenLimit,49 tokenLimit: tokenLimit,
52 sponsorTimeout: sponsorTimeout,50 sponsorTransferTimeout,
53 ownerCanTransfer: true,51 ownerCanTransfer: true,
54 ownerCanDestroy: true,52 ownerCanDestroy: true,
55 },53 },
58 const result = getCreateItemResult(events);56 const result = getCreateItemResult(events);
5957
60 // get collection limits defined previously58 // get collection limits defined previously
61 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;59 const collectionInfo = await queryCollectionExpectSuccess(api, collectionIdForTesting);
6260
63 // tslint:disable-next-line:no-unused-expression61 // tslint:disable-next-line:no-unused-expression
64 expect(result.success).to.be.true;62 expect(result.success).to.be.true;
65 expect(collectionInfo.limits.accountTokenOwnershipLimit).to.be.equal(accountTokenOwnershipLimit);63 expect(collectionInfo.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.equal(accountTokenOwnershipLimit);
66 expect(collectionInfo.limits.sponsoredDataSize).to.be.equal(sponsoredDataSize);64 expect(collectionInfo.limits.sponsoredDataSize.unwrap().toNumber()).to.be.equal(sponsoredDataSize);
67 expect(collectionInfo.limits.tokenLimit).to.be.equal(tokenLimit);65 expect(collectionInfo.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
68 expect(collectionInfo.limits.sponsorTimeout).to.be.equal(sponsorTimeout);66 expect(collectionInfo.limits.sponsorTransferTimeout.unwrap().toNumber()).to.be.equal(sponsorTransferTimeout);
69 expect(collectionInfo.limits.ownerCanTransfer).to.be.true;67 expect(collectionInfo.limits.ownerCanTransfer.unwrap().toJSON()).to.be.true;
70 expect(collectionInfo.limits.ownerCanDestroy).to.be.true;68 expect(collectionInfo.limits.ownerCanDestroy.unwrap().toJSON()).to.be.true;
71 });69 });
72 });70 });
7371
78 accountTokenOwnershipLimit: accountTokenOwnershipLimit,76 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
79 sponsoredMintSize: sponsoredDataSize,77 sponsoredMintSize: sponsoredDataSize,
80 tokenLimit: tokenLimit,78 tokenLimit: tokenLimit,
81 sponsorTimeout: sponsorTimeout,79 sponsorTransferTimeout,
82 ownerCanTransfer: true,80 ownerCanTransfer: true,
83 ownerCanDestroy: true,81 ownerCanDestroy: true,
84 };82 };
90 );88 );
91 const events1 = await submitTransactionAsync(alice, tx1);89 const events1 = await submitTransactionAsync(alice, tx1);
92 const result1 = getCreateItemResult(events1);90 const result1 = getCreateItemResult(events1);
91 expect(result1.success).to.be.true;
93 const collectionInfo1 = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;92 const collectionInfo1 = await queryCollectionExpectSuccess(api, collectionIdForTesting);
93 expect(collectionInfo1.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
9494
95 // The second time95 // The second time
96 const tx2 = api.tx.nft.setCollectionLimits(96 const tx2 = api.tx.nft.setCollectionLimits(
99 );99 );
100 const events2 = await submitTransactionAsync(alice, tx2);100 const events2 = await submitTransactionAsync(alice, tx2);
101 const result2 = getCreateItemResult(events2);101 const result2 = getCreateItemResult(events2);
102 const collectionInfo2 = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;
103
104 // tslint:disable-next-line:no-unused-expression
105 expect(result1.success).to.be.true;102 expect(result2.success).to.be.true;
106 expect(collectionInfo1.limits.tokenLimit).to.be.equal(tokenLimit);
107 expect(result2.success).to.be.true;103 const collectionInfo2 = await queryCollectionExpectSuccess(api, collectionIdForTesting);
108 expect(collectionInfo2.limits.tokenLimit).to.be.equal(tokenLimit);104 expect(collectionInfo2.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
109 });105 });
110 });106 });
111107
130 {126 {
131 accountTokenOwnershipLimit,127 accountTokenOwnershipLimit,
132 sponsoredDataSize,128 sponsoredDataSize,
133 sponsoredMintSize,129 // sponsoredMintSize,
134 tokenLimit,130 tokenLimit,
135 },131 },
136 );132 );
144 {140 {
145 accountTokenOwnershipLimit,141 accountTokenOwnershipLimit,
146 sponsoredDataSize,142 sponsoredDataSize,
147 sponsoredMintSize,143 // sponsoredMintSize,
148 tokenLimit,144 tokenLimit,
149 },145 },
150 );146 );
151 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;147 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
152 });148 });
153 });149 });
154 it('execute setCollectionLimits from admin collection', async () => {150 it('execute setCollectionLimits from admin collection', async () => {
155 await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob);151 await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);
156 await usingApi(async (api: ApiPromise) => {152 await usingApi(async (api: ApiPromise) => {
157 tx = api.tx.nft.setCollectionLimits(153 tx = api.tx.nft.setCollectionLimits(
158 collectionIdForTesting,154 collectionIdForTesting,
159 {155 {
160 accountTokenOwnershipLimit,156 accountTokenOwnershipLimit,
161 sponsoredDataSize,157 sponsoredDataSize,
162 sponsoredMintSize,158 // sponsoredMintSize,
163 tokenLimit,159 tokenLimit,
164 },160 },
165 );161 );
173 accountTokenOwnershipLimit: accountTokenOwnershipLimit,169 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
174 sponsoredMintSize: sponsoredDataSize,170 sponsoredMintSize: sponsoredDataSize,
175 tokenLimit: tokenLimit,171 tokenLimit: tokenLimit,
176 sponsorTimeout: sponsorTimeout,172 sponsorTransferTimeout,
177 ownerCanTransfer: false,173 ownerCanTransfer: false,
178 ownerCanDestroy: true,174 ownerCanDestroy: true,
179 });175 });
180 await setCollectionLimitsExpectFailure(alice, collectionId, {176 await setCollectionLimitsExpectFailure(alice, collectionId, {
181 accountTokenOwnershipLimit: accountTokenOwnershipLimit,177 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
182 sponsoredMintSize: sponsoredDataSize,178 sponsoredMintSize: sponsoredDataSize,
183 tokenLimit: tokenLimit,179 tokenLimit: tokenLimit,
184 sponsorTimeout: sponsorTimeout,180 sponsorTransferTimeout,
185 ownerCanTransfer: true,181 ownerCanTransfer: true,
186 ownerCanDestroy: true,182 ownerCanDestroy: true,
187 });183 });
193 accountTokenOwnershipLimit: accountTokenOwnershipLimit,189 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
194 sponsoredMintSize: sponsoredDataSize,190 sponsoredMintSize: sponsoredDataSize,
195 tokenLimit: tokenLimit,191 tokenLimit: tokenLimit,
196 sponsorTimeout: sponsorTimeout,192 sponsorTransferTimeout,
197 ownerCanTransfer: true,193 ownerCanTransfer: true,
198 ownerCanDestroy: false,194 ownerCanDestroy: false,
199 });195 });
200 await setCollectionLimitsExpectFailure(alice, collectionId, {196 await setCollectionLimitsExpectFailure(alice, collectionId, {
201 accountTokenOwnershipLimit: accountTokenOwnershipLimit,197 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
202 sponsoredMintSize: sponsoredDataSize,198 sponsoredMintSize: sponsoredDataSize,
203 tokenLimit: tokenLimit,199 tokenLimit: tokenLimit,
204 sponsorTimeout: sponsorTimeout,200 sponsorTransferTimeout,
205 ownerCanTransfer: true,201 ownerCanTransfer: true,
206 ownerCanDestroy: true,202 ownerCanDestroy: true,
207 });203 });
215 accountTokenOwnershipLimit: accountTokenOwnershipLimit,211 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
216 sponsoredMintSize: sponsoredDataSize,212 sponsoredMintSize: sponsoredDataSize,
217 tokenLimit: tokenLimit,213 tokenLimit: tokenLimit,
218 sponsorTimeout: sponsorTimeout,214 sponsorTransferTimeout,
219 ownerCanTransfer: true,215 ownerCanTransfer: true,
220 ownerCanDestroy: true,216 ownerCanDestroy: true,
221 };217 };
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
77 // Find the collection that never existed77 // Find the collection that never existed
78 let collectionId = 0;78 let collectionId = 0;
79 await usingApi(async (api) => {79 await usingApi(async (api) => {
80 collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;80 collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
81 });81 });
8282
83 await setCollectionSponsorExpectFailure(collectionId, bob.address);83 await setCollectionSponsorExpectFailure(collectionId, bob.address);
89 });89 });
90 it('(!negative test!) Collection admin add sponsor', async () => {90 it('(!negative test!) Collection admin add sponsor', async () => {
91 const collectionId = await createCollectionExpectSuccess();91 const collectionId = await createCollectionExpectSuccess();
92 await addCollectionAdminExpectSuccess(alice, collectionId, bob);92 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
93 await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Bob');93 await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Bob');
94 });94 });
95});95});
modifiedtests/src/setConstOnChainSchema.test.tsdiffbeforeafterboth
17chai.use(chaiAsPromised);17chai.use(chaiAsPromised);
18const expect = chai.expect;18const expect = chai.expect;
1919
20let Alice: IKeyringPair;20let alice: IKeyringPair;
21let Bob: IKeyringPair;21let bob: IKeyringPair;
22let Shema: any;22let shema: any;
23let largeShema: any;23let largeShema: any;
2424
25before(async () => {25before(async () => {
26 await usingApi(async () => {26 await usingApi(async () => {
27 const keyring = new Keyring({ type: 'sr25519' });27 const keyring = new Keyring({type: 'sr25519'});
28 Alice = keyring.addFromUri('//Alice');28 alice = keyring.addFromUri('//Alice');
29 Bob = keyring.addFromUri('//Bob');29 bob = keyring.addFromUri('//Bob');
30 Shema = '0x31';30 shema = '0x31';
31 largeShema = new Array(4097).fill(0xff);31 largeShema = new Array(4097).fill(0xff);
3232
33 });33 });
37 it('Run extrinsic with parameters of the collection id, set the scheme', async () => {37 it('Run extrinsic with parameters of the collection id, set the scheme', async () => {
38 await usingApi(async (api) => {38 await usingApi(async (api) => {
39 const collectionId = await createCollectionExpectSuccess();39 const collectionId = await createCollectionExpectSuccess();
40 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();40 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
41 expect(collection.owner).to.be.eq(Alice.address);41 expect(collection.owner.toString()).to.be.eq(alice.address);
42 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);42 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, shema);
43 await submitTransactionAsync(Alice, setShema);43 await submitTransactionAsync(alice, setShema);
44 });44 });
45 });45 });
4646
47 it('Collection admin can set the scheme', async () => {47 it('Collection admin can set the scheme', async () => {
48 await usingApi(async (api) => {48 await usingApi(async (api) => {
49 const collectionId = await createCollectionExpectSuccess();49 const collectionId = await createCollectionExpectSuccess();
50 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();50 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
51 expect(collection.owner).to.be.eq(Alice.address);51 expect(collection.owner.toString()).to.be.eq(alice.address);
52 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);52 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
53 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);53 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, shema);
54 await submitTransactionAsync(Bob, setShema);54 await submitTransactionAsync(bob, setShema);
55 });55 });
56 });56 });
5757
58 it('Checking collection data using the ConstOnChainSchema parameter', async () => {58 it('Checking collection data using the ConstOnChainSchema parameter', async () => {
59 await usingApi(async (api) => {59 await usingApi(async (api) => {
60 const collectionId = await createCollectionExpectSuccess();60 const collectionId = await createCollectionExpectSuccess();
61 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);61 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, shema);
62 await submitTransactionAsync(Alice, setShema);62 await submitTransactionAsync(alice, setShema);
63 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();63 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
64 expect(collection.constOnChainSchema.toString()).to.be.eq(Shema);64 expect(collection.constOnChainSchema.toString()).to.be.eq(shema);
65
66 });65 });
67 });66 });
72 it('Set a non-existent collection', async () => {71 it('Set a non-existent collection', async () => {
73 await usingApi(async (api) => {72 await usingApi(async (api) => {
74 // tslint:disable-next-line: radix73 // tslint:disable-next-line: radix
75 const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;74 const collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
76 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);75 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, shema);
77 await expect(submitTransactionExpectFailAsync(Alice, setShema)).to.be.rejected;76 await expect(submitTransactionExpectFailAsync(alice, setShema)).to.be.rejected;
78 });77 });
79 });78 });
8079
81 it('Set a previously deleted collection', async () => {80 it('Set a previously deleted collection', async () => {
82 await usingApi(async (api) => {81 await usingApi(async (api) => {
83 const collectionId = await createCollectionExpectSuccess();82 const collectionId = await createCollectionExpectSuccess();
84 await destroyCollectionExpectSuccess(collectionId);83 await destroyCollectionExpectSuccess(collectionId);
85 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);84 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, shema);
86 await expect(submitTransactionExpectFailAsync(Alice, setShema)).to.be.rejected;85 await expect(submitTransactionExpectFailAsync(alice, setShema)).to.be.rejected;
87 });86 });
88 });87 });
8988
90 it('Set invalid data in schema (size too large:> 1024b)', async () => {89 it('Set invalid data in schema (size too large:> 1024b)', async () => {
91 await usingApi(async (api) => {90 await usingApi(async (api) => {
92 const collectionId = await createCollectionExpectSuccess();91 const collectionId = await createCollectionExpectSuccess();
93 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, largeShema);92 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, largeShema);
94 await expect(submitTransactionExpectFailAsync(Alice, setShema)).to.be.rejected;93 await expect(submitTransactionExpectFailAsync(alice, setShema)).to.be.rejected;
95 });94 });
96 });95 });
9796
98 it('Execute method not on behalf of the collection owner', async () => {97 it('Execute method not on behalf of the collection owner', async () => {
99 await usingApi(async (api) => {98 await usingApi(async (api) => {
100 const collectionId = await createCollectionExpectSuccess();99 const collectionId = await createCollectionExpectSuccess();
101 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();100 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
102 expect(collection.owner).to.be.eq(Alice.address);101 expect(collection.owner.toString()).to.be.eq(alice.address);
103 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);102 const setShema = api.tx.nft.setConstOnChainSchema(collectionId, shema);
104 await expect(submitTransactionExpectFailAsync(Bob, setShema)).to.be.rejected;103 await expect(submitTransactionExpectFailAsync(bob, setShema)).to.be.rejected;
105 });104 });
106 });105 });
107106
modifiedtests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/setMintPermission.test.tsdiffbeforeafterboth
95 it('Collection admin fails on set', async () => {95 it('Collection admin fails on set', async () => {
96 await usingApi(async () => {96 await usingApi(async () => {
97 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });97 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
98 await addCollectionAdminExpectSuccess(alice, collectionId, bob);98 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
99 await setMintPermissionExpectFailure(bob, collectionId, true);99 await setMintPermissionExpectFailure(bob, collectionId, true);
100 });100 });
101 });101 });
modifiedtests/src/setOffchainSchema.test.tsdiffbeforeafterboth
35 });35 });
3636
37 it('execute setOffchainSchema, verify data was set', async () => {37 it('execute setOffchainSchema, verify data was set', async () => {
38 await usingApi(async api => {
38 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });39 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
39 await setOffchainSchemaExpectSuccess(alice, collectionId, DATA);40 await setOffchainSchemaExpectSuccess(alice, collectionId, DATA);
40 const collection = await queryCollectionExpectSuccess(collectionId);41 const collection = await queryCollectionExpectSuccess(api, collectionId);
4142
42 expect(collection.offchainSchema).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));43 expect(collection.offchainSchema).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));
44 });
43 });45 });
4446
45 it('execute setOffchainSchema (collection admin), verify data was set', async () => {47 it('execute setOffchainSchema (collection admin), verify data was set', async () => {
48 await usingApi(async api => {
46 const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });49 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
47 await addCollectionAdminExpectSuccess(alice, collectionId, bob);50 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
48 await setOffchainSchemaExpectSuccess(bob, collectionId, DATA);51 await setOffchainSchemaExpectSuccess(bob, collectionId, DATA);
49 const collection = await queryCollectionExpectSuccess(collectionId);52 const collection = await queryCollectionExpectSuccess(api, collectionId);
5053
51 expect(collection.offchainSchema).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));54 expect(collection.offchainSchema).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));
55 });
52 });56 });
53});57});
5458
modifiedtests/src/setPublicAccessMode.test.tsdiffbeforeafterboth
24chai.use(chaiAsPromised);24chai.use(chaiAsPromised);
25const expect = chai.expect;25const expect = chai.expect;
2626
27let Alice: IKeyringPair;27let alice: IKeyringPair;
28let Bob: IKeyringPair;28let bob: IKeyringPair;
2929
30describe('Integration Test setPublicAccessMode(): ', () => {30describe('Integration Test setPublicAccessMode(): ', () => {
31 before(async () => {31 before(async () => {
32 await usingApi(async () => {32 await usingApi(async () => {
33 Alice = privateKey('//Alice');33 alice = privateKey('//Alice');
34 Bob = privateKey('//Bob');34 bob = privateKey('//Bob');
35 });35 });
36 });36 });
3737
38 it('Run extrinsic with collection id parameters, set the whitelist mode for the collection', async () => {38 it('Run extrinsic with collection id parameters, set the whitelist mode for the collection', async () => {
39 await usingApi(async () => {39 await usingApi(async () => {
40 const collectionId: number = await createCollectionExpectSuccess();40 const collectionId: number = await createCollectionExpectSuccess();
41 await enableWhiteListExpectSuccess(Alice, collectionId);41 await enableWhiteListExpectSuccess(alice, collectionId);
42 await enablePublicMintingExpectSuccess(Alice, collectionId);42 await enablePublicMintingExpectSuccess(alice, collectionId);
43 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);43 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
44 await createItemExpectSuccess(Bob, collectionId, 'NFT', Bob.address);44 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
45 });45 });
46 });46 });
4747
48 it('Whitelisted collection limits', async () => {48 it('Whitelisted collection limits', async () => {
49 await usingApi(async (api: ApiPromise) => {49 await usingApi(async (api: ApiPromise) => {
50 const collectionId = await createCollectionExpectSuccess();50 const collectionId = await createCollectionExpectSuccess();
51 await enableWhiteListExpectSuccess(Alice, collectionId);51 await enableWhiteListExpectSuccess(alice, collectionId);
52 await enablePublicMintingExpectSuccess(Alice, collectionId);52 await enablePublicMintingExpectSuccess(alice, collectionId);
53 const tx = api.tx.nft.createItem(collectionId, normalizeAccountId(Bob.address), 'NFT');53 const tx = api.tx.nft.createItem(collectionId, normalizeAccountId(bob.address), 'NFT');
54 await expect(submitTransactionExpectFailAsync(Bob, tx)).to.be.rejected;54 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
55 });55 });
56 });56 });
57});57});
60 it('Set a non-existent collection', async () => {60 it('Set a non-existent collection', async () => {
61 await usingApi(async (api: ApiPromise) => {61 await usingApi(async (api: ApiPromise) => {
62 // tslint:disable-next-line: radix62 // tslint:disable-next-line: radix
63 const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;63 const collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
64 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');64 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');
65 await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;65 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
66 });66 });
67 });67 });
6868
72 const collectionId = await createCollectionExpectSuccess();72 const collectionId = await createCollectionExpectSuccess();
73 await destroyCollectionExpectSuccess(collectionId);73 await destroyCollectionExpectSuccess(collectionId);
74 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');74 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');
75 await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;75 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
76 });76 });
77 });77 });
7878
79 it('Re-set the list mode already set in quantity', async () => {79 it('Re-set the list mode already set in quantity', async () => {
80 await usingApi(async () => {80 await usingApi(async () => {
81 const collectionId: number = await createCollectionExpectSuccess();81 const collectionId: number = await createCollectionExpectSuccess();
82 await enableWhiteListExpectSuccess(Alice, collectionId);82 await enableWhiteListExpectSuccess(alice, collectionId);
83 await enableWhiteListExpectSuccess(Alice, collectionId);83 await enableWhiteListExpectSuccess(alice, collectionId);
84 });84 });
85 });85 });
8686
89 // tslint:disable-next-line: no-bitwise89 // tslint:disable-next-line: no-bitwise
90 const collectionId = await createCollectionExpectSuccess();90 const collectionId = await createCollectionExpectSuccess();
91 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');91 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');
92 await expect(submitTransactionExpectFailAsync(Bob, tx)).to.be.rejected;92 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
93 });93 });
94 });94 });
95});95});
9696
97describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {97describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {
98 before(async () => {98 before(async () => {
99 await usingApi(async () => {99 await usingApi(async () => {
100 Alice = privateKey('//Alice');100 alice = privateKey('//Alice');
101 Bob = privateKey('//Bob');101 bob = privateKey('//Bob');
102 });102 });
103 });103 });
104 it('setPublicAccessMode by collection admin', async () => {104 it('setPublicAccessMode by collection admin', async () => {
105 await usingApi(async (api: ApiPromise) => {105 await usingApi(async (api: ApiPromise) => {
106 // tslint:disable-next-line: no-bitwise106 // tslint:disable-next-line: no-bitwise
107 const collectionId = await createCollectionExpectSuccess();107 const collectionId = await createCollectionExpectSuccess();
108 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);108 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
109 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');109 const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');
110 await expect(submitTransactionExpectFailAsync(Bob, tx)).to.be.rejected;110 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
111 });111 });
112 });112 });
113});113});
modifiedtests/src/setSchemaVersion.test.tsdiffbeforeafterboth
9import chai from 'chai';9import chai from 'chai';
10import chaiAsPromised from 'chai-as-promised';10import chaiAsPromised from 'chai-as-promised';
11import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';11import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
12import { ICollectionInterface } from './types';
13import {12import {
14 createCollectionExpectSuccess,13 createCollectionExpectSuccess,
15 destroyCollectionExpectSuccess,14 destroyCollectionExpectSuccess,
25let alice: IKeyringPair;24let alice: IKeyringPair;
26let bob: IKeyringPair;25let bob: IKeyringPair;
27let charlie: IKeyringPair;26let charlie: IKeyringPair;
28let collectionIdForTesting: number;
2927
30/*28/*
311. We create collection.291. We create collection.
322. Save just created collection id.302. Save just created collection id.
333. Use this id for setSchemaVersion.313. Use this id for setSchemaVersion.
34*/32*/
35
36describe('hooks', () => {
37 before(async () => {
38 await usingApi(async () => {
39 const keyring = new Keyring({ type: 'sr25519' });
40 alice = keyring.addFromUri('//Alice');
41 });
42 });
43 it('choose or create collection for testing', async () => {
44 await usingApi(async () => {
45 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
46 });
47 });
48});
49
50describe('setSchemaVersion positive', () => {33describe('setSchemaVersion positive', () => {
51 let tx;34 let tx;
57 });40 });
58 it('execute setSchemaVersion with image url and unique ', async () => {41 it('execute setSchemaVersion with image url and unique ', async () => {
59 await usingApi(async (api: ApiPromise) => {42 await usingApi(async (api: ApiPromise) => {
43 const collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
60 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Unique');44 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Unique');
61 const events = await submitTransactionAsync(alice, tx);45 const events = await submitTransactionAsync(alice, tx);
62 const result = getCreateItemResult(events);46 const result = getCreateItemResult(events);
63 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;47 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting);
64 // tslint:disable-next-line:no-unused-expression48 // tslint:disable-next-line:no-unused-expression
65 expect(result.success).to.be.true;49 expect(result.success).to.be.true;
66 // tslint:disable-next-line:no-unused-expression50 // tslint:disable-next-line:no-unused-expression
7357
74describe('Collection admin setSchemaVersion positive', () => {58describe('Collection admin setSchemaVersion positive', () => {
75 let tx;59 let tx;
60 let collectionIdForTesting: any;
61
76 before(async () => {62 before(async () => {
77 await usingApi(async () => {63 await usingApi(async () => {
78 const keyring = new Keyring({ type: 'sr25519' });64 const keyring = new Keyring({type: 'sr25519'});
79 alice = keyring.addFromUri('//Alice');65 alice = keyring.addFromUri('//Alice');
80 bob = keyring.addFromUri('//Bob');66 bob = keyring.addFromUri('//Bob');
67 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
81 await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob);68 await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);
82 });69 });
83 });70 });
84 it('execute setSchemaVersion with image url and unique ', async () => {71 it('execute setSchemaVersion with image url and unique ', async () => {
85 await usingApi(async (api: ApiPromise) => {72 await usingApi(async (api: ApiPromise) => {
86 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Unique');73 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Unique');
87 const events = await submitTransactionAsync(bob, tx);74 const events = await submitTransactionAsync(bob, tx);
88 const result = getCreateItemResult(events);75 const result = getCreateItemResult(events);
89 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;76 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting);
90 // tslint:disable-next-line:no-unused-expression77 // tslint:disable-next-line:no-unused-expression
91 expect(result.success).to.be.true;78 expect(result.success).to.be.true;
92 // tslint:disable-next-line:no-unused-expression79 // tslint:disable-next-line:no-unused-expression
101 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'ImageURL');88 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'ImageURL');
102 const events = await submitTransactionAsync(bob, tx);89 const events = await submitTransactionAsync(bob, tx);
103 const result = getCreateItemResult(events);90 const result = getCreateItemResult(events);
104 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;91 const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting);
105 // tslint:disable-next-line:no-unused-expression92 // tslint:disable-next-line:no-unused-expression
106 expect(result.success).to.be.true;93 expect(result.success).to.be.true;
107 // tslint:disable-next-line:no-unused-expression94 // tslint:disable-next-line:no-unused-expression
114101
115describe('setSchemaVersion negative', () => {102describe('setSchemaVersion negative', () => {
116 let tx;103 let tx;
104 let collectionIdForTesting: any;
117 before(async () => {105 before(async () => {
118 await usingApi(async () => {106 await usingApi(async () => {
119 const keyring = new Keyring({ type: 'sr25519' });107 const keyring = new Keyring({type: 'sr25519'});
120 alice = keyring.addFromUri('//Alice');108 alice = keyring.addFromUri('//Alice');
121 charlie = keyring.addFromUri('//Charlie');109 charlie = keyring.addFromUri('//Charlie');
110 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
122 });111 });
123 });112 });
124 it('execute setSchemaVersion for not exists collection', async () => {113 it('execute setSchemaVersion for not exists collection', async () => {
129 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;118 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
130 });119 });
131 });120 });
132 it('execute setSchemaVersion with not correct schema version', async () => {
133 await usingApi(async (api: ApiPromise) => {
134 const consoleError = console.error;
135 console.error = () => {};
136 try {
137 tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Test');
138 await submitTransactionAsync(alice, tx);
139 } catch (e) {
140 // tslint:disable-next-line:no-unused-expression
141 expect(e).to.be.exist;
142 } finally {
143 console.error = consoleError;
144 }
145 });
146 });
147 it('execute setSchemaVersion for deleted collection', async () => {121 it('execute setSchemaVersion for deleted collection', async () => {
148 await usingApi(async (api: ApiPromise) => {122 await usingApi(async (api: ApiPromise) => {
149 await destroyCollectionExpectSuccess(collectionIdForTesting);123 await destroyCollectionExpectSuccess(collectionIdForTesting);
modifiedtests/src/setVariableMetaData.test.tsdiffbeforeafterboth
18 setVariableMetaDataExpectSuccess,18 setVariableMetaDataExpectSuccess,
19 addCollectionAdminExpectSuccess,19 addCollectionAdminExpectSuccess,
20 setMetadataUpdatePermissionFlagExpectSuccess,20 setMetadataUpdatePermissionFlagExpectSuccess,
21 getVariableMetadata,
21} from './util/helpers';22} from './util/helpers';
2223
23chai.use(chaiAsPromised);24chai.use(chaiAsPromised);
4344
44 it('verify data was set', async () => {45 it('verify data was set', async () => {
45 await usingApi(async api => {46 await usingApi(async api => {
46 const item: any = (await api.query.nft.nftItemList(collectionId, tokenId) as any).unwrap();
47
48 expect(Array.from(item.variableData)).to.deep.equal(Array.from(data));47 expect(await getVariableMetadata(api, collectionId, tokenId)).to.deep.equal(data);
49 });48 });
50 });49 });
51});50});
64 collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });63 collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
65 tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');64 tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
66 await setMetadataUpdatePermissionFlagExpectSuccess(alice, collectionId, 'Admin');65 await setMetadataUpdatePermissionFlagExpectSuccess(alice, collectionId, 'Admin');
67 await addCollectionAdminExpectSuccess(alice, collectionId, bob);66 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
68 });67 });
69 });68 });
7069
7473
75 it('verify data was set', async () => {74 it('verify data was set', async () => {
76 await usingApi(async api => {75 await usingApi(async api => {
77 const item: any = (await api.query.nft.nftItemList(collectionId, tokenId) as any).unwrap();
78
79 expect(Array.from(item.variableData)).to.deep.equal(Array.from(data));76 expect(await getVariableMetadata(api, collectionId, tokenId)).to.deep.equal(data);
80 });77 });
81 });78 });
82});79});
modifiedtests/src/setVariableMetadataSponsoringRateLimit.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/setVariableOnChainSchema.test.tsdiffbeforeafterboth
17chai.use(chaiAsPromised);17chai.use(chaiAsPromised);
18const expect = chai.expect;18const expect = chai.expect;
1919
20let Alice: IKeyringPair;20let alice: IKeyringPair;
21let Bob: IKeyringPair;21let bob: IKeyringPair;
22let Schema: any;22let schema: any;
23let largeSchema: any;23let largeSchema: any;
2424
25before(async () => {25before(async () => {
26 await usingApi(async () => {26 await usingApi(async () => {
27 const keyring = new Keyring({ type: 'sr25519' });27 const keyring = new Keyring({type: 'sr25519'});
28 Alice = keyring.addFromUri('//Alice');28 alice = keyring.addFromUri('//Alice');
29 Bob = keyring.addFromUri('//Bob');29 bob = keyring.addFromUri('//Bob');
30 Schema = '0x31';30 schema = '0x31';
31 largeSchema = new Array(4097).fill(0xff);31 largeSchema = new Array(4097).fill(0xff);
3232
33 });33 });
37 it('Run extrinsic with parameters of the collection id, set the scheme', async () => {37 it('Run extrinsic with parameters of the collection id, set the scheme', async () => {
38 await usingApi(async (api) => {38 await usingApi(async (api) => {
39 const collectionId = await createCollectionExpectSuccess();39 const collectionId = await createCollectionExpectSuccess();
40 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();40 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
41 expect(collection.owner).to.be.eq(Alice.address);41 expect(collection.owner.toString()).to.be.eq(alice.address);
42 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);42 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
43 await submitTransactionAsync(Alice, setSchema);43 await submitTransactionAsync(alice, setSchema);
44 });44 });
45 });45 });
4646
47 it('Checking collection data using the setVariableOnChainSchema parameter', async () => {47 it('Checking collection data using the setVariableOnChainSchema parameter', async () => {
48 await usingApi(async (api) => {48 await usingApi(async (api) => {
49 const collectionId = await createCollectionExpectSuccess();49 const collectionId = await createCollectionExpectSuccess();
50 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);50 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
51 await submitTransactionAsync(Alice, setSchema);51 await submitTransactionAsync(alice, setSchema);
52 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();52 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
53 expect(collection.variableOnChainSchema.toString()).to.be.eq(Schema);53 expect(collection.variableOnChainSchema.toString()).to.be.eq(schema);
5454
55 });55 });
56 });56 });
61 it('Run extrinsic with parameters of the collection id, set the scheme', async () => {61 it('Run extrinsic with parameters of the collection id, set the scheme', async () => {
62 await usingApi(async (api) => {62 await usingApi(async (api) => {
63 const collectionId = await createCollectionExpectSuccess();63 const collectionId = await createCollectionExpectSuccess();
64 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();64 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
65 expect(collection.owner).to.be.eq(Alice.address);65 expect(collection.owner.toString()).to.be.eq(alice.address);
66 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);66 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
67 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);67 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
68 await submitTransactionAsync(Bob, setSchema);68 await submitTransactionAsync(bob, setSchema);
69 });69 });
70 });70 });
7171
72 it('Checking collection data using the setVariableOnChainSchema parameter', async () => {72 it('Checking collection data using the setVariableOnChainSchema parameter', async () => {
73 await usingApi(async (api) => {73 await usingApi(async (api) => {
74 const collectionId = await createCollectionExpectSuccess();74 const collectionId = await createCollectionExpectSuccess();
75 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);75 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
76 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);76 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
77 await submitTransactionAsync(Bob, setSchema);77 await submitTransactionAsync(bob, setSchema);
78 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();78 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
79 expect(collection.variableOnChainSchema.toString()).to.be.eq(Schema);79 expect(collection.variableOnChainSchema.toString()).to.be.eq(schema);
8080
81 });81 });
82 });82 });
87 it('Set a non-existent collection', async () => {87 it('Set a non-existent collection', async () => {
88 await usingApi(async (api) => {88 await usingApi(async (api) => {
89 // tslint:disable-next-line: radix89 // tslint:disable-next-line: radix
90 const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;90 const collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;
91 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);91 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
92 await expect(submitTransactionExpectFailAsync(Alice, setSchema)).to.be.rejected;92 await expect(submitTransactionExpectFailAsync(alice, setSchema)).to.be.rejected;
93 });93 });
94 });94 });
9595
96 it('Set a previously deleted collection', async () => {96 it('Set a previously deleted collection', async () => {
97 await usingApi(async (api) => {97 await usingApi(async (api) => {
98 const collectionId = await createCollectionExpectSuccess();98 const collectionId = await createCollectionExpectSuccess();
99 await destroyCollectionExpectSuccess(collectionId);99 await destroyCollectionExpectSuccess(collectionId);
100 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);100 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
101 await expect(submitTransactionExpectFailAsync(Alice, setSchema)).to.be.rejected;101 await expect(submitTransactionExpectFailAsync(alice, setSchema)).to.be.rejected;
102 });102 });
103 });103 });
104104
105 it('Set invalid data in schema (size too large:> 1024b)', async () => {105 it('Set invalid data in schema (size too large:> 1024b)', async () => {
106 await usingApi(async (api) => {106 await usingApi(async (api) => {
107 const collectionId = await createCollectionExpectSuccess();107 const collectionId = await createCollectionExpectSuccess();
108 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, largeSchema);108 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, largeSchema);
109 await expect(submitTransactionExpectFailAsync(Alice, setSchema)).to.be.rejected;109 await expect(submitTransactionExpectFailAsync(alice, setSchema)).to.be.rejected;
110 });110 });
111 });111 });
112112
113 it('Execute method not on behalf of the collection owner', async () => {113 it('Execute method not on behalf of the collection owner', async () => {
114 await usingApi(async (api) => {114 await usingApi(async (api) => {
115 const collectionId = await createCollectionExpectSuccess();115 const collectionId = await createCollectionExpectSuccess();
116 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();116 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
117 expect(collection.owner).to.be.eq(Alice.address);117 expect(collection.owner.toString()).to.be.eq(alice.address);
118 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);118 const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, schema);
119 await expect(submitTransactionExpectFailAsync(Bob, setSchema)).to.be.rejected;119 await expect(submitTransactionExpectFailAsync(bob, setSchema)).to.be.rejected;
120 });120 });
121 });121 });
122122
modifiedtests/src/substrate/get-balance.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/substrate/privateKey.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/substrate/promisify-substrate.tsdiffbeforeafterboth

no syntactic changes

deletedtests/src/substrate/rpc_defs.jsondiffbeforeafterboth

no changes

modifiedtests/src/substrate/substrate-api.tsdiffbeforeafterboth
11import config from '../config';11import config from '../config';
12import promisifySubstrate from './promisify-substrate';12import promisifySubstrate from './promisify-substrate';
13import { ApiOptions, SubmittableExtrinsic, ApiTypes } from '@polkadot/api/types';13import {ApiOptions, SubmittableExtrinsic, ApiTypes} from '@polkadot/api/types';
14import * as defs from '../interfaces/definitions';
15
1416
15function defaultApiOptions(): ApiOptions {17function defaultApiOptions(): ApiOptions {
21 payload: {},23 payload: {},
22 },24 },
23 },25 },
26 rpc: {
27 nft: defs.nft.rpc,
28 },
24 };29 };
25}30}
2631
35 const consoleLog = console.log;40 const consoleLog = console.log;
36 const consoleWarn = console.warn;41 const consoleWarn = console.warn;
3742
38 const outFn = (message: string) => {43 const outFn = (printer: any) => (...args: any[]) => {
44 for (const arg of args) {
39 if (typeof message !== 'string') {45 if (typeof arg !== 'string')
40 consoleErr(message);
41 return;46 continue;
42 }
43 if (!message.includes('StorageChangeSet:: WebSocket is not connected') &&47 if (arg.includes('1000:: Normal connection closure' || arg === 'Normal connection closure'))
44 !message.includes('2021-') &&
45 !message.includes('StorageChangeSet:: Normal connection closure'))
46 consoleErr(message);48 return;
49 }
50 printer(...args);
47 };51 };
4852
49 console.error = outFn;53 console.error = outFn(consoleErr.bind(console));
50 console.log = outFn;54 console.log = outFn(consoleLog.bind(console));
51 console.warn = outFn;55 console.warn = outFn(consoleWarn.bind(console));
5256
53 try {57 try {
54 await promisifySubstrate(api, async () => {58 await promisifySubstrate(api, async () => {
114}118}
115119
116export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {120export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {
117 const consoleError = console.error;
118 const consoleLog = console.log;
119 console.error = () => {};121 console.error = () => {};
120 console.log = () => {};122 console.log = () => {};
121123
124 const resolve = (rec: EventRecord[]) => {126 const resolve = (rec: EventRecord[]) => {
125 setTimeout(() => {127 setTimeout(() => {
126 res(rec);128 res(rec);
127 console.error = consoleError;
128 console.log = consoleLog;
129 });129 });
130 };130 };
131 const reject = (errror: any) => {131 const reject = (errror: any) => {
132 setTimeout(() => {132 setTimeout(() => {
133 rej(errror);133 rej(errror);
134 console.error = consoleError;
135 console.log = consoleLog;
136 });134 });
137 };135 };
138 try {136 try {
modifiedtests/src/substrate/wait-new-blocks.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/toggleContractWhiteList.test.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/transfer.nload.tsdiffbeforeafterboth

no syntactic changes

modifiedtests/src/transfer.test.tsdiffbeforeafterboth
21 addCollectionAdminExpectSuccess,21 addCollectionAdminExpectSuccess,
22} from './util/helpers';22} from './util/helpers';
2323
24let Alice: IKeyringPair;24let alice: IKeyringPair;
25let Bob: IKeyringPair;25let bob: IKeyringPair;
26let Charlie: IKeyringPair;26let charlie: IKeyringPair;
2727
28describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {28describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
29 it('Balance transfers and check balance', async () => {29 it('Balance transfers and check balance', async () => {
6666
67 it('User can transfer owned token', async () => {67 it('User can transfer owned token', async () => {
68 await usingApi(async () => {68 await usingApi(async () => {
69 const Alice = privateKey('//Alice');69 const alice = privateKey('//Alice');
70 const Bob = privateKey('//Bob');70 const bob = privateKey('//Bob');
71 // nft71 // nft
72 const nftCollectionId = await createCollectionExpectSuccess();72 const nftCollectionId = await createCollectionExpectSuccess();
73 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');73 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
74 await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1, 'NFT');74 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
75 // fungible75 // fungible
76 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});76 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
77 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');77 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
78 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');78 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
79 // reFungible79 // reFungible
80 const reFungibleCollectionId = await80 const reFungibleCollectionId = await
81 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});81 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
82 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');82 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
83 await transferExpectSuccess(83 await transferExpectSuccess(
84 reFungibleCollectionId,84 reFungibleCollectionId,
85 newReFungibleTokenId,85 newReFungibleTokenId,
86 Alice,86 alice,
87 Bob,87 bob,
88 100,88 100,
89 'ReFungible',89 'ReFungible',
90 );90 );
9393
94 it('Collection admin can transfer owned token', async () => {94 it('Collection admin can transfer owned token', async () => {
95 await usingApi(async () => {95 await usingApi(async () => {
96 const Alice = privateKey('//Alice');96 const alice = privateKey('//Alice');
97 const Bob = privateKey('//Bob');97 const bob = privateKey('//Bob');
98 // nft98 // nft
99 const nftCollectionId = await createCollectionExpectSuccess();99 const nftCollectionId = await createCollectionExpectSuccess();
100 await addCollectionAdminExpectSuccess(Alice, nftCollectionId, Bob);100 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
101 const newNftTokenId = await createItemExpectSuccess(Bob, nftCollectionId, 'NFT', Bob.address);101 const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
102 await transferExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice, 1, 'NFT');102 await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
103 // fungible103 // fungible
104 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});104 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
105 await addCollectionAdminExpectSuccess(Alice, fungibleCollectionId, Bob);105 await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
106 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible', Bob.address);106 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
107 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, Bob, Alice, 1, 'Fungible');107 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
108 // reFungible108 // reFungible
109 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});109 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
110 await addCollectionAdminExpectSuccess(Alice, reFungibleCollectionId, Bob);110 await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
111 const newReFungibleTokenId = await createItemExpectSuccess(Bob, reFungibleCollectionId, 'ReFungible', Bob.address);111 const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
112 await transferExpectSuccess(112 await transferExpectSuccess(
113 reFungibleCollectionId,113 reFungibleCollectionId,
114 newReFungibleTokenId,114 newReFungibleTokenId,
115 Bob,115 bob,
116 Alice,116 alice,
117 100,117 100,
118 'ReFungible',118 'ReFungible',
119 );119 );
124describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {124describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
125 before(async () => {125 before(async () => {
126 await usingApi(async () => {126 await usingApi(async () => {
127 Alice = privateKey('//Alice');127 alice = privateKey('//Alice');
128 Bob = privateKey('//Bob');128 bob = privateKey('//Bob');
129 Charlie = privateKey('//Charlie');129 charlie = privateKey('//Charlie');
130 });130 });
131 });131 });
132 it('Transfer with not existed collection_id', async () => {132 it('Transfer with not existed collection_id', async () => {
133 await usingApi(async (api) => {133 await usingApi(async (api) => {
134 // nft134 // nft
135 const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;135 const nftCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
136 await transferExpectFailure(nftCollectionCount + 1, 1, Alice, Bob, 1);136 await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);
137 // fungible137 // fungible
138 const fungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;138 const fungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
139 await transferExpectFailure(fungibleCollectionCount + 1, 1, Alice, Bob, 1);139 await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
140 // reFungible140 // reFungible
141 const reFungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;141 const reFungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
142 await transferExpectFailure(reFungibleCollectionCount + 1, 1, Alice, Bob, 1);142 await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
143 });143 });
144 });144 });
145 it('Transfer with deleted collection_id', async () => {145 it('Transfer with deleted collection_id', async () => {
146 // nft146 // nft
147 const nftCollectionId = await createCollectionExpectSuccess();147 const nftCollectionId = await createCollectionExpectSuccess();
148 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');148 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
149 await destroyCollectionExpectSuccess(nftCollectionId);149 await destroyCollectionExpectSuccess(nftCollectionId);
150 await transferExpectFailure(nftCollectionId, newNftTokenId, Alice, Bob, 1);150 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
151 // fungible151 // fungible
152 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});152 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
153 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');153 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
154 await destroyCollectionExpectSuccess(fungibleCollectionId);154 await destroyCollectionExpectSuccess(fungibleCollectionId);
155 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1);155 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
156 // reFungible156 // reFungible
157 const reFungibleCollectionId = await157 const reFungibleCollectionId = await
158 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});158 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
159 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');159 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
160 await destroyCollectionExpectSuccess(reFungibleCollectionId);160 await destroyCollectionExpectSuccess(reFungibleCollectionId);
161 await transferExpectFailure(161 await transferExpectFailure(
162 reFungibleCollectionId,162 reFungibleCollectionId,
163 newReFungibleTokenId,163 newReFungibleTokenId,
164 Alice,164 alice,
165 Bob,165 bob,
166 1,166 1,
167 );167 );
168 });168 });
169 it('Transfer with not existed item_id', async () => {169 it('Transfer with not existed item_id', async () => {
170 // nft170 // nft
171 const nftCollectionId = await createCollectionExpectSuccess();171 const nftCollectionId = await createCollectionExpectSuccess();
172 await transferExpectFailure(nftCollectionId, 2, Alice, Bob, 1);172 await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
173 // fungible173 // fungible
174 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});174 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
175 await transferExpectFailure(fungibleCollectionId, 2, Alice, Bob, 1);175 await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);
176 // reFungible176 // reFungible
177 const reFungibleCollectionId = await177 const reFungibleCollectionId = await
178 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});178 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
179 await transferExpectFailure(179 await transferExpectFailure(
180 reFungibleCollectionId,180 reFungibleCollectionId,
181 2,181 2,
182 Alice,182 alice,
183 Bob,183 bob,
184 1,184 1,
185 );185 );
186 });186 });
187 it('Transfer with deleted item_id', async () => {187 it('Transfer with deleted item_id', async () => {
188 // nft188 // nft
189 const nftCollectionId = await createCollectionExpectSuccess();189 const nftCollectionId = await createCollectionExpectSuccess();
190 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');190 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
191 await burnItemExpectSuccess(Alice, nftCollectionId, newNftTokenId, 1);191 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
192 await transferExpectFailure(nftCollectionId, newNftTokenId, Alice, Bob, 1);192 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
193 // fungible193 // fungible
194 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});194 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
195 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');195 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
196 await burnItemExpectSuccess(Alice, fungibleCollectionId, newFungibleTokenId, 10);196 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
197 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1);197 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
198 // reFungible198 // reFungible
199 const reFungibleCollectionId = await199 const reFungibleCollectionId = await
200 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});200 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
201 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');201 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
202 await burnItemExpectSuccess(Alice, reFungibleCollectionId, newReFungibleTokenId, 100);202 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
203 await transferExpectFailure(203 await transferExpectFailure(
204 reFungibleCollectionId,204 reFungibleCollectionId,
205 newReFungibleTokenId,205 newReFungibleTokenId,
206 Alice,206 alice,
207 Bob,207 bob,
208 1,208 1,
209 );209 );
210 });210 });
211 it('Transfer with recipient that is not owner', async () => {211 it('Transfer with recipient that is not owner', async () => {
212 // nft212 // nft
213 const nftCollectionId = await createCollectionExpectSuccess();213 const nftCollectionId = await createCollectionExpectSuccess();
214 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');214 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
215 await transferExpectFailure(nftCollectionId, newNftTokenId, Charlie, Bob, 1);215 await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
216 // fungible216 // fungible
217 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});217 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
218 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');218 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
219 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, Charlie, Bob, 1);219 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
220 // reFungible220 // reFungible
221 const reFungibleCollectionId = await221 const reFungibleCollectionId = await
222 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});222 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
223 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');223 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
224 await transferExpectFailure(224 await transferExpectFailure(
225 reFungibleCollectionId,225 reFungibleCollectionId,
226 newReFungibleTokenId,226 newReFungibleTokenId,
227 Charlie,227 charlie,
228 Bob,228 bob,
229 1,229 1,
230 );230 );
231 });231 });
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
25const expect = chai.expect;25const expect = chai.expect;
2626
27describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {27describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
28 let Alice: IKeyringPair;28 let alice: IKeyringPair;
29 let Bob: IKeyringPair;29 let bob: IKeyringPair;
30 let Charlie: IKeyringPair;30 let charlie: IKeyringPair;
3131
32 before(async () => {32 before(async () => {
33 await usingApi(async () => {33 await usingApi(async () => {
34 Alice = privateKey('//Alice');34 alice = privateKey('//Alice');
35 Bob = privateKey('//Bob');35 bob = privateKey('//Bob');
36 Charlie = privateKey('//Charlie');36 charlie = privateKey('//Charlie');
37 });37 });
38 });38 });
3939
40 it('Execute the extrinsic and check nftItemList - owner of token', async () => {40 it('Execute the extrinsic and check nftItemList - owner of token', async () => {
41 await usingApi(async () => {41 await usingApi(async () => {
42 // nft42 // nft
43 const nftCollectionId = await createCollectionExpectSuccess();43 const nftCollectionId = await createCollectionExpectSuccess();
44 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');44 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
45 await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);45 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
4646
47 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 1, 'NFT');47 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
4848
49 // fungible49 // fungible
50 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});50 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
51 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');51 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
52 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);52 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
53 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1, 'Fungible');53 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
5454
55 // reFungible55 // reFungible
56 const reFungibleCollectionId = await56 const reFungibleCollectionId = await
57 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});57 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
58 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');58 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
59 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 100);59 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
60 await transferFromExpectSuccess(60 await transferFromExpectSuccess(
61 reFungibleCollectionId,61 reFungibleCollectionId,
62 newReFungibleTokenId,62 newReFungibleTokenId,
63 Bob,63 bob,
64 Alice,64 alice,
65 Charlie,65 charlie,
66 100,66 100,
67 'ReFungible',67 'ReFungible',
68 );68 );
69 });69 });
70 });70 });
7171
72 it('Should reduce allowance if value is big', async () => {72 it('Should reduce allowance if value is big', async () => {
73 await usingApi(async () => {73 await usingApi(async (api) => {
74 const alice = privateKey('//Alice');74 const alice = privateKey('//Alice');
75 const bob = privateKey('//Bob');75 const bob = privateKey('//Bob');
76 const charlie = privateKey('//Charlie');76 const charlie = privateKey('//Charlie');
79 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});79 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
80 const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, { Value: 500000n });80 const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 500000n});
8181
82 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 500000n);82 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 500000n);
83 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');83 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');
84 expect((await getAllowance(fungibleCollectionId, newFungibleTokenId, alice.address, bob.address)).toString()).to.equal('0');84 expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, newFungibleTokenId)).to.equal(0n);
85 });85 });
86 });86 });
8787
88 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {88 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {
89 const collectionId = await createCollectionExpectSuccess();89 const collectionId = await createCollectionExpectSuccess();
90 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);90 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
9191
92 await transferFromExpectSuccess(collectionId, itemId, Alice, Bob, Charlie);92 await transferFromExpectSuccess(collectionId, itemId, alice, bob, charlie);
93 });93 });
94});94});
9595
96describe('Negative Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {96describe('Negative Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
97 let Alice: IKeyringPair;97 let alice: IKeyringPair;
98 let Bob: IKeyringPair;98 let bob: IKeyringPair;
99 let Charlie: IKeyringPair;99 let charlie: IKeyringPair;
100100
101 before(async () => {101 before(async () => {
102 await usingApi(async () => {102 await usingApi(async () => {
103 Alice = privateKey('//Alice');103 alice = privateKey('//Alice');
104 Bob = privateKey('//Bob');104 bob = privateKey('//Bob');
105 Charlie = privateKey('//Charlie');105 charlie = privateKey('//Charlie');
106 });106 });
107 });107 });
108108
109 it('transferFrom for a collection that does not exist', async () => {109 it('transferFrom for a collection that does not exist', async () => {
110 await usingApi(async (api: ApiPromise) => {110 await usingApi(async (api: ApiPromise) => {
111 // nft111 // nft
112 const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;112 const nftCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
113 await approveExpectFail(nftCollectionCount + 1, 1, Alice, Bob);113 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
114114
115 await transferFromExpectFail(nftCollectionCount + 1, 1, Bob, Alice, Charlie, 1);115 await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);
116116
117 // fungible117 // fungible
118 const fungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;118 const fungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
119 await approveExpectFail(fungibleCollectionCount + 1, 1, Alice, Bob);119 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
120120
121 await transferFromExpectFail(fungibleCollectionCount + 1, 1, Bob, Alice, Charlie, 1);121 await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
122 // reFungible122 // reFungible
123 const reFungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;123 const reFungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();
124 await approveExpectFail(reFungibleCollectionCount + 1, 1, Alice, Bob);124 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
125125
126 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, Bob, Alice, Charlie, 1);126 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);
127 });127 });
128 });128 });
129129
149 await usingApi(async () => {149 await usingApi(async () => {
150 // nft150 // nft
151 const nftCollectionId = await createCollectionExpectSuccess();151 const nftCollectionId = await createCollectionExpectSuccess();
152 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');152 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
153153
154 await transferFromExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 1);154 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
155155
156 // fungible156 // fungible
157 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});157 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
158 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');158 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
159 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1);159 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
160 // reFungible160 // reFungible
161 const reFungibleCollectionId = await161 const reFungibleCollectionId = await
162 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});162 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
163 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');163 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
164 await transferFromExpectFail(164 await transferFromExpectFail(
165 reFungibleCollectionId,165 reFungibleCollectionId,
166 newReFungibleTokenId,166 newReFungibleTokenId,
167 Bob,167 bob,
168 Alice,168 alice,
169 Charlie,169 charlie,
170 1,170 1,
171 );171 );
172 });172 });
176 await usingApi(async () => {176 await usingApi(async () => {
177 // nft177 // nft
178 const nftCollectionId = await createCollectionExpectSuccess();178 const nftCollectionId = await createCollectionExpectSuccess();
179 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');179 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
180 await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);180 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
181181
182 await transferFromExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 2);182 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
183183
184 // fungible184 // fungible
185 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});185 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
186 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');186 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
187 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);187 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
188 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 2);188 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
189 // reFungible189 // reFungible
190 const reFungibleCollectionId = await190 const reFungibleCollectionId = await
191 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});191 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
192 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');192 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
193 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);193 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
194 await transferFromExpectFail(194 await transferFromExpectFail(
195 reFungibleCollectionId,195 reFungibleCollectionId,
196 newReFungibleTokenId,196 newReFungibleTokenId,
197 Bob,197 bob,
198 Alice,198 alice,
199 Charlie,199 charlie,
200 2,200 2,
201 );201 );
202 });202 });
203 });203 });
204204
205 it('execute transferFrom from account that is not owner of collection', async () => {205 it('execute transferFrom from account that is not owner of collection', async () => {
206 await usingApi(async () => {206 await usingApi(async () => {
207 const Dave = privateKey('//Dave');207 const dave = privateKey('//Dave');
208 // nft208 // nft
209 const nftCollectionId = await createCollectionExpectSuccess();209 const nftCollectionId = await createCollectionExpectSuccess();
210 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');210 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
211 try {211 try {
212 await approveExpectFail(nftCollectionId, newNftTokenId, Dave, Bob);212 await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
213 await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);213 await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);
214 } catch (e) {214 } catch (e) {
215 // tslint:disable-next-line:no-unused-expression215 // tslint:disable-next-line:no-unused-expression
216 expect(e).to.be.exist;216 expect(e).to.be.exist;
220220
221 // fungible221 // fungible
222 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});222 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
223 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');223 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
224 try {224 try {
225 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Dave, Bob);225 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, dave, bob);
226 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Dave, Alice, Charlie, 1);226 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, dave, alice, charlie, 1);
227 } catch (e) {227 } catch (e) {
228 // tslint:disable-next-line:no-unused-expression228 // tslint:disable-next-line:no-unused-expression
229 expect(e).to.be.exist;229 expect(e).to.be.exist;
230 }230 }
231 // reFungible231 // reFungible
232 const reFungibleCollectionId = await232 const reFungibleCollectionId = await
233 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});233 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
234 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');234 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
235 try {235 try {
236 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Dave, Bob);236 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
237 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, Dave, Alice, Charlie, 1);237 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
238 } catch (e) {238 } catch (e) {
239 // tslint:disable-next-line:no-unused-expression239 // tslint:disable-next-line:no-unused-expression
240 expect(e).to.be.exist;240 expect(e).to.be.exist;
245 await usingApi(async () => {245 await usingApi(async () => {
246 // nft246 // nft
247 const nftCollectionId = await createCollectionExpectSuccess();247 const nftCollectionId = await createCollectionExpectSuccess();
248 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');248 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
249 await burnItemExpectSuccess(Alice, nftCollectionId, newNftTokenId, 1);249 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
250 await approveExpectFail(nftCollectionId, newNftTokenId, Alice, Bob);250 await approveExpectFail(nftCollectionId, newNftTokenId, alice, bob);
251 await transferFromExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 1);251 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
252 });252 });
253 });253 });
254 it( 'transferFrom burnt token before approve Fungible', async () => {254 it('transferFrom burnt token before approve Fungible', async () => {
255 await usingApi(async () => {255 await usingApi(async () => {
256 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});256 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
257 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');257 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
258 await burnItemExpectSuccess(Alice, fungibleCollectionId, 1, 10);258 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
259 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);259 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
260 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1);260 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
261261
262 });262 });
263 });263 });
264 it( 'transferFrom burnt token before approve ReFungible', async () => {264 it('transferFrom burnt token before approve ReFungible', async () => {
265 await usingApi(async () => {265 await usingApi(async () => {
266 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});266 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
267 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');267 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
268 await burnItemExpectSuccess(Alice, reFungibleCollectionId, newReFungibleTokenId, 100);268 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
269 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);269 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, alice, bob);
270 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice, Charlie, 1);270 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
271271
272 });272 });
273 });273 });
276 await usingApi(async () => {276 await usingApi(async () => {
277 // nft277 // nft
278 const nftCollectionId = await createCollectionExpectSuccess();278 const nftCollectionId = await createCollectionExpectSuccess();
279 const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');279 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
280 await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);280 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
281 await burnItemExpectSuccess(Alice, nftCollectionId, newNftTokenId, 1);281 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
282 await transferFromExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 1);282 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
283 });283 });
284 });284 });
285 it( 'transferFrom burnt token after approve Fungible', async () => {285 it('transferFrom burnt token after approve Fungible', async () => {
286 await usingApi(async () => {286 await usingApi(async () => {
287 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});287 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
288 const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');288 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
289 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);289 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
290 await burnItemExpectSuccess(Alice, fungibleCollectionId, 1, 10);290 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
291 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1);291 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
292292
293 });293 });
294 });294 });
295 it( 'transferFrom burnt token after approve ReFungible', async () => {295 it('transferFrom burnt token after approve ReFungible', async () => {
296 await usingApi(async () => {296 await usingApi(async () => {
297 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});297 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
298 const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');298 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
299 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);299 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
300 await burnItemExpectSuccess(Alice, reFungibleCollectionId, newReFungibleTokenId, 100);300 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
301 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice, Charlie, 1);301 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
302302
303 });303 });
304 });304 });
305305
306 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {306 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {
307 const collectionId = await createCollectionExpectSuccess();307 const collectionId = await createCollectionExpectSuccess();
308 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);308 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
309 await setCollectionLimitsExpectSuccess(Alice, collectionId, { ownerCanTransfer: false });309 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});
310310
311 await transferFromExpectFail(collectionId, itemId, Alice, Bob, Charlie);311 await transferFromExpectFail(collectionId, itemId, alice, bob, charlie);
312 });312 });
313});313});
314314
deletedtests/src/types.tsdiffbeforeafterboth

no changes

modifiedtests/src/util/contracthelpers.tsdiffbeforeafterboth
1313
14chai.use(chaiAsPromised);14chai.use(chaiAsPromised);
15const expect = chai.expect;15const expect = chai.expect;
16import { BigNumber } from 'bignumber.js';
17import { findUnusedAddress, getGenericResult } from '../util/helpers';16import {findUnusedAddress, getGenericResult} from '../util/helpers';
1817
19const value = 0;18const value = 0;
42 // Transfer balance to it41 // Transfer balance to it
43 const keyring = new Keyring({ type: 'sr25519' });42 const keyring = new Keyring({type: 'sr25519'});
44 const alice = keyring.addFromUri('//Alice');43 const alice = keyring.addFromUri('//Alice');
45 let amount = new BigNumber(endowment);44 const amount = BigInt(endowment) + 10n**15n;
46 amount = amount.plus(100e15);
47 const tx = api.tx.balances.transfer(deployer.address, amount.toFixed());45 const tx = api.tx.balances.transfer(deployer.address, amount);
48 await submitTransactionAsync(alice, tx);46 await submitTransactionAsync(alice, tx);
4947
50 return deployer;48 return deployer;
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
7import type { AccountId, EventRecord } from '@polkadot/types/interfaces';7import type {AccountId, EventRecord} from '@polkadot/types/interfaces';
8import { IKeyringPair } from '@polkadot/types/types';8import {IKeyringPair} from '@polkadot/types/types';
9import { evmToAddress } from '@polkadot/util-crypto';9import {evmToAddress} from '@polkadot/util-crypto';
10import { BigNumber } from 'bignumber.js';
11import BN from 'bn.js';10import BN from 'bn.js';
12import chai from 'chai';11import chai from 'chai';
13import chaiAsPromised from 'chai-as-promised';12import chaiAsPromised from 'chai-as-promised';
14import { alicesPublicKey } from '../accounts';13import {alicesPublicKey} from '../accounts';
14import {NftDataStructsCollection} from '../interfaces';
15import privateKey from '../substrate/privateKey';15import privateKey from '../substrate/privateKey';
16import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from '../substrate/substrate-api';16import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from '../substrate/substrate-api';
17import { ICollectionInterface } from '../types';
18import { hexToStr, strToUTF16, utf16ToStr } from './util';17import {hexToStr, strToUTF16, utf16ToStr} from './util';
1918
20chai.use(chaiAsPromised);19chai.use(chaiAsPromised);
21const expect = chai.expect;20const expect = chai.expect;
2221
23export type CrossAccountId = {22export type CrossAccountId = {
24 substrate: string,23 Substrate: string,
25} | {24} | {
26 ethereum: string,25 Ethereum: string,
27};26};
28export function normalizeAccountId(input: string | AccountId | CrossAccountId | IKeyringPair): CrossAccountId {27export function normalizeAccountId(input: string | AccountId | CrossAccountId | IKeyringPair): CrossAccountId {
29 if (typeof input === 'string')28 if (typeof input === 'string') {
29 if (input.length === 48 || input.length === 47) {
30 return { substrate: input };30 return {Substrate: input};
31 } else if (input.length === 42 && input.startsWith('0x')) {
32 return {Ethereum: input.toLowerCase()};
33 } else if (input.length === 40 && !input.startsWith('0x')) {
34 return {Ethereum: '0x' + input.toLowerCase()};
35 } else {
36 throw new Error(`Unknown address format: "${input}"`);
37 }
38 }
31 if ('address' in input) {39 if ('address' in input) {
32 return { substrate: input.address };40 return {Substrate: input.address};
33 }41 }
34 if ('ethereum' in input) {42 if ('Ethereum' in input) {
43 return {
44 Ethereum: input.Ethereum.toLowerCase(),
45 };
46 } else if ('ethereum' in input) {
47 return {
35 input.ethereum = input.ethereum.toLowerCase();48 Ethereum: (input as any).ethereum.toLowerCase(),
36 return input;49 };
37 }50 } else if ('Substrate' in input) {
38 if ('substrate' in input) {51 return input;
39 return input;52 }else if ('substrate' in input) {
40 }53 return {
54 Substrate: (input as any).substrate,
55 };
56 }
4157
42 // AccountId58 // AccountId
43 return {substrate: input.toString()};59 return {Substrate: input.toString()};
44}60}
45export function toSubstrateAddress(input: string | CrossAccountId | IKeyringPair): string {61export function toSubstrateAddress(input: string | CrossAccountId | IKeyringPair): string {
46 input = normalizeAccountId(input);62 input = normalizeAccountId(input);
47 if ('substrate' in input) {63 if ('Substrate' in input) {
48 return input.substrate;64 return input.Substrate;
49 } else {65 } else {
50 return evmToAddress(input.ethereum);66 return evmToAddress(input.Ethereum);
51 }67 }
52}68}
5369
88 owner: number[];104 owner: number[];
89}105}
90
91interface ITokenDataType {
92 owner: IKeyringPair;
93 constData: number[];
94 variableData: number[];
95}
96106
97interface IGetMessage {107interface IGetMessage {
98 checkMsgNftMethod: string;108 checkMsgNftMethod: string;
128 let checkMsgTrsMethod = '';138 let checkMsgTrsMethod = '';
129 let checkMsgSysMethod = '';139 let checkMsgSysMethod = '';
130 events.forEach(({ event: { method, section } }) => {140 events.forEach(({event: {method, section}}) => {
131 if (section === 'nft') {141 if (section === 'common') {
132 checkMsgNftMethod = method;142 checkMsgNftMethod = method;
133 } else if (section === 'treasury') {143 } else if (section === 'treasury') {
134 checkMsgTrsMethod = method;144 checkMsgTrsMethod = method;
166 // console.log(` ${phase}: ${section}.${method}:: ${data}`);176 // console.log(` ${phase}: ${section}.${method}:: ${data}`);
167 if (method == 'ExtrinsicSuccess') {177 if (method == 'ExtrinsicSuccess') {
168 success = true;178 success = true;
169 } else if ((section == 'nft') && (method == 'CollectionCreated')) {179 } else if ((section == 'common') && (method == 'CollectionCreated')) {
170 collectionId = parseInt(data[0].toString());180 collectionId = parseInt(data[0].toString(), 10);
171 }181 }
172 });182 });
173 const result: CreateCollectionResult = {183 const result: CreateCollectionResult = {
186 // console.log(` ${phase}: ${section}.${method}:: ${data}`);196 // console.log(` ${phase}: ${section}.${method}:: ${data}`);
187 if (method == 'ExtrinsicSuccess') {197 if (method == 'ExtrinsicSuccess') {
188 success = true;198 success = true;
189 } else if ((section == 'nft') && (method == 'ItemCreated')) {199 } else if ((section == 'common') && (method == 'ItemCreated')) {
190 collectionId = parseInt(data[0].toString());200 collectionId = parseInt(data[0].toString(), 10);
191 itemId = parseInt(data[1].toString());201 itemId = parseInt(data[1].toString(), 10);
192 recipient = data[2].toJSON();202 recipient = normalizeAccountId(data[2].toJSON() as any);
193 }203 }
194 });204 });
195 const result: CreateItemResult = {205 const result: CreateItemResult = {
212 events.forEach(({ event: { data, method, section } }) => {222 events.forEach(({event: {data, method, section}}) => {
213 if (method === 'ExtrinsicSuccess') {223 if (method === 'ExtrinsicSuccess') {
214 result.success = true;224 result.success = true;
215 } else if (section === 'nft' && method === 'Transfer') {225 } else if (section === 'common' && method === 'Transfer') {
216 result.collectionId = +data[0].toString();226 result.collectionId = +data[0].toString();
217 result.itemId = +data[1].toString();227 result.itemId = +data[1].toString();
218 result.sender = data[2].toJSON() as CrossAccountId;228 result.sender = normalizeAccountId(data[2].toJSON() as any);
219 result.recipient = data[3].toJSON() as CrossAccountId;229 result.recipient = normalizeAccountId(data[3].toJSON() as any);
220 result.value = BigInt(data[4].toString());230 result.value = BigInt(data[4].toString());
221 }231 }
222 });232 });
259 let collectionId = 0;269 let collectionId = 0;
260 await usingApi(async (api) => {270 await usingApi(async (api) => {
261 // Get number of collections before the transaction271 // Get number of collections before the transaction
262 const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10);272 const collectionCountBefore = (await api.query.common.createdCollectionCount()).toNumber();
263273
264 // Run the CreateCollection transaction274 // Run the CreateCollection transaction
265 const alicePrivateKey = privateKey('//Alice');275 const alicePrivateKey = privateKey('//Alice');
273 modeprm = { refungible: null };283 modeprm = {refungible: null};
274 }284 }
275285
276 const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm);286 const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm as any);
277 const events = await submitTransactionAsync(alicePrivateKey, tx);287 const events = await submitTransactionAsync(alicePrivateKey, tx);
278 const result = getCreateCollectionResult(events);288 const result = getCreateCollectionResult(events);
279289
280 // Get number of collections after the transaction290 // Get number of collections after the transaction
281 const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10);291 const collectionCountAfter = (await api.query.common.createdCollectionCount()).toNumber();
282292
283 // Get the collection293 // Get the collection
284 const collection: any = (await api.query.nft.collectionById(result.collectionId) as any).toJSON();294 const collection = (await api.query.common.collectionById(result.collectionId)).unwrap();
285295
286 // What to expect296 // What to expect
287 // tslint:disable-next-line:no-unused-expression297 // tslint:disable-next-line:no-unused-expression
288 expect(result.success).to.be.true;298 expect(result.success).to.be.true;
289 expect(result.collectionId).to.be.equal(BcollectionCount);299 expect(result.collectionId).to.be.equal(collectionCountAfter);
290 // tslint:disable-next-line:no-unused-expression300 // tslint:disable-next-line:no-unused-expression
291 expect(collection).to.be.not.null;301 expect(collection).to.be.not.null;
292 expect(BcollectionCount).to.be.equal(AcollectionCount + 1, 'Error: NFT collection NOT created.');302 expect(collectionCountAfter).to.be.equal(collectionCountBefore + 1, 'Error: NFT collection NOT created.');
293 expect(collection.owner).to.be.equal(toSubstrateAddress(alicesPublicKey));303 expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicesPublicKey));
294 expect(utf16ToStr(collection.name)).to.be.equal(name);304 expect(utf16ToStr(collection.name.toJSON() as any)).to.be.equal(name);
295 expect(utf16ToStr(collection.description)).to.be.equal(description);305 expect(utf16ToStr(collection.description.toJSON() as any)).to.be.equal(description);
296 expect(hexToStr(collection.tokenPrefix)).to.be.equal(tokenPrefix);306 expect(hexToStr(collection.tokenPrefix.toJSON())).to.be.equal(tokenPrefix);
297307
298 collectionId = result.collectionId;308 collectionId = result.collectionId;
299 });309 });
315325
316 await usingApi(async (api) => {326 await usingApi(async (api) => {
317 // Get number of collections before the transaction327 // Get number of collections before the transaction
318 const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());328 const collectionCountBefore = (await api.query.common.createdCollectionCount()).toNumber();
319329
320 // Run the CreateCollection transaction330 // Run the CreateCollection transaction
321 const alicePrivateKey = privateKey('//Alice');331 const alicePrivateKey = privateKey('//Alice');
322 const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm);332 const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm as any);
323 const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;333 const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;
324 const result = getCreateCollectionResult(events);334 const result = getCreateCollectionResult(events);
325335
326 // Get number of collections after the transaction336 // Get number of collections after the transaction
327 const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());337 const collectionCountAfter = (await api.query.common.createdCollectionCount()).toNumber();
328338
329 // What to expect339 // What to expect
330 // tslint:disable-next-line:no-unused-expression340 // tslint:disable-next-line:no-unused-expression
331 expect(result.success).to.be.false;341 expect(result.success).to.be.false;
332 expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Collection with incorrect data created.');342 expect(collectionCountAfter).to.be.equal(collectionCountBefore, 'Error: Collection with incorrect data created.');
333 });343 });
334}344}
335345
336export async function findUnusedAddress(api: ApiPromise, seedAddition = ''): Promise<IKeyringPair> {346export async function findUnusedAddress(api: ApiPromise, seedAddition = ''): Promise<IKeyringPair> {
337 let bal = new BigNumber(0);347 let bal = 0n;
338 let unused;348 let unused;
339 do {349 do {
340 const randomSeed = 'seed' + Math.floor(Math.random() * Math.floor(10000)) + seedAddition;350 const randomSeed = 'seed' + Math.floor(Math.random() * Math.floor(10000)) + seedAddition;
341 const keyring = new Keyring({ type: 'sr25519' });351 const keyring = new Keyring({type: 'sr25519'});
342 unused = keyring.addFromUri(`//${randomSeed}`);352 unused = keyring.addFromUri(`//${randomSeed}`);
343 bal = new BigNumber((await api.query.system.account(unused.address)).data.free.toString());353 bal = (await api.query.system.account(unused.address)).data.free.toBigInt();
344 } while (bal.toFixed() != '0');354 } while (bal !== 0n);
345 return unused;355 return unused;
346}356}
347357
348export async function getAllowance(collectionId: number, tokenId: number, owner: string, approved: string) {358export async function getAllowance(api: ApiPromise, collectionId: number, owner: CrossAccountId | string, approved: CrossAccountId | string, tokenId: number) {
349 return await usingApi(async (api) => {359 return (await api.rpc.nft.allowance(collectionId, normalizeAccountId(owner), normalizeAccountId(approved), tokenId)).toBigInt();
350 const bn = await api.query.nft.allowances(collectionId, [tokenId, owner, approved]) as unknown as BN;
351 return BigInt(bn.toString());
352 });
353}360}
354361
355export function findUnusedAddresses(api: ApiPromise, amount: number): Promise<IKeyringPair[]> {362export function findUnusedAddresses(api: ApiPromise, amount: number): Promise<IKeyringPair[]> {
356 return Promise.all(new Array(amount).fill(null).map(() => findUnusedAddress(api, '_' + Date.now())));363 return Promise.all(new Array(amount).fill(null).map(() => findUnusedAddress(api, '_' + Date.now())));
357}364}
358365
359export async function findNotExistingCollection(api: ApiPromise): Promise<number> {366export async function findNotExistingCollection(api: ApiPromise): Promise<number> {
360 const totalNumber = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10) as unknown as number;367 const totalNumber = (await api.query.common.createdCollectionCount()).toNumber();
361 const newCollection: number = totalNumber + 1;368 const newCollection: number = totalNumber + 1;
362 return newCollection;369 return newCollection;
363}370}
389 const events = await submitTransactionAsync(alicePrivateKey, tx);396 const events = await submitTransactionAsync(alicePrivateKey, tx);
390 const result = getDestroyResult(events);397 const result = getDestroyResult(events);
391
392 // Get the collection
393 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
394
395 // What to expect
396 expect(result).to.be.true;398 expect(result).to.be.true;
399
400 // What to expect
397 expect(collection).to.be.null;401 expect((await api.query.common.collectionById(collectionId)).isNone).to.be.true;
398 });402 });
399}403}
400
401export async function queryCollectionLimits(collectionId: number) {
402 return await usingApi(async (api) => {
403 return ((await api.query.nft.collectionById(collectionId)).toJSON() as any).limits;
404 });
405}
406404
407export async function setCollectionLimitsExpectSuccess(sender: IKeyringPair, collectionId: number, limits: any) {405export async function setCollectionLimitsExpectSuccess(sender: IKeyringPair, collectionId: number, limits: any) {
408 await usingApi(async (api) => {406 await usingApi(async (api) => {
409 const oldLimits = await queryCollectionLimits(collectionId);
410 const newLimits = { ...oldLimits as any, ...limits };
411 const tx = api.tx.nft.setCollectionLimits(collectionId, newLimits);407 const tx = api.tx.nft.setCollectionLimits(collectionId, limits);
412 const events = await submitTransactionAsync(sender, tx);408 const events = await submitTransactionAsync(sender, tx);
413 const result = getGenericResult(events);409 const result = getGenericResult(events);
414410
418414
419export async function setCollectionLimitsExpectFailure(sender: IKeyringPair, collectionId: number, limits: any) {415export async function setCollectionLimitsExpectFailure(sender: IKeyringPair, collectionId: number, limits: any) {
420 await usingApi(async (api) => {416 await usingApi(async (api) => {
421 const oldLimits = await queryCollectionLimits(collectionId);
422 const newLimits = { ...oldLimits as any, ...limits };
423 const tx = api.tx.nft.setCollectionLimits(collectionId, newLimits);417 const tx = api.tx.nft.setCollectionLimits(collectionId, limits);
424 const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;418 const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
425 const result = getGenericResult(events);419 const result = getGenericResult(events);
426420
438 const result = getGenericResult(events);432 const result = getGenericResult(events);
439433
440 // Get the collection434 // Get the collection
441 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();435 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
442436
443 // What to expect437 // What to expect
444 expect(result.success).to.be.true;438 expect(result.success).to.be.true;
445 expect(collection.sponsorship).to.deep.equal({439 expect(collection.sponsorship.toJSON()).to.deep.equal({
446 unconfirmed: sponsor,440 unconfirmed: sponsor,
447 });441 });
448 });442 });
458 const result = getGenericResult(events);452 const result = getGenericResult(events);
459453
460 // Get the collection454 // Get the collection
461 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();455 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
462456
463 // What to expect457 // What to expect
464 expect(result.success).to.be.true;458 expect(result.success).to.be.true;
465 expect(collection.sponsorship).to.be.deep.equal({ disabled: null });459 expect(collection.sponsorship.toJSON()).to.be.deep.equal({disabled: null});
466 });460 });
467}461}
468462
496 const result = getGenericResult(events);490 const result = getGenericResult(events);
497491
498 // Get the collection492 // Get the collection
499 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();493 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
500494
501 // What to expect495 // What to expect
502 expect(result.success).to.be.true;496 expect(result.success).to.be.true;
503 expect(collection.sponsorship).to.be.deep.equal({497 expect(collection.sponsorship.toJSON()).to.be.deep.equal({
504 confirmed: sender.address,498 confirmed: sender.address,
505 });499 });
506 });500 });
520export async function setMetadataUpdatePermissionFlagExpectSuccess(sender: IKeyringPair, collectionId: number, flag: string) {514export async function setMetadataUpdatePermissionFlagExpectSuccess(sender: IKeyringPair, collectionId: number, flag: string) {
521515
522 await usingApi(async (api) => {516 await usingApi(async (api) => {
523 const tx = api.tx.nft.setMetaUpdatePermissionFlag(collectionId, flag);517 const tx = api.tx.nft.setMetaUpdatePermissionFlag(collectionId, flag as any);
524 const events = await submitTransactionAsync(sender, tx);518 const events = await submitTransactionAsync(sender, tx);
525 const result = getGenericResult(events);519 const result = getGenericResult(events);
526520
531export async function setMetadataUpdatePermissionFlagExpectFailure(sender: IKeyringPair, collectionId: number, flag: string) {525export async function setMetadataUpdatePermissionFlagExpectFailure(sender: IKeyringPair, collectionId: number, flag: string) {
532526
533 await usingApi(async (api) => {527 await usingApi(async (api) => {
534 const tx = api.tx.nft.setMetaUpdatePermissionFlag(collectionId, flag);528 const tx = api.tx.nft.setMetaUpdatePermissionFlag(collectionId, flag as any);
535 const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;529 const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
536 const result = getGenericResult(events);530 const result = getGenericResult(events);
537531
702696
703export async function burnItemExpectSuccess(sender: IKeyringPair, collectionId: number, tokenId: number, value = 1) {697export async function burnItemExpectSuccess(sender: IKeyringPair, collectionId: number, tokenId: number, value = 1) {
704 await usingApi(async (api) => {698 await usingApi(async (api) => {
699 const balanceBefore = await getBalance(api, collectionId, normalizeAccountId(sender), tokenId);
700 // if burning token by admin - use adminButnItemExpectSuccess
701 expect(balanceBefore >= BigInt(value)).to.be.true;
702
705 const tx = api.tx.nft.burnItem(collectionId, tokenId, value);703 const tx = api.tx.nft.burnItem(collectionId, tokenId, value);
706 const events = await submitTransactionAsync(sender, tx);704 const events = await submitTransactionAsync(sender, tx);
707 const result = getGenericResult(events);705 const result = getGenericResult(events);
708 // Get the item
709 const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();
710 // What to expect
711 // tslint:disable-next-line:no-unused-expression
712 expect(result.success).to.be.true;706 expect(result.success).to.be.true;
713 // tslint:disable-next-line:no-unused-expression707
708 const balanceAfter = await getBalance(api, collectionId, normalizeAccountId(sender), tokenId);
714 expect(item).to.be.null;709 expect(balanceAfter + BigInt(value)).to.be.equal(balanceBefore);
715 });710 });
716}711}
717712
718export async function713export async function
719approveExpectSuccess(714approveExpectSuccess(
720 collectionId: number,715 collectionId: number,
721 tokenId: number, owner: IKeyringPair, approved: IKeyringPair | CrossAccountId | string, amount: number | bigint = 1,716 tokenId: number, owner: IKeyringPair, approved: CrossAccountId | string, amount: number | bigint = 1,
722) {717) {
723 await usingApi(async (api: ApiPromise) => {718 await usingApi(async (api: ApiPromise) => {
724 approved = normalizeAccountId(approved);
725 const allowanceBefore =
726 await api.query.nft.allowances(collectionId, [tokenId, owner.address, toSubstrateAddress(approved)]) as unknown as BN;
727 const approveNftTx = api.tx.nft.approve(approved, collectionId, tokenId, amount);719 const approveNftTx = api.tx.nft.approve(normalizeAccountId(approved), collectionId, tokenId, amount);
728 const events = await submitTransactionAsync(owner, approveNftTx);720 const events = await submitTransactionAsync(owner, approveNftTx);
729 const result = getCreateItemResult(events);721 const result = getGenericResult(events);
730 // tslint:disable-next-line:no-unused-expression
731 expect(result.success).to.be.true;722 expect(result.success).to.be.true;
732 const allowanceAfter =723
733 await api.query.nft.allowances(collectionId, [tokenId, owner.address, toSubstrateAddress(approved)]) as unknown as BN;
734 expect(allowanceAfter.sub(allowanceBefore).toString()).to.be.equal(amount.toString());724 expect(await getAllowance(api, collectionId, owner.address, approved, tokenId)).to.be.equal(BigInt(amount));
735 });725 });
736}726}
727
728export async function adminApproveFromExpectSuccess(
729 collectionId: number,
730 tokenId: number, admin: IKeyringPair, owner: CrossAccountId | string, approved: CrossAccountId | string, amount: number | bigint = 1,
731) {
732 await usingApi(async (api: ApiPromise) => {
733 const approveNftTx = api.tx.nft.approve(normalizeAccountId(approved), collectionId, tokenId, amount);
734 const events = await submitTransactionAsync(admin, approveNftTx);
735 const result = getGenericResult(events);
736 expect(result.success).to.be.true;
737
738 expect(await getAllowance(api, collectionId, owner, approved, tokenId)).to.be.equal(BigInt(amount));
739 });
740}
737741
738export async function742export async function
739transferFromExpectSuccess(743transferFromExpectSuccess(
747) {751) {
748 await usingApi(async (api: ApiPromise) => {752 await usingApi(async (api: ApiPromise) => {
749 const to = normalizeAccountId(accountTo);753 const to = normalizeAccountId(accountTo);
750 let balanceBefore = new BN(0);754 let balanceBefore = 0n;
751 if (type === 'Fungible') {755 if (type === 'Fungible') {
752 balanceBefore = await api.query.nft.balance(collectionId, toSubstrateAddress(to)) as unknown as BN;756 balanceBefore = await getBalance(api, collectionId, to, tokenId);
753 }757 }
754 const transferFromTx = api.tx.nft.transferFrom(normalizeAccountId(accountFrom), to, collectionId, tokenId, value);758 const transferFromTx = api.tx.nft.transferFrom(normalizeAccountId(accountFrom), to, collectionId, tokenId, value);
755 const events = await submitTransactionAsync(accountApproved, transferFromTx);759 const events = await submitTransactionAsync(accountApproved, transferFromTx);
756 const result = getCreateItemResult(events);760 const result = getCreateItemResult(events);
757 // tslint:disable-next-line:no-unused-expression761 // tslint:disable-next-line:no-unused-expression
758 expect(result.success).to.be.true;762 expect(result.success).to.be.true;
759 if (type === 'NFT') {763 if (type === 'NFT') {
760 const nftItemData = (await api.query.nft.nftItemList(collectionId, tokenId) as any).toJSON() as ITokenDataType;
761 expect(nftItemData.owner).to.be.deep.equal(to);764 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(to);
762 }765 }
763 if (type === 'Fungible') {766 if (type === 'Fungible') {
764 const balanceAfter = (await api.query.nft.fungibleItemList(collectionId, toSubstrateAddress(to)) as any).value as unknown as BN;767 const balanceAfter = await getBalance(api, collectionId, to, tokenId);
765 expect(balanceAfter.sub(balanceBefore).toString()).to.be.equal(value.toString());768 expect(balanceAfter - balanceBefore).to.be.equal(BigInt(value));
766 }769 }
767 if (type === 'ReFungible') {770 if (type === 'ReFungible') {
768 const nftItemData =
769 (await api.query.nft.reFungibleItemList(collectionId, tokenId) as any).toJSON() as IReFungibleTokenDataType;
770 expect(nftItemData.owner[0].owner).to.be.deep.equal(normalizeAccountId(to));
771 expect(nftItemData.owner[0].fraction).to.be.equal(value);771 expect(await getBalance(api, collectionId, to, tokenId)).to.be.equal(BigInt(value));
772 }772 }
773 });773 });
774}774}
801 });801 });
802}802}
803803
804export async function addCollectionAdminExpectSuccess(sender: IKeyringPair, collectionId: number, address: IKeyringPair) {804export async function addCollectionAdminExpectSuccess(sender: IKeyringPair, collectionId: number, address: string | CrossAccountId) {
805 await usingApi(async (api) => {805 await usingApi(async (api) => {
806 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(address.address));806 const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(address));
807 const events = await submitTransactionAsync(sender, changeAdminTx);807 const events = await submitTransactionAsync(sender, changeAdminTx);
808 const result = getCreateCollectionResult(events);808 const result = getCreateCollectionResult(events);
809 expect(result.success).to.be.true;809 expect(result.success).to.be.true;
828 sender: IKeyringPair,828 sender: IKeyringPair,
829 recipient: IKeyringPair,829 recipient: IKeyringPair,
830 value: number | bigint = 1,830 value: number | bigint = 1,
831 blockTimeMs: number,
832 blockSchedule: number,831 blockSchedule: number,
833) {832) {
834 await usingApi(async (api: ApiPromise) => {833 await usingApi(async (api: ApiPromise) => {
835 const blockNumber: number | undefined = await getBlockNumber(api);834 const blockNumber: number | undefined = await getBlockNumber(api);
836 const expectedBlockNumber = blockNumber + blockSchedule;835 const expectedBlockNumber = blockNumber + blockSchedule;
837836
838 expect(blockNumber).to.be.greaterThan(0);837 expect(blockNumber).to.be.greaterThan(0);
839 const transferTx = await api.tx.nft.transfer(normalizeAccountId(recipient.address), collectionId, tokenId, value);838 const transferTx = api.tx.nft.transfer(normalizeAccountId(recipient.address), collectionId, tokenId, value);
840 const scheduleTx = await api.tx.scheduler.schedule(expectedBlockNumber, null, 0, transferTx);839 const scheduleTx = api.tx.scheduler.schedule(expectedBlockNumber, null, 0, transferTx as any);
841840
842 await submitTransactionAsync(sender, scheduleTx);841 await submitTransactionAsync(sender, scheduleTx);
843842
844 const recipientBalanceBefore = new BigNumber((await api.query.system.account(recipient.address)).data.free.toString());843 const recipientBalanceBefore = (await api.query.system.account(recipient.address)).data.free.toBigInt();
845844
846 const nftItemDataBefore = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON() as any as ITokenDataType;
847 expect(toSubstrateAddress(nftItemDataBefore.owner)).to.be.equal(sender.address);845 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(sender.address));
848846
849 // sleep for 4 blocks847 // sleep for 4 blocks
850 await new Promise(resolve => setTimeout(resolve, blockTimeMs * (blockSchedule + 1)));848 await waitNewBlocks(blockSchedule + 1);
851849
852 const recipientBalanceAfter = new BigNumber((await api.query.system.account(recipient.address)).data.free.toString());850 const recipientBalanceAfter = (await api.query.system.account(recipient.address)).data.free.toBigInt();
853851
854 const nftItemData = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON() as unknown as ITokenDataType;
855 expect(toSubstrateAddress(nftItemData.owner)).to.be.equal(recipient.address);852 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(recipient.address));
856 expect(recipientBalanceAfter.toNumber()).to.be.equal(recipientBalanceBefore.toNumber());853 expect(recipientBalanceAfter).to.be.equal(recipientBalanceBefore);
857 });854 });
858}855}
859856
870 await usingApi(async (api: ApiPromise) => {867 await usingApi(async (api: ApiPromise) => {
871 const to = normalizeAccountId(recipient);868 const to = normalizeAccountId(recipient);
872869
873 let balanceBefore = new BN(0);870 let balanceBefore = 0n;
874 if (type === 'Fungible') {871 if (type === 'Fungible') {
875 balanceBefore = await api.query.nft.balance(collectionId, toSubstrateAddress(to)) as unknown as BN;872 balanceBefore = await getBalance(api, collectionId, to, tokenId);
876 }873 }
877 const transferTx = api.tx.nft.transfer(to, collectionId, tokenId, value);874 const transferTx = api.tx.nft.transfer(to, collectionId, tokenId, value);
878 const events = await submitTransactionAsync(sender, transferTx);875 const events = await submitTransactionAsync(sender, transferTx);
883 expect(result.itemId).to.be.equal(tokenId);880 expect(result.itemId).to.be.equal(tokenId);
884 expect(result.sender).to.be.deep.equal(normalizeAccountId(sender.address));881 expect(result.sender).to.be.deep.equal(normalizeAccountId(sender.address));
885 expect(result.recipient).to.be.deep.equal(to);882 expect(result.recipient).to.be.deep.equal(to);
886 expect(result.value.toString()).to.be.equal(value.toString());883 expect(result.value).to.be.equal(BigInt(value));
887 if (type === 'NFT') {884 if (type === 'NFT') {
888 const nftItemData = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON() as unknown as ITokenDataType;
889 expect(nftItemData.owner).to.be.deep.equal(to);885 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(to);
890 }886 }
891 if (type === 'Fungible') {887 if (type === 'Fungible') {
892 const balanceAfter = (await api.query.nft.fungibleItemList(collectionId, toSubstrateAddress(to)) as any).value as unknown as BN;888 const balanceAfter = await getBalance(api, collectionId, to, tokenId);
893 expect(balanceAfter.sub(balanceBefore).toString()).to.be.equal(value.toString());889 expect(balanceAfter - balanceBefore).to.be.equal(BigInt(value));
894 }890 }
895 if (type === 'ReFungible') {891 if (type === 'ReFungible') {
896 const nftItemData =
897 (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON() as unknown as IReFungibleTokenDataType;892 expect(await getBalance(api, collectionId, to, tokenId) >= value).to.be.true;
898 const expectedOwner = toSubstrateAddress(to);
899 const ownerIndex = nftItemData.owner.findIndex(v => toSubstrateAddress(v.owner as any as string) == expectedOwner);
900 expect(ownerIndex).to.not.equal(-1);
901 expect(nftItemData.owner[ownerIndex].owner).to.be.deep.equal(normalizeAccountId(to));
902 expect(nftItemData.owner[ownerIndex].fraction).to.be.greaterThanOrEqual(value as number);
903 }893 }
904 });894 });
905}895}
937 });927 });
938}928}
939929
930export async function getBalance(
931 api: ApiPromise,
932 collectionId: number,
933 owner: string | CrossAccountId,
934 token: number,
935): Promise<bigint> {
936 return (await api.rpc.nft.balance(collectionId, normalizeAccountId(owner), token)).toBigInt();
937}
940export async function getFungibleBalance(938export async function getTokenOwner(
939 api: ApiPromise,
941 collectionId: number,940 collectionId: number,
942 owner: string,941 token: number,
943) {942): Promise<CrossAccountId> {
944 return await usingApi(async (api) => {943 return normalizeAccountId((await api.rpc.nft.tokenOwner(collectionId, token)).toJSON() as any);
945 const response = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON() as unknown as { value: string };
946 return BigInt(response.value);
947 });
948}944}
945export async function isTokenExists(
946 api: ApiPromise,
947 collectionId: number,
948 token: number,
949): Promise<boolean> {
950 return (await api.rpc.nft.tokenExists(collectionId, token)).toJSON();
951}
952export async function getLastTokenId(
953 api: ApiPromise,
954 collectionId: number,
955): Promise<number> {
956 return (await api.rpc.nft.lastTokenId(collectionId)).toJSON();
957}
958export async function getAdminList(
959 api: ApiPromise,
960 collectionId: number,
961): Promise<string[]> {
962 return (await api.rpc.nft.adminlist(collectionId)).toHuman() as any;
963}
964export async function getVariableMetadata(
965 api: ApiPromise,
966 collectionId: number,
967 tokenId: number,
968): Promise<number[]> {
969 return [...(await api.rpc.nft.variableMetadata(collectionId, tokenId))];
970}
971export async function getConstMetadata(
972 api: ApiPromise,
973 collectionId: number,
974 tokenId: number,
975): Promise<number[]> {
976 return [...(await api.rpc.nft.constMetadata(collectionId, tokenId))];
977}
949978
950export async function createFungibleItemExpectSuccess(979export async function createFungibleItemExpectSuccess(
951 sender: IKeyringPair,980 sender: IKeyringPair,
968 let newItemId = 0;997 let newItemId = 0;
969 await usingApi(async (api) => {998 await usingApi(async (api) => {
970 const to = normalizeAccountId(owner);999 const to = normalizeAccountId(owner);
971 const AItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString(), 10);1000 const itemCountBefore = await getLastTokenId(api, collectionId);
972 const Aitem: any = (await api.query.nft.fungibleItemList(collectionId, toSubstrateAddress(to))).toJSON();1001 const itemBalanceBefore = await getBalance(api, collectionId, to, newItemId);
973 const AItemBalance = new BigNumber(Aitem.value);
9741002
975 let tx;1003 let tx;
976 if (createMode === 'Fungible') {1004 if (createMode === 'Fungible') {
977 const createData = { fungible: { value: 10 } };1005 const createData = {fungible: {value: 10}};
978 tx = api.tx.nft.createItem(collectionId, to, createData);1006 tx = api.tx.nft.createItem(collectionId, to, createData as any);
979 } else if (createMode === 'ReFungible') {1007 } else if (createMode === 'ReFungible') {
980 const createData = { refungible: { const_data: [], variable_data: [], pieces: 100 } };1008 const createData = {refungible: {const_data: [], variable_data: [], pieces: 100}};
981 tx = api.tx.nft.createItem(collectionId, to, createData);1009 tx = api.tx.nft.createItem(collectionId, to, createData as any);
982 } else {1010 } else {
983 const createData = { nft: { const_data: [], variable_data: [] } };1011 const createData = {nft: {const_data: [], variable_data: []}};
984 tx = api.tx.nft.createItem(collectionId, to, createData);1012 tx = api.tx.nft.createItem(collectionId, to, createData as any);
985 }1013 }
9861014
987 const events = await submitTransactionAsync(sender, tx);1015 const events = await submitTransactionAsync(sender, tx);
988 const result = getCreateItemResult(events);1016 const result = getCreateItemResult(events);
9891017
990 const BItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString(), 10);1018 const itemCountAfter = await getLastTokenId(api, collectionId);
991 const Bitem: any = (await api.query.nft.fungibleItemList(collectionId, toSubstrateAddress(to))).toJSON();1019 const itemBalanceAfter = await getBalance(api, collectionId, to, newItemId);
992 const BItemBalance = new BigNumber(Bitem.value);
9931020
994 // What to expect1021 // What to expect
995 // tslint:disable-next-line:no-unused-expression1022 // tslint:disable-next-line:no-unused-expression
996 expect(result.success).to.be.true;1023 expect(result.success).to.be.true;
997 if (createMode === 'Fungible') {1024 if (createMode === 'Fungible') {
998 expect(BItemBalance.minus(AItemBalance).toNumber()).to.be.equal(10);1025 expect(itemBalanceAfter - itemBalanceBefore).to.be.equal(10n);
999 } else {1026 } else {
1000 expect(BItemCount).to.be.equal(AItemCount + 1);1027 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
1001 }1028 }
1002 expect(collectionId).to.be.equal(result.collectionId);1029 expect(collectionId).to.be.equal(result.collectionId);
1003 expect(BItemCount.toString()).to.be.equal(result.itemId.toString());1030 expect(itemCountAfter.toString()).to.be.equal(result.itemId.toString());
1004 expect(to).to.be.deep.equal(result.recipient);1031 expect(to).to.be.deep.equal(result.recipient);
1005 newItemId = result.itemId;1032 newItemId = result.itemId;
1006 });1033 });
1030 const result = getGenericResult(events);1057 const result = getGenericResult(events);
10311058
1032 // Get the collection1059 // Get the collection
1033 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();1060 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
10341061
1035 // What to expect1062 // What to expect
1036 // tslint:disable-next-line:no-unused-expression1063 // tslint:disable-next-line:no-unused-expression
1037 expect(result.success).to.be.true;1064 expect(result.success).to.be.true;
1038 expect(collection.access).to.be.equal(accessMode);1065 expect(collection.access.toHuman()).to.be.equal(accessMode);
1039 });1066 });
1040}1067}
10411068
1075 const tx = api.tx.nft.setMintPermission(collectionId, enabled);1102 const tx = api.tx.nft.setMintPermission(collectionId, enabled);
1076 const events = await submitTransactionAsync(sender, tx);1103 const events = await submitTransactionAsync(sender, tx);
1077 const result = getGenericResult(events);1104 const result = getGenericResult(events);
1105 expect(result.success).to.be.true;
10781106
1079 // Get the collection1107 // Get the collection
1080 const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();1108 const collection = (await api.query.common.collectionById(collectionId)).unwrap();
10811109
1082 // What to expect
1083 // tslint:disable-next-line:no-unused-expression
1084 expect(result.success).to.be.true;
1085 expect(collection.mintMode).to.be.equal(enabled);1110 expect(collection.mintMode.toHuman()).to.be.equal(enabled);
1086 });1111 });
1087}1112}
10881113
1112 });1137 });
1113}1138}
11141139
1115export async function isWhitelisted(collectionId: number, address: string) {1140export async function isWhitelisted(collectionId: number, address: string | CrossAccountId) {
1116 let whitelisted = false;
1117 await usingApi(async (api) => {1141 return await usingApi(async (api) => {
1118 whitelisted = (await api.query.nft.whiteList(collectionId, address)).toJSON() as unknown as boolean;1142 return (await api.query.common.allowlist(collectionId, normalizeAccountId(address))).toJSON();
1119 });1143 });
1120 return whitelisted;
1121}1144}
11221145
1123export async function addToWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number, address: string | AccountId) {1146export async function addToWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number, address: string | AccountId | CrossAccountId) {
1124 await usingApi(async (api) => {1147 await usingApi(async (api) => {
1125
1126 const whiteListedBefore = (await api.query.nft.whiteList(collectionId, address)).toJSON();1148 expect(await isWhitelisted(collectionId, normalizeAccountId(address))).to.be.false;
11271149
1128 // Run the transaction1150 // Run the transaction
1129 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(address));1151 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(address));
1130 const events = await submitTransactionAsync(sender, tx);1152 const events = await submitTransactionAsync(sender, tx);
1131 const result = getGenericResult(events);1153 const result = getGenericResult(events);
1132
1133 const whiteListedAfter = (await api.query.nft.whiteList(collectionId, address)).toJSON();
1134
1135 // What to expect
1136 // tslint:disable-next-line:no-unused-expression
1137 expect(result.success).to.be.true;1154 expect(result.success).to.be.true;
1138 // tslint:disable-next-line: no-unused-expression1155
1139 expect(whiteListedBefore).to.be.false;
1140 // tslint:disable-next-line: no-unused-expression
1141 expect(whiteListedAfter).to.be.true;1156 expect(await isWhitelisted(collectionId, normalizeAccountId(address))).to.be.true;
1142 });1157 });
1143}1158}
11441159
1145export async function addToWhiteListAgainExpectSuccess(sender: IKeyringPair, collectionId: number, address: string | AccountId) {1160export async function addToWhiteListAgainExpectSuccess(sender: IKeyringPair, collectionId: number, address: string | AccountId) {
1146 await usingApi(async (api) => {1161 await usingApi(async (api) => {
11471162
1148 const whiteListedBefore = (await api.query.nft.whiteList(collectionId, address)).toJSON();1163 expect(await isWhitelisted(collectionId, normalizeAccountId(address))).to.be.true;
11491164
1150 // Run the transaction1165 // Run the transaction
1151 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(address));1166 const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(address));
1152 const events = await submitTransactionAsync(sender, tx);1167 const events = await submitTransactionAsync(sender, tx);
1153 const result = getGenericResult(events);1168 const result = getGenericResult(events);
1154
1155 const whiteListedAfter = (await api.query.nft.whiteList(collectionId, address)).toJSON();
1156
1157 // What to expect
1158 // tslint:disable-next-line:no-unused-expression
1159 expect(result.success).to.be.true;1169 expect(result.success).to.be.true;
1160 // tslint:disable-next-line: no-unused-expression1170
1161 expect(whiteListedBefore).to.be.true;1171 expect(await isWhitelisted(collectionId, normalizeAccountId(address))).to.be.true;
1162 // tslint:disable-next-line: no-unused-expression
1163 expect(whiteListedAfter).to.be.true;
1164 });1172 });
1165}1173}
11661174
1205}1213}
12061214
1207export const getDetailedCollectionInfo = async (api: ApiPromise, collectionId: number)1215export const getDetailedCollectionInfo = async (api: ApiPromise, collectionId: number)
1208 : Promise<ICollectionInterface | null> => {1216 : Promise<NftDataStructsCollection | null> => {
1209 return (await api.query.nft.collectionById(collectionId)).toJSON() as unknown as ICollectionInterface;1217 return (await api.query.common.collectionById(collectionId)).unwrapOr(null);
1210};1218};
12111219
1212export const getCreatedCollectionCount = async (api: ApiPromise): Promise<number> => {1220export const getCreatedCollectionCount = async (api: ApiPromise): Promise<number> => {
1213 // set global object - collectionsCount1221 // set global object - collectionsCount
1214 return (await api.query.nft.createdCollectionCount() as unknown as BN).toNumber();1222 return (await api.query.common.createdCollectionCount()).toNumber();
1215};1223};
1216
1217export async function queryCollectionExpectSuccess(collectionId: number): Promise<ICollectionInterface> {
1218 return await usingApi(async (api) => {
1219 return (await api.query.nft.collectionById(collectionId)).toJSON() as unknown as ICollectionInterface;
1220 });
1221}
12221224
1223export async function queryNftOwner(api: ApiPromise, collectionId: number, tokenId: number): Promise<CrossAccountId> {1225export async function queryCollectionExpectSuccess(api: ApiPromise, collectionId: number): Promise<NftDataStructsCollection> {
1224 return normalizeAccountId((await api.query.nft.nftItemList(collectionId, tokenId) as any).toJSON().owner);1226 return (await api.query.common.collectionById(collectionId)).unwrap();
1225}1227}
12261228
1227export async function waitNewBlocks(blocksCount = 1): Promise<void> {1229export async function waitNewBlocks(blocksCount = 1): Promise<void> {
modifiedtests/src/whiteLists.test.tsdiffbeforeafterboth
3// file 'LICENSE', which is part of this source code package.3// file 'LICENSE', which is part of this source code package.
4//4//
55
6import { IKeyringPair } from '@polkadot/types/types';6import {IKeyringPair} from '@polkadot/types/types';
7import chai from 'chai';7import chai from 'chai';
8import chaiAsPromised from 'chai-as-promised';8import chaiAsPromised from 'chai-as-promised';
9import privateKey from './substrate/privateKey';9import privateKey from './substrate/privateKey';
10import usingApi, { submitTransactionExpectFailAsync } from './substrate/substrate-api';10import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api';
11import {11import {
12 addToWhiteListExpectSuccess,12 addToWhiteListExpectSuccess,
13 createCollectionExpectSuccess,13 createCollectionExpectSuccess,
32chai.use(chaiAsPromised);32chai.use(chaiAsPromised);
33const expect = chai.expect;33const expect = chai.expect;
3434
35let Alice: IKeyringPair;35let alice: IKeyringPair;
36let Bob: IKeyringPair;36let bob: IKeyringPair;
37let Charlie: IKeyringPair;37let charlie: IKeyringPair;
3838
39describe('Integration Test ext. White list tests', () => {39describe('Integration Test ext. White list tests', () => {
4040
41 before(async () => {41 before(async () => {
42 await usingApi(async () => {42 await usingApi(async () => {
43 Alice = privateKey('//Alice');43 alice = privateKey('//Alice');
44 Bob = privateKey('//Bob');44 bob = privateKey('//Bob');
45 Charlie = privateKey('//Charlie');45 charlie = privateKey('//Charlie');
46 });46 });
47 });47 });
4848
49 it('Owner can add address to white list', async () => {49 it('Owner can add address to white list', async () => {
50 const collectionId = await createCollectionExpectSuccess();50 const collectionId = await createCollectionExpectSuccess();
51 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);51 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
52 });52 });
5353
54 it('Admin can add address to white list', async () => {54 it('Admin can add address to white list', async () => {
55 const collectionId = await createCollectionExpectSuccess();55 const collectionId = await createCollectionExpectSuccess();
56 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);56 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
57 await addToWhiteListExpectSuccess(Bob, collectionId, Charlie.address);57 await addToWhiteListExpectSuccess(bob, collectionId, charlie.address);
58 });58 });
5959
60 it('Non-privileged user cannot add address to white list', async () => {60 it('Non-privileged user cannot add address to white list', async () => {
61 const collectionId = await createCollectionExpectSuccess();61 const collectionId = await createCollectionExpectSuccess();
62 await addToWhiteListExpectFail(Bob, collectionId, Charlie.address);62 await addToWhiteListExpectFail(bob, collectionId, charlie.address);
63 });63 });
6464
65 it('Nobody can add address to white list of non-existing collection', async () => {65 it('Nobody can add address to white list of non-existing collection', async () => {
66 const collectionId = (1<<32) - 1;66 const collectionId = (1<<32) - 1;
67 await addToWhiteListExpectFail(Alice, collectionId, Bob.address);67 await addToWhiteListExpectFail(alice, collectionId, bob.address);
68 });68 });
6969
70 it('Nobody can add address to white list of destroyed collection', async () => {70 it('Nobody can add address to white list of destroyed collection', async () => {
71 const collectionId = await createCollectionExpectSuccess();71 const collectionId = await createCollectionExpectSuccess();
72 await destroyCollectionExpectSuccess(collectionId, '//Alice');72 await destroyCollectionExpectSuccess(collectionId, '//Alice');
73 await addToWhiteListExpectFail(Alice, collectionId, Bob.address);73 await addToWhiteListExpectFail(alice, collectionId, bob.address);
74 });74 });
7575
76 it('If address is already added to white list, nothing happens', async () => {76 it('If address is already added to white list, nothing happens', async () => {
77 const collectionId = await createCollectionExpectSuccess();77 const collectionId = await createCollectionExpectSuccess();
78 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);78 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
79 await addToWhiteListAgainExpectSuccess(Alice, collectionId, Bob.address);79 await addToWhiteListAgainExpectSuccess(alice, collectionId, bob.address);
80 });80 });
8181
82 it('Owner can remove address from white list', async () => {82 it('Owner can remove address from white list', async () => {
83 const collectionId = await createCollectionExpectSuccess();83 const collectionId = await createCollectionExpectSuccess();
84 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);84 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
85 await removeFromWhiteListExpectSuccess(Alice, collectionId, normalizeAccountId(Bob));85 await removeFromWhiteListExpectSuccess(alice, collectionId, normalizeAccountId(bob));
86 }); 86 });
8787
88 it('Admin can remove address from white list', async () => {88 it('Admin can remove address from white list', async () => {
89 const collectionId = await createCollectionExpectSuccess();89 const collectionId = await createCollectionExpectSuccess();
90 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);90 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
91 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);91 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
92 await removeFromWhiteListExpectSuccess(Bob, collectionId, normalizeAccountId(Charlie));92 await removeFromWhiteListExpectSuccess(bob, collectionId, normalizeAccountId(charlie));
93 }); 93 });
9494
95 it('Non-privileged user cannot remove address from white list', async () => {95 it('Non-privileged user cannot remove address from white list', async () => {
96 const collectionId = await createCollectionExpectSuccess();96 const collectionId = await createCollectionExpectSuccess();
97 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);97 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
98 await removeFromWhiteListExpectFailure(Bob, collectionId, normalizeAccountId(Charlie));98 await removeFromWhiteListExpectFailure(bob, collectionId, normalizeAccountId(charlie));
99 }); 99 });
100100
101 it('Nobody can remove address from white list of non-existing collection', async () => {101 it('Nobody can remove address from white list of non-existing collection', async () => {
102 const collectionId = (1<<32) - 1;102 const collectionId = (1<<32) - 1;
103 await removeFromWhiteListExpectFailure(Alice, collectionId, normalizeAccountId(Charlie));103 await removeFromWhiteListExpectFailure(alice, collectionId, normalizeAccountId(charlie));
104 }); 104 });
105105
106
107
108 it('Nobody can remove address from white list of deleted collection', async () => {106 it('Nobody can remove address from white list of deleted collection', async () => {
109 const collectionId = await createCollectionExpectSuccess();107 const collectionId = await createCollectionExpectSuccess();
110 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);108 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
111 await destroyCollectionExpectSuccess(collectionId, '//Alice');109 await destroyCollectionExpectSuccess(collectionId, '//Alice');
112 await removeFromWhiteListExpectFailure(Alice, collectionId, normalizeAccountId(Charlie));110 await removeFromWhiteListExpectFailure(alice, collectionId, normalizeAccountId(charlie));
113 }); 111 });
114112
115 it('If address is already removed from white list, nothing happens', async () => {113 it('If address is already removed from white list, nothing happens', async () => {
116 const collectionId = await createCollectionExpectSuccess();114 const collectionId = await createCollectionExpectSuccess();
117 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);115 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
118 await removeFromWhiteListExpectSuccess(Alice, collectionId, normalizeAccountId(Charlie));116 await removeFromWhiteListExpectSuccess(alice, collectionId, normalizeAccountId(charlie));
119 await removeFromWhiteListExpectSuccess(Alice, collectionId, normalizeAccountId(Charlie));117 await removeFromWhiteListExpectSuccess(alice, collectionId, normalizeAccountId(charlie));
120 }); 118 });
121119
122 it('If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom. Test1', async () => {120 it('If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom. Test1', async () => {
123 const collectionId = await createCollectionExpectSuccess();121 const collectionId = await createCollectionExpectSuccess();
124 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);122 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
125 await enableWhiteListExpectSuccess(Alice, collectionId);123 await enableWhiteListExpectSuccess(alice, collectionId);
126 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);124 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
127125
128 await transferExpectFailure(126 await transferExpectFailure(
129 collectionId,127 collectionId,
130 itemId,128 itemId,
131 Alice,129 alice,
132 Charlie,130 charlie,
133 1,131 1,
134 );132 );
135 }); 133 });
136134
137 it('If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom. Test2', async () => {135 it('If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom. Test2', async () => {
138 const collectionId = await createCollectionExpectSuccess();136 const collectionId = await createCollectionExpectSuccess();
139 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);137 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
140 await enableWhiteListExpectSuccess(Alice, collectionId);138 await enableWhiteListExpectSuccess(alice, collectionId);
141 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);139 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
142 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);140 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
143 await approveExpectSuccess(collectionId, itemId, Alice, Charlie);141 await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
144 await removeFromWhiteListExpectSuccess(Alice, collectionId, normalizeAccountId(Alice));142 await removeFromWhiteListExpectSuccess(alice, collectionId, normalizeAccountId(alice));
145143
146 await transferExpectFailure(144 await transferExpectFailure(
147 collectionId,145 collectionId,
148 itemId,146 itemId,
149 Alice,147 alice,
150 Charlie,148 charlie,
151 1,149 1,
152 );150 );
153 }); 151 });
154152
155 it('If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom. Test1', async () => {153 it('If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom. Test1', async () => {
156 const collectionId = await createCollectionExpectSuccess();154 const collectionId = await createCollectionExpectSuccess();
157 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);155 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
158 await enableWhiteListExpectSuccess(Alice, collectionId);156 await enableWhiteListExpectSuccess(alice, collectionId);
159 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);157 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
160158
161 await transferExpectFailure(159 await transferExpectFailure(
162 collectionId,160 collectionId,
163 itemId,161 itemId,
164 Alice,162 alice,
165 Charlie,163 charlie,
166 1,164 1,
167 );165 );
168 }); 166 });
169167
170 it('If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom. Test2', async () => {168 it('If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom. Test2', async () => {
171 const collectionId = await createCollectionExpectSuccess();169 const collectionId = await createCollectionExpectSuccess();
172 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);170 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
173 await enableWhiteListExpectSuccess(Alice, collectionId);171 await enableWhiteListExpectSuccess(alice, collectionId);
174 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);172 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
175 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);173 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
176 await approveExpectSuccess(collectionId, itemId, Alice, Charlie);174 await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
177 await removeFromWhiteListExpectSuccess(Alice, collectionId, normalizeAccountId(Alice));175 await removeFromWhiteListExpectSuccess(alice, collectionId, normalizeAccountId(alice));
178176
179 await transferExpectFailure(177 await transferExpectFailure(
180 collectionId,178 collectionId,
181 itemId,179 itemId,
182 Alice,180 alice,
183 Charlie,181 charlie,
184 1,182 1,
185 );183 );
186 }); 184 });
187185
188 it('If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)', async () => {186 it('If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)', async () => {
189 const collectionId = await createCollectionExpectSuccess();187 const collectionId = await createCollectionExpectSuccess();
190 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);188 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
191 await enableWhiteListExpectSuccess(Alice, collectionId);189 await enableWhiteListExpectSuccess(alice, collectionId);
192190
193 await usingApi(async (api) => {191 await usingApi(async (api) => {
194 const tx = api.tx.nft.burnItem(collectionId, itemId, /*normalizeAccountId(Alice.address),*/ 11);192 const tx = api.tx.nft.burnItem(collectionId, itemId, /*normalizeAccountId(Alice.address),*/ 11);
195 const badTransaction = async function () { 193 const badTransaction = async function () {
196 await submitTransactionExpectFailAsync(Alice, tx);194 await submitTransactionExpectFailAsync(alice, tx);
197 };195 };
198 await expect(badTransaction()).to.be.rejected;196 await expect(badTransaction()).to.be.rejected;
199 });197 });
200 }); 198 });
201 199
202 it('If Public Access mode is set to WhiteList, token transfers can’t be Approved by a non-whitelisted address (see Approve method)', async () => {200 it('If Public Access mode is set to WhiteList, token transfers can’t be Approved by a non-whitelisted address (see Approve method)', async () => {
203 const collectionId = await createCollectionExpectSuccess();201 const collectionId = await createCollectionExpectSuccess();
204 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);202 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
205 await enableWhiteListExpectSuccess(Alice, collectionId);203 await enableWhiteListExpectSuccess(alice, collectionId);
206 await approveExpectFail(collectionId, itemId, Alice, Bob);204 await approveExpectFail(collectionId, itemId, alice, bob);
207 }); 205 });
208 206
209 it('If Public Access mode is set to WhiteList, tokens can be transferred to a whitelisted address with transfer.', async () => {207 it('If Public Access mode is set to WhiteList, tokens can be transferred to a whitelisted address with transfer.', async () => {
210 const collectionId = await createCollectionExpectSuccess();208 const collectionId = await createCollectionExpectSuccess();
211 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);209 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
212 await enableWhiteListExpectSuccess(Alice, collectionId);210 await enableWhiteListExpectSuccess(alice, collectionId);
213 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);211 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
214 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);212 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
215 await transferExpectSuccess(collectionId, itemId, Alice, Charlie, 1, 'NFT');213 await transferExpectSuccess(collectionId, itemId, alice, charlie, 1, 'NFT');
216 }); 214 });
217215
218 it('If Public Access mode is set to WhiteList, tokens can be transferred to a whitelisted address with transferFrom.', async () => {216 it('If Public Access mode is set to WhiteList, tokens can be transferred to a whitelisted address with transferFrom.', async () => {
219 const collectionId = await createCollectionExpectSuccess();217 const collectionId = await createCollectionExpectSuccess();
220 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);218 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
221 await enableWhiteListExpectSuccess(Alice, collectionId);219 await enableWhiteListExpectSuccess(alice, collectionId);
222 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);220 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
223 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);221 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
224 await approveExpectSuccess(collectionId, itemId, Alice, Charlie);222 await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
225 await transferFromExpectSuccess(collectionId, itemId, Alice, Alice, Charlie, 1, 'NFT');223 await transferFromExpectSuccess(collectionId, itemId, alice, alice, charlie, 1, 'NFT');
226 });224 });
227225
228 it('If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer', async () => {226 it('If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer', async () => {
229 const collectionId = await createCollectionExpectSuccess();227 const collectionId = await createCollectionExpectSuccess();
230 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);228 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
231 await enableWhiteListExpectSuccess(Alice, collectionId);229 await enableWhiteListExpectSuccess(alice, collectionId);
232 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);230 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
233 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);231 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
234 await transferExpectSuccess(collectionId, itemId, Alice, Charlie, 1, 'NFT');232 await transferExpectSuccess(collectionId, itemId, alice, charlie, 1, 'NFT');
235 });233 });
236234
237 it('If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transferFrom', async () => {235 it('If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transferFrom', async () => {
238 const collectionId = await createCollectionExpectSuccess();236 const collectionId = await createCollectionExpectSuccess();
239 const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);237 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
240 await enableWhiteListExpectSuccess(Alice, collectionId);238 await enableWhiteListExpectSuccess(alice, collectionId);
241 await addToWhiteListExpectSuccess(Alice, collectionId, Alice.address);239 await addToWhiteListExpectSuccess(alice, collectionId, alice.address);
242 await addToWhiteListExpectSuccess(Alice, collectionId, Charlie.address);240 await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
243 await approveExpectSuccess(collectionId, itemId, Alice, Charlie);241 await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
244 await transferFromExpectSuccess(collectionId, itemId, Alice, Alice, Charlie, 1, 'NFT');242 await transferFromExpectSuccess(collectionId, itemId, alice, alice, charlie, 1, 'NFT');
245 });243 });
246244
247 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner', async () => {245 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner', async () => {
248 const collectionId = await createCollectionExpectSuccess();246 const collectionId = await createCollectionExpectSuccess();
249 await enableWhiteListExpectSuccess(Alice, collectionId);247 await enableWhiteListExpectSuccess(alice, collectionId);
250 await setMintPermissionExpectSuccess(Alice, collectionId, false);248 await setMintPermissionExpectSuccess(alice, collectionId, false);
251 await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);249 await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
252 });250 });
253251
254 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin', async () => {252 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin', async () => {
255 const collectionId = await createCollectionExpectSuccess();253 const collectionId = await createCollectionExpectSuccess();
256 await enableWhiteListExpectSuccess(Alice, collectionId);254 await enableWhiteListExpectSuccess(alice, collectionId);
257 await setMintPermissionExpectSuccess(Alice, collectionId, false);255 await setMintPermissionExpectSuccess(alice, collectionId, false);
258 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);256 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
259 await createItemExpectSuccess(Bob, collectionId, 'NFT', Bob.address);257 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
260 });258 });
261259
262 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white-listed address', async () => {260 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white-listed address', async () => {
263 const collectionId = await createCollectionExpectSuccess();261 const collectionId = await createCollectionExpectSuccess();
264 await enableWhiteListExpectSuccess(Alice, collectionId);262 await enableWhiteListExpectSuccess(alice, collectionId);
265 await setMintPermissionExpectSuccess(Alice, collectionId, false);263 await setMintPermissionExpectSuccess(alice, collectionId, false);
266 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);264 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
267 await createItemExpectFailure(Bob, collectionId, 'NFT', Bob.address);265 await createItemExpectFailure(bob, collectionId, 'NFT', bob.address);
268 });266 });
269267
270 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address', async () => {268 it('If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address', async () => {
271 const collectionId = await createCollectionExpectSuccess();269 const collectionId = await createCollectionExpectSuccess();
272 await enableWhiteListExpectSuccess(Alice, collectionId);270 await enableWhiteListExpectSuccess(alice, collectionId);
273 await setMintPermissionExpectSuccess(Alice, collectionId, false);271 await setMintPermissionExpectSuccess(alice, collectionId, false);
274 await createItemExpectFailure(Bob, collectionId, 'NFT', Bob.address);272 await createItemExpectFailure(bob, collectionId, 'NFT', bob.address);
275 });273 });
276274
277 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner', async () => {275 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner', async () => {
278 const collectionId = await createCollectionExpectSuccess();276 const collectionId = await createCollectionExpectSuccess();
279 await enableWhiteListExpectSuccess(Alice, collectionId);277 await enableWhiteListExpectSuccess(alice, collectionId);
280 await setMintPermissionExpectSuccess(Alice, collectionId, true);278 await setMintPermissionExpectSuccess(alice, collectionId, true);
281 await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);279 await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
282 }); 280 });
283281
284 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin', async () => {282 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin', async () => {
285 const collectionId = await createCollectionExpectSuccess();283 const collectionId = await createCollectionExpectSuccess();
286 await enableWhiteListExpectSuccess(Alice, collectionId);284 await enableWhiteListExpectSuccess(alice, collectionId);
287 await setMintPermissionExpectSuccess(Alice, collectionId, true);285 await setMintPermissionExpectSuccess(alice, collectionId, true);
288 await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);286 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
289 await createItemExpectSuccess(Bob, collectionId, 'NFT', Bob.address);287 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
290 });288 });
291289
292 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address', async () => {290 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address', async () => {
293 const collectionId = await createCollectionExpectSuccess();291 const collectionId = await createCollectionExpectSuccess();
294 await enableWhiteListExpectSuccess(Alice, collectionId);292 await enableWhiteListExpectSuccess(alice, collectionId);
295 await setMintPermissionExpectSuccess(Alice, collectionId, true);293 await setMintPermissionExpectSuccess(alice, collectionId, true);
296 await createItemExpectFailure(Bob, collectionId, 'NFT', Bob.address);294 await createItemExpectFailure(bob, collectionId, 'NFT', bob.address);
297 });295 });
298296
299 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address', async () => {297 it('If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address', async () => {
300 const collectionId = await createCollectionExpectSuccess();298 const collectionId = await createCollectionExpectSuccess();
301 await enableWhiteListExpectSuccess(Alice, collectionId);299 await enableWhiteListExpectSuccess(alice, collectionId);
302 await setMintPermissionExpectSuccess(Alice, collectionId, true);300 await setMintPermissionExpectSuccess(alice, collectionId, true);
303 await addToWhiteListExpectSuccess(Alice, collectionId, Bob.address);301 await addToWhiteListExpectSuccess(alice, collectionId, bob.address);
304 await createItemExpectSuccess(Bob, collectionId, 'NFT', Bob.address);302 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
305 });303 });
306});304});
307
308305
modifiedtests/tsconfig.jsondiffbeforeafterboth
13 "sourceMap": true,13 "sourceMap": true,
14 "outDir": "dist",14 "outDir": "dist",
15 "rootDir": "src",15 "rootDir": "src",
16 "strict": true16 "strict": true,
17 "paths": {
18 "@polkadot/api/augment": [
19 "./src/interfaces/augment-api.ts"
20 ],
21 "@polkadot/types/augment": [
22 "./src/interfaces/augment-types.ts"
23 ]
24 }
17 },25 },
18 "include": [26 "include": [
19 "src/**/*"27 "src/**/*"
20 ],28 ],
21 "lib": ["es2017"]29 "lib": [
30 "es2017"
31 ],
22}32}
2333
modifiedtests/yarn.lockdiffbeforeafterboth
1899 dependencies:1899 dependencies:
1900 "@octokit/openapi-types" "^7.3.2"1900 "@octokit/openapi-types" "^7.3.2"
19011901
1902"@polkadot/api-contract@6.5.1":1902"@polkadot/api-contract@6.6.2-5":
1903 version "6.5.1"1903 version "6.6.2-5"
1904 resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-6.5.1.tgz#bc61e0def693ab866550c304384d909fec6cf64d"1904 resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-6.6.2-5.tgz#b0e40242c320015f1c55999e86a08826e2d946c0"
1905 integrity sha512-cV86H2oGKs9dbO3wf911ftRrGvbzq9tkJzTsocx12WhAKORVT11zIKPThaVmzzrdqSqN7q7tth8p4HBDXZp9qw==1905 integrity sha512-STchCvoGHq4BVnqYuYUDZnJ6NuHfuwDPH4oh2O8DSVRWSTLPWBcWLBFUzDPJe6wfWUf7ih0CW6p7msCq7zqltg==
1906 dependencies:1906 dependencies:
1907 "@babel/runtime" "^7.15.4"1907 "@babel/runtime" "^7.15.4"
1908 "@polkadot/api" "6.5.1"1908 "@polkadot/api" "6.6.2-5"
1909 "@polkadot/types" "6.5.1"1909 "@polkadot/types" "6.6.2-5"
1910 "@polkadot/util" "^7.6.1"1910 "@polkadot/util" "^7.7.1"
1911 rxjs "^7.4.0"1911 rxjs "^7.4.0"
19121912
1913"@polkadot/api-derive@6.5.1":1913"@polkadot/api-derive@6.6.2-5":
1914 version "6.5.1"1914 version "6.6.2-5"
1915 resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-6.5.1.tgz#c2e7d632c3c156355218650e6414504d9a154b17"1915 resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-6.6.2-5.tgz#52f8d7f071a0c8d8c81bf41e8e1666485af8cd56"
1916 integrity sha512-OwiCYcak3fqiZtE28FbqEd+ZTck9LmsEk01VPQigwSgNu/qbiuKGZ+MurK6yWy8sHbFdcDLPR07/iD5/fhQZRw==1916 integrity sha512-TZmGJuSdfbvSaQ4bE4cCx+pjINnB8ZrSCpV4RZXfhUZmqQ1KQBXLDbXsSdRK+PldFnprged14T3yFD7pgptM6A==
1917 dependencies:1917 dependencies:
1918 "@babel/runtime" "^7.15.4"1918 "@babel/runtime" "^7.15.4"
1919 "@polkadot/api" "6.5.1"1919 "@polkadot/api" "6.6.2-5"
1920 "@polkadot/rpc-core" "6.5.1"1920 "@polkadot/rpc-core" "6.6.2-5"
1921 "@polkadot/types" "6.5.1"1921 "@polkadot/types" "6.6.2-5"
1922 "@polkadot/util" "^7.6.1"1922 "@polkadot/util" "^7.7.1"
1923 "@polkadot/util-crypto" "^7.6.1"1923 "@polkadot/util-crypto" "^7.7.1"
1924 rxjs "^7.4.0"1924 rxjs "^7.4.0"
19251925
1926"@polkadot/api-derive@6.5.2-3":1926"@polkadot/api@6.6.2-5":
1927 version "6.5.2-3"1927 version "6.6.2-5"
1928 resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-6.5.2-3.tgz#c3c85a4326a105398083858d2eca44d14685d8b3"1928 resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-6.6.2-5.tgz#d9c2ce51886407d1ee140ee4dbbc7da934ab0fc0"
1929 integrity sha512-VSBKcSrZU/nvl2yy3w1hWkTayoYGXGyySUkYrc6H/xA6NDeU9Pj3p3PMNnI1zeTL9SIuoQs1g2h8k8Ynaxq5fQ==1929 integrity sha512-XS2Jetbo6zALL8pTgkRSAnpcOI83p92nGqCPf3gWHzL+MCuHT2kudLICbE1tKbJOHkiMyn87uH1v8OOV7mPPGw==
1930 dependencies:1930 dependencies:
1931 "@babel/runtime" "^7.15.4"1931 "@babel/runtime" "^7.15.4"
1932 "@polkadot/api" "6.5.2-3"1932 "@polkadot/api-derive" "6.6.2-5"
1933 "@polkadot/rpc-core" "6.5.2-3"
1934 "@polkadot/types" "6.5.2-3"
1935 "@polkadot/util" "^7.6.1"1933 "@polkadot/keyring" "^7.7.1"
1936 "@polkadot/util-crypto" "^7.6.1"1934 "@polkadot/rpc-core" "6.6.2-5"
1937 rxjs "^7.4.0"
1938
1939"@polkadot/api@6.5.1":
1940 version "6.5.1"
1941 resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-6.5.1.tgz#c6c46ed8274114d56652574bfc64a01610401490"
1942 integrity sha512-hxnXb4qFlRbqBKnWgvNtRAukDRthAcLjhh1IY9oQ6WRJipdb2wMtNz6MY06gLI0MVGv9u2fOC6Rhd2JGo4CKZg==1935 "@polkadot/rpc-provider" "6.6.2-5"
1943 dependencies:
1944 "@babel/runtime" "^7.15.4"
1945 "@polkadot/api-derive" "6.5.1"
1946 "@polkadot/keyring" "^7.6.1"
1947 "@polkadot/rpc-core" "6.5.1"
1948 "@polkadot/rpc-provider" "6.5.1"1936 "@polkadot/types" "6.6.2-5"
1949 "@polkadot/types" "6.5.1"
1950 "@polkadot/types-known" "6.5.1"1937 "@polkadot/types-known" "6.6.2-5"
1951 "@polkadot/util" "^7.6.1"1938 "@polkadot/util" "^7.7.1"
1952 "@polkadot/util-crypto" "^7.6.1"1939 "@polkadot/util-crypto" "^7.7.1"
1953 eventemitter3 "^4.0.7"1940 eventemitter3 "^4.0.7"
1954 rxjs "^7.4.0"1941 rxjs "^7.4.0"
19551942
1956"@polkadot/api@6.5.2-3":1943"@polkadot/dev@0.63.18":
1957 version "6.5.2-3"1944 version "0.63.18"
1958 resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-6.5.2-3.tgz#715f2746faf5edb84ddebeeaf9b37c15226a50f4"1945 resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.63.18.tgz#2bd5f0a2019a67aa3acfd71bc4a9d81486887a7b"
1959 integrity sha512-Ugrd3MK265cwE88cu6W9k/4bIutu5O5YFpw6t7Rf0OWOgibZsGnd1/CTi1e/F85Ro7FxyT7lBFQFM9XA1hUnDA==1946 integrity sha512-oaSySgI8eNctXzA2n3hEUgILw9sP4a9mAKdbtZAMDP2Jf6Dw92rsKwEfKiIXU6MRL0kukafMH3oQPd9nJIL+zg==
1960 dependencies:1947 dependencies:
1961 "@babel/runtime" "^7.15.4"
1962 "@polkadot/api-derive" "6.5.2-3"
1963 "@polkadot/keyring" "^7.6.1"
1964 "@polkadot/rpc-core" "6.5.2-3"
1965 "@polkadot/rpc-provider" "6.5.2-3"
1966 "@polkadot/types" "6.5.2-3"
1967 "@polkadot/types-known" "6.5.2-3"
1968 "@polkadot/util" "^7.6.1"
1969 "@polkadot/util-crypto" "^7.6.1"
1970 eventemitter3 "^4.0.7"
1971 rxjs "^7.4.0"
1972
1973"@polkadot/dev@0.63.9":
1974 version "0.63.9"
1975 resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.63.9.tgz#911e92d2b8c60d35dbb897fb917f065f1aa750ac"
1976 integrity sha512-lH9A7NTJNHJN+J4TBPcqhGkhEAsNAjqeVgUH980MwcovMo7mehFLadSt9Qi/+qFeZxEsp67+daeI4sqdo8csmg==
1977 dependencies:
1978 "@babel/cli" "^7.15.7"1948 "@babel/cli" "^7.15.7"
1979 "@babel/core" "^7.15.8"1949 "@babel/core" "^7.15.8"
1980 "@babel/plugin-proposal-class-properties" "^7.14.5"1950 "@babel/plugin-proposal-class-properties" "^7.14.5"
1999 "@rollup/plugin-inject" "^4.0.3"1969 "@rollup/plugin-inject" "^4.0.3"
2000 "@rollup/plugin-json" "^4.1.0"1970 "@rollup/plugin-json" "^4.1.0"
2001 "@rollup/plugin-node-resolve" "^13.0.6"1971 "@rollup/plugin-node-resolve" "^13.0.6"
2002 "@rushstack/eslint-patch" "^1.0.8"1972 "@rushstack/eslint-patch" "^1.0.9"
2003 "@typescript-eslint/eslint-plugin" "5.1.0"1973 "@typescript-eslint/eslint-plugin" "5.2.0"
2004 "@typescript-eslint/parser" "5.1.0"1974 "@typescript-eslint/parser" "5.2.0"
2005 "@vue/component-compiler-utils" "^3.2.2"1975 "@vue/component-compiler-utils" "^3.3.0"
2006 babel-jest "^27.3.1"1976 babel-jest "^27.3.1"
2007 babel-plugin-module-extension-resolver "^1.0.0-rc.2"1977 babel-plugin-module-extension-resolver "^1.0.0-rc.2"
2008 babel-plugin-module-resolver "^4.1.0"1978 babel-plugin-module-resolver "^4.1.0"
2009 babel-plugin-styled-components "^1.13.3"1979 babel-plugin-styled-components "^1.13.3"
2010 browserslist "^4.17.4"1980 browserslist "^4.17.5"
2011 chalk "^4.1.2"1981 chalk "^4.1.2"
2012 coveralls "^3.1.1"1982 coveralls "^3.1.1"
2013 eslint "^8.1.0"1983 eslint "^8.1.0"
2021 eslint-plugin-react "^7.26.1"1991 eslint-plugin-react "^7.26.1"
2022 eslint-plugin-react-hooks "^4.2.1-alpha-930c9e7ee-20211015"1992 eslint-plugin-react-hooks "^4.2.1-alpha-930c9e7ee-20211015"
2023 eslint-plugin-simple-import-sort "^7.0.0"1993 eslint-plugin-simple-import-sort "^7.0.0"
2024 eslint-plugin-sort-destructure-keys "^1.3.5"1994 eslint-plugin-sort-destructure-keys "^1.4.0"
2025 fs-extra "^10.0.0"1995 fs-extra "^10.0.0"
2026 gh-pages "^3.2.3"1996 gh-pages "^3.2.3"
2027 gh-release "^6.0.1"1997 gh-release "^6.0.1"
2037 mkdirp "^1.0.4"2007 mkdirp "^1.0.4"
2038 prettier "^2.4.1"2008 prettier "^2.4.1"
2039 rimraf "^3.0.2"2009 rimraf "^3.0.2"
2040 rollup "^2.58.0"2010 rollup "^2.58.3"
2041 typescript "^4.4.4"2011 typescript "^4.4.4"
2042 yargs "^17.2.1"2012 yargs "^17.2.1"
20432013
2044"@polkadot/keyring@^7.6.1":2014"@polkadot/keyring@^7.7.1":
2045 version "7.6.1"2015 version "7.7.1"
2046 resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-7.6.1.tgz#a138e417cbbf85b3f0f66af66f5cd40735ba24a1"2016 resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-7.7.1.tgz#0ab6a8d104669ead3e269cf2c185346b24dfbd36"
2047 integrity sha512-lpbTHAQqae++cvaNfuCjdz2xbNrk0ZSGCM8w08Br6NIz8NyrwR/qm1PfV75leoLq/Qx58+aj8v2qANEBOVz4vQ==2017 integrity sha512-MzdwUeR5BjqEqSnW1SVg1mMaUPkirGcLd60vsp187qf/y9IaI+ZinkeP50d/GxldRobNL/bOdiOuV3bSulUvSQ==
2048 dependencies:2018 dependencies:
2049 "@babel/runtime" "^7.15.4"2019 "@babel/runtime" "^7.15.4"
2050 "@polkadot/util" "7.6.1"2020 "@polkadot/util" "7.7.1"
2051 "@polkadot/util-crypto" "7.6.1"2021 "@polkadot/util-crypto" "7.7.1"
20522022
2053"@polkadot/networks@7.6.1", "@polkadot/networks@^7.6.1":2023"@polkadot/networks@7.7.1", "@polkadot/networks@^7.7.1":
2054 version "7.6.1"2024 version "7.7.1"
2055 resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-7.6.1.tgz#d7ca346a3c15b29c9286ccbc67b1438bf9c8130e"2025 resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-7.7.1.tgz#de9674a355bd4f68d650e3dd580d717d83ea4161"
2056 integrity sha512-76RdEVy+G14P13oxSe3+VDwFdVYRNVAy7xi9ESJBRZFnQC/TIL2rOeg7Gq5+HP/mkgzG4gL5X30VdE+aKzokpA==2026 integrity sha512-ghUA9jd+12lfbKclPIxRQBmvfd1+BoECr5C8t+2rfM5plE+1f1Ucdrpz9wQ362+WNlnP4q1u9yB1zQlFM+K6yQ==
2057 dependencies:2027 dependencies:
2058 "@babel/runtime" "^7.15.4"2028 "@babel/runtime" "^7.15.4"
20592029
2060"@polkadot/rpc-core@6.5.1":2030"@polkadot/rpc-core@6.6.2-5":
2061 version "6.5.1"2031 version "6.6.2-5"
2062 resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-6.5.1.tgz#0a2ecb78b38c63f0831c7fb5363d9cc1fb72ec0e"2032 resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-6.6.2-5.tgz#5b547406ba5b2ad117394cd624f18aab0f0d413a"
2063 integrity sha512-teWI8iumsAMHF1vgMzbRVqpSTfVcNIG7bRwSlGoy4V4ZT8dS5LjOYCR7Eqr19wRuef1DjBY87oiN7e8M2x8jCA==2033 integrity sha512-8+Vw/oF2cal+G27g/T2aFgdt2GJFcpvQPH6fv/9WJc5gcTWciwb1mQsMDBaB/VA1DbjZXZlCdMZBigayg8/+jg==
2064 dependencies:2034 dependencies:
2065 "@babel/runtime" "^7.15.4"2035 "@babel/runtime" "^7.15.4"
2066 "@polkadot/rpc-provider" "6.5.1"2036 "@polkadot/rpc-provider" "6.6.2-5"
2067 "@polkadot/types" "6.5.1"2037 "@polkadot/types" "6.6.2-5"
2068 "@polkadot/util" "^7.6.1"2038 "@polkadot/util" "^7.7.1"
2069 rxjs "^7.4.0"2039 rxjs "^7.4.0"
20702040
2071"@polkadot/rpc-core@6.5.2-3":2041"@polkadot/rpc-provider@6.6.2-5":
2072 version "6.5.2-3"2042 version "6.6.2-5"
2073 resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-6.5.2-3.tgz#72a15dd6288ed9232b12be1e6f8b848268d8b3bd"2043 resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-6.6.2-5.tgz#46695eb11a0ce1ef8617ad354af22a027bae115a"
2074 integrity sha512-1Lkp4/k/MYbEqLj5adayw3jAMlrmwv0hGN5rfggyIQJVLXDpDf78frOIVLNGPsDQaB1Euizfxmm/IeShFAyvxg==2044 integrity sha512-HQ6zWqWtxMZ0k95ABGtrmFdV6LScQ3332Ic41qjOzYE8UMvKrK8vZy0/1wWx8h0tfIu6Evtw6zz/0q5KDJWjGw==
2075 dependencies:2045 dependencies:
2076 "@babel/runtime" "^7.15.4"2046 "@babel/runtime" "^7.15.4"
2077 "@polkadot/rpc-provider" "6.5.2-3"2047 "@polkadot/types" "6.6.2-5"
2078 "@polkadot/types" "6.5.2-3"
2079 "@polkadot/util" "^7.6.1"2048 "@polkadot/util" "^7.7.1"
2080 rxjs "^7.4.0"
2081
2082"@polkadot/rpc-provider@6.5.1":
2083 version "6.5.1"2049 "@polkadot/util-crypto" "^7.7.1"
2084 resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-6.5.1.tgz#bde30ac49b62edb592b89e19aeea36d23e14b25c"
2085 integrity sha512-09GId3vknImuEaRH0WDlrP8rsTC/QSIFM7sV55QzjfnLKRct1Fulez0hfFP25orXpjraWqHNZvY1yxniUxK6nA==
2086 dependencies:
2087 "@babel/runtime" "^7.15.4"
2088 "@polkadot/types" "6.5.1"
2089 "@polkadot/util" "^7.6.1"
2090 "@polkadot/util-crypto" "^7.6.1"
2091 "@polkadot/x-fetch" "^7.6.1"2050 "@polkadot/x-fetch" "^7.7.1"
2092 "@polkadot/x-global" "^7.6.1"2051 "@polkadot/x-global" "^7.7.1"
2093 "@polkadot/x-ws" "^7.6.1"2052 "@polkadot/x-ws" "^7.7.1"
2094 eventemitter3 "^4.0.7"2053 eventemitter3 "^4.0.7"
20952054
2096"@polkadot/rpc-provider@6.5.2-3":
2097 version "6.5.2-3"
2098 resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-6.5.2-3.tgz#3f9c87123adddf957c0789e23963a82817d96537"
2099 integrity sha512-Rw4oESRwJRIRlhjwhgrL8idbYelIFmSkdk3eV1QjLQZdkHUiZkujtltUnQgT5iRi1XvGN+0ybcgFDDaNz1Ncmg==
2100 dependencies:
2101 "@babel/runtime" "^7.15.4"
2102 "@polkadot/types" "6.5.2-3"
2103 "@polkadot/util" "^7.6.1"
2104 "@polkadot/util-crypto" "^7.6.1"
2105 "@polkadot/x-fetch" "^7.6.1"
2106 "@polkadot/x-global" "^7.6.1"
2107 "@polkadot/x-ws" "^7.6.1"
2108 eventemitter3 "^4.0.7"
2109
2110"@polkadot/ts@0.4.12":2055"@polkadot/ts@0.4.12":
2111 version "0.4.12"2056 version "0.4.12"
2112 resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.4.12.tgz#4fa15415fbf30b1719610d8814fade5c26ea3244"2057 resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.4.12.tgz#4fa15415fbf30b1719610d8814fade5c26ea3244"
2113 integrity sha512-VXfCkEctJEx4gquXpfaKr7qvg4owGp+s9guy0GyodKQUz0N82VzUKdpllC+dmcTzGRzaU8X3EZOd9cTZrToAyQ==2058 integrity sha512-VXfCkEctJEx4gquXpfaKr7qvg4owGp+s9guy0GyodKQUz0N82VzUKdpllC+dmcTzGRzaU8X3EZOd9cTZrToAyQ==
2114 dependencies:2059 dependencies:
2115 "@types/chrome" "^0.0.159"2060 "@types/chrome" "^0.0.159"
21162061
2117"@polkadot/typegen@6.5.2-3":2062"@polkadot/typegen@6.6.2-5":
2118 version "6.5.2-3"2063 version "6.6.2-5"
2119 resolved "https://registry.yarnpkg.com/@polkadot/typegen/-/typegen-6.5.2-3.tgz#f264ed18dbeb546be413aa905ac94e2043628159"2064 resolved "https://registry.yarnpkg.com/@polkadot/typegen/-/typegen-6.6.2-5.tgz#2f3df4f42a3acfc28a4e40e3af8e28c72d1fa5aa"
2120 integrity sha512-jB3yC7QX8wbABPwtrSIeCPcmFqE/pNlg6MBShrZou4OVCt9uuyE4ju2QGLxxBHbeaXriltV4jrPpZUklKvNS+w==2065 integrity sha512-1U29AIPNTjGgJkOn7aKn8/OmiOPcWOIQQn6+DqGxbDOjHclgQffSeE5og82b26j5hKqNE0ks6mVwmZLLoh5pAw==
2121 dependencies:2066 dependencies:
2122 "@babel/core" "^7.15.8"2067 "@babel/core" "^7.15.8"
2123 "@babel/register" "^7.15.3"2068 "@babel/register" "^7.15.3"
2124 "@babel/runtime" "^7.15.4"2069 "@babel/runtime" "^7.15.4"
2125 "@polkadot/api" "6.5.2-3"2070 "@polkadot/api" "6.6.2-5"
2126 "@polkadot/rpc-provider" "6.5.2-3"2071 "@polkadot/rpc-provider" "6.6.2-5"
2127 "@polkadot/types" "6.5.2-3"2072 "@polkadot/types" "6.6.2-5"
2128 "@polkadot/types-support" "6.5.2-3"2073 "@polkadot/types-support" "6.6.2-5"
2129 "@polkadot/util" "^7.6.1"2074 "@polkadot/util" "^7.7.1"
2130 handlebars "^4.7.7"2075 handlebars "^4.7.7"
2131 websocket "^1.0.34"2076 websocket "^1.0.34"
2132 yargs "^17.2.1"2077 yargs "^17.2.1"
21332078
2134"@polkadot/types-known@6.5.1":2079"@polkadot/types-known@6.6.2-5":
2135 version "6.5.1"2080 version "6.6.2-5"
2136 resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-6.5.1.tgz#753af9a6c4188accb761639505e3e5cd7e5bc176"2081 resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-6.6.2-5.tgz#b0d479742b3887063efa82e77de8f13086782ef8"
2137 integrity sha512-eIgk836zlA5KnhK6UotXYr/I9O12xxhNcKXTcA+8NY6ek2xQWlT9VGuMk4wTF4qU1sV/fhOFIDeoNrT7AgSagg==2082 integrity sha512-IsdWo3oR1l+DRXZoip5U/5VJfHJSVJoFMePKL+a51vTXM0Wcx7p8aYZtVlThenyItUUXiPvYY5NCPBnwX/ZsoQ==
2138 dependencies:2083 dependencies:
2139 "@babel/runtime" "^7.15.4"2084 "@babel/runtime" "^7.15.4"
2140 "@polkadot/networks" "^7.6.1"2085 "@polkadot/networks" "^7.7.1"
2141 "@polkadot/types" "6.5.1"2086 "@polkadot/types" "6.6.2-5"
2142 "@polkadot/util" "^7.6.1"2087 "@polkadot/util" "^7.7.1"
21432088
2144"@polkadot/types-known@6.5.2-3":2089"@polkadot/types-support@6.6.2-5":
2145 version "6.5.2-3"2090 version "6.6.2-5"
2146 resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-6.5.2-3.tgz#ebfa59495f576c0895accda20ac9c019f2afa91d"2091 resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-6.6.2-5.tgz#13e414dee7e48e2bf5f1c837b2864a44b1c735c6"
2147 integrity sha512-/ORaKrDnJdRgQy247G2Bst8WUWnKGf5snSZMFHAkVTfqQK4w017gsKR+NusgPiCqziHgRptdUsVgS4tFdh5lgQ==2092 integrity sha512-alq2VXVrLKogf3e1ebtxw37s9CwLkC3xdXJ0RUx0PbK4oFtVFM9U0s3Ogo2rXwVVXqRQnMIwbzEaFHI2LvLKLQ==
2148 dependencies:2093 dependencies:
2149 "@babel/runtime" "^7.15.4"2094 "@babel/runtime" "^7.15.4"
2150 "@polkadot/networks" "^7.6.1"2095 "@polkadot/util" "^7.7.1"
2151 "@polkadot/types" "6.5.2-3"
2152 "@polkadot/util" "^7.6.1"
21532096
2154"@polkadot/types-support@6.5.2-3":2097"@polkadot/types@6.6.2-5":
2155 version "6.5.2-3"2098 version "6.6.2-5"
2156 resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-6.5.2-3.tgz#3d5d6fa864e825dd4bf3d00ca4de7af6e6167b09"2099 resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-6.6.2-5.tgz#465a574c943484e87681c766f41698b5aed3b203"
2157 integrity sha512-FL6n7xqts5f70gHSiYflszUY0wKJt0LGQ+BmkGJ9lxda2R5Ynx6hRP/jIse6XYhCe8xDZwz/wzf2f+k7m7ooTg==2100 integrity sha512-3Tv7RhKKtnqy77Quyt2JDdXbC7Hlt6GmBH9eQv47geR8CQMTwfAx7e4sVFocQQCANhhYn/VRl6aImkX+JYBcNA==
2158 dependencies:2101 dependencies:
2159 "@babel/runtime" "^7.15.4"2102 "@babel/runtime" "^7.15.4"
2160 "@polkadot/util" "^7.6.1"2103 "@polkadot/util" "^7.7.1"
2161
2162"@polkadot/types@6.5.1":
2163 version "6.5.1"
2164 resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-6.5.1.tgz#6d348b7c37ec351506e952ee16f696ecf4a56725"
2165 integrity sha512-EiW/5vbR6sP20Yq7wto7Ozepie6YzGjPCH4IPLkGrPsDaMegbwNRvEV+5AbCYvEPKF6LJoaRPUcF/WQxncVonA==
2166 dependencies:
2167 "@babel/runtime" "^7.15.4"
2168 "@polkadot/util" "^7.6.1"
2169 "@polkadot/util-crypto" "^7.6.1"2104 "@polkadot/util-crypto" "^7.7.1"
2170 rxjs "^7.4.0"2105 rxjs "^7.4.0"
21712106
2172"@polkadot/types@6.5.2-3":2107"@polkadot/util-crypto@7.7.1", "@polkadot/util-crypto@^7.7.1":
2173 version "6.5.2-3"2108 version "7.7.1"
2174 resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-6.5.2-3.tgz#347e6044041d61cb411e03e2afefbbebd04d7115"2109 resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-7.7.1.tgz#6c3b84558d4e971cc0a7190f99e34ce801eb498d"
2175 integrity sha512-N+OsC8fAEY8YGWQxV0GHrHIlMncIHbumxJVbiB4QdW8fL0kUDlfl0414+6lVMCLlgu+XkoyJXkEc2u+KYKseOA==2110 integrity sha512-K269URC/ofbYM1vFSIVLbuRi4Z+9bMdyJQ1k+59+jx0VwYu50l9vzNhFO8WMGoBZ6eDzqQkeWj7usCTKlU9xUw==
2176 dependencies:2111 dependencies:
2177 "@babel/runtime" "^7.15.4"2112 "@babel/runtime" "^7.15.4"
2178 "@polkadot/util" "^7.6.1"2113 "@polkadot/networks" "7.7.1"
2179 "@polkadot/util-crypto" "^7.6.1"
2180 rxjs "^7.4.0"2114 "@polkadot/util" "7.7.1"
2181
2182"@polkadot/util-crypto@7.6.1", "@polkadot/util-crypto@^7.6.1":
2183 version "7.6.1"
2184 resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-7.6.1.tgz#3e40270e9dce7885d92d0992aef9761feb57f2e2"
2185 integrity sha512-5lLEfexkYOc73jitwC4K/Ll3JNA8Hdo2aU3GSOkDah8bBpm02djD7ypwfmuWRJw0UDyTgY67g0SXn4frPcQiag==
2186 dependencies:
2187 "@babel/runtime" "^7.15.4"
2188 "@polkadot/networks" "7.6.1"
2189 "@polkadot/util" "7.6.1"
2190 "@polkadot/wasm-crypto" "^4.2.1"2115 "@polkadot/wasm-crypto" "^4.2.1"
2191 "@polkadot/x-randomvalues" "7.6.1"2116 "@polkadot/x-randomvalues" "7.7.1"
2192 base-x "^3.0.9"2117 base-x "^3.0.9"
2193 base64-js "^1.5.1"2118 base64-js "^1.5.1"
2194 blakejs "^1.1.1"2119 blakejs "^1.1.1"
2202 tweetnacl "^1.0.3"2127 tweetnacl "^1.0.3"
2203 xxhashjs "^0.2.2"2128 xxhashjs "^0.2.2"
22042129
2205"@polkadot/util@7.6.1", "@polkadot/util@^7.6.1":2130"@polkadot/util@7.7.1", "@polkadot/util@^7.7.1":
2206 version "7.6.1"2131 version "7.7.1"
2207 resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-7.6.1.tgz#e6988124728fdf053929022827216241dd50a6fa"2132 resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-7.7.1.tgz#b9c74f8c242669ff8ce26a3101630231914de7c7"
2208 integrity sha512-96UgzMOxwwsndGHN4aoyPYVRXpHcVpYb4zngFH2O9ma0YxrG2HhhqqoJ5pS0OUlhvcQkVz6T6t+heGFnTkvQxw==2133 integrity sha512-REw11iHZKUm7GeC7Ktx1HguT9y76mbmiVtZJyNXpUTDKmfm6z+SMqs3pOCL/rvzqm+6M3ag6ffRrlzTTgh0HAg==
2209 dependencies:2134 dependencies:
2210 "@babel/runtime" "^7.15.4"2135 "@babel/runtime" "^7.15.4"
2211 "@polkadot/x-textdecoder" "7.6.1"2136 "@polkadot/x-textdecoder" "7.7.1"
2212 "@polkadot/x-textencoder" "7.6.1"2137 "@polkadot/x-textencoder" "7.7.1"
2213 "@types/bn.js" "^4.11.6"2138 "@types/bn.js" "^4.11.6"
2214 bn.js "^4.12.0"2139 bn.js "^4.12.0"
2215 camelcase "^6.2.0"2140 camelcase "^6.2.0"
2238 "@polkadot/wasm-crypto-asmjs" "^4.2.1"2163 "@polkadot/wasm-crypto-asmjs" "^4.2.1"
2239 "@polkadot/wasm-crypto-wasm" "^4.2.1"2164 "@polkadot/wasm-crypto-wasm" "^4.2.1"
22402165
2241"@polkadot/x-fetch@^7.6.1":2166"@polkadot/x-fetch@^7.7.1":
2242 version "7.6.1"2167 version "7.7.1"
2243 resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-7.6.1.tgz#fda1a89bbb584217f96c2d3c3a3ce0f10a454436"2168 resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-7.7.1.tgz#88b99936b89a44c3a3a980666b4ab4db6f90481b"
2244 integrity sha512-CdjCg7BGhKfKNntUiK9vFOoum44o86TInPpqNumLGWAZmqI+kU0DCUDtqcw7uFOdZL1j/3GHdXigJ6LL1TnNcg==2169 integrity sha512-0ocN1CSwDHXRzz2yUAaoDH0VrOg3Kmx0nAW05wZdoMfvU9vEiJHhTT/c27pss3dsbEs334PWL5QbcTzYiQvDVQ==
2245 dependencies:2170 dependencies:
2246 "@babel/runtime" "^7.15.4"2171 "@babel/runtime" "^7.15.4"
2247 "@polkadot/x-global" "7.6.1"2172 "@polkadot/x-global" "7.7.1"
2248 "@types/node-fetch" "^2.5.12"2173 "@types/node-fetch" "^2.5.12"
2249 node-fetch "^2.6.5"2174 node-fetch "^2.6.5"
22502175
2251"@polkadot/x-global@7.6.1", "@polkadot/x-global@^7.6.1":2176"@polkadot/x-global@7.7.1", "@polkadot/x-global@^7.7.1":
2252 version "7.6.1"2177 version "7.7.1"
2253 resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-7.6.1.tgz#f43a61d40bfaf2f43f9a4ef39e01a24546768394"2178 resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-7.7.1.tgz#ab390aa07807d62a7ec0fa2fd6e7c4837524c227"
2254 integrity sha512-jKPNFHiC0yIc6TfqZtopaqsW3pDun1uh9lp0kcDkfOYozwwN1NVXWLClDBa2C5UiKU/jxA3biYiNZUyZpbV13g==2179 integrity sha512-S7MYqEtcfMgWA64qR09Z8O3zbaRyyW1y2qtvn04dexPesuEPOw2W5+WBHss8UAI/aVxjlG+d2D3OlYUr+IOO9Q==
2255 dependencies:2180 dependencies:
2256 "@babel/runtime" "^7.15.4"2181 "@babel/runtime" "^7.15.4"
22572182
2258"@polkadot/x-randomvalues@7.6.1":2183"@polkadot/x-randomvalues@7.7.1":
2259 version "7.6.1"2184 version "7.7.1"
2260 resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-7.6.1.tgz#0cd143cf976e36f5c9fcf53ba41fd5fffca95c44"2185 resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-7.7.1.tgz#37edb6920bac4f6c6c7620f02ef9dd5b43405a5b"
2261 integrity sha512-hfSMBeMZTrnuejv/oXp3tMZARTOGyQZ3G0GW44dV2fR2L1+tlLj9VuXgVGgupNBq7AC6eSfE3XhJwCGyH5FhmQ==2186 integrity sha512-dFhxei2TP3cWepfITDSq6eaBbdsP8TPBQagincqJynt5EaU0pzQ5psMBMJ/rAYy194oEpg0ED16XK/iFdZ42rA==
2262 dependencies:2187 dependencies:
2263 "@babel/runtime" "^7.15.4"2188 "@babel/runtime" "^7.15.4"
2264 "@polkadot/x-global" "7.6.1"2189 "@polkadot/x-global" "7.7.1"
22652190
2266"@polkadot/x-textdecoder@7.6.1":2191"@polkadot/x-textdecoder@7.7.1":
2267 version "7.6.1"2192 version "7.7.1"
2268 resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-7.6.1.tgz#7e80b512f1ddfd01f243dbbe8afc9dab7d0c6c85"2193 resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-7.7.1.tgz#bfcf8f8a7ce620ca72a649dd0a322a4476a51a28"
2269 integrity sha512-sJtQMMw+jO3CwpOf0t1hrVl3xMw1BOLs/Xjd0v/yhiTAJ1rr6dqvhcnOHkU3a7udqo7G9dXDrnGi1q3efifXPw==2194 integrity sha512-2+kYLVxjdtbuxcIDMdEiBK+GvCs/M8QdKVmTGLTb47PphSeiMKLu8qjy1ygBJeaFeQOZxIj1f8IJ5ICI9TlVcA==
2270 dependencies:2195 dependencies:
2271 "@babel/runtime" "^7.15.4"2196 "@babel/runtime" "^7.15.4"
2272 "@polkadot/x-global" "7.6.1"2197 "@polkadot/x-global" "7.7.1"
22732198
2274"@polkadot/x-textencoder@7.6.1":2199"@polkadot/x-textencoder@7.7.1":
2275 version "7.6.1"2200 version "7.7.1"
2276 resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-7.6.1.tgz#2a2fb4baa13889fbc53b86ce9003de748f0df2aa"2201 resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-7.7.1.tgz#7dc5b0165e3b6ad6882904169ad3362487ada92b"
2277 integrity sha512-iqOGwXJIzc8rWYLPTYcO09LwA2q4fqwJhLsLCd+p13Z0yDSUvwgq785/2WEQfhSFbMd8HM6udedqrQTpnpIujg==2202 integrity sha512-pRTG7F6EYilkbkyxfWOV1LXCVohcVnFPVfPvGydHsDJ3kGZ4n+L9PuJ+t3WKwd6tirEDUIBGe2eNEl/arcWzTw==
2278 dependencies:2203 dependencies:
2279 "@babel/runtime" "^7.15.4"2204 "@babel/runtime" "^7.15.4"
2280 "@polkadot/x-global" "7.6.1"2205 "@polkadot/x-global" "7.7.1"
22812206
2282"@polkadot/x-ws@^7.6.1":2207"@polkadot/x-ws@^7.7.1":
2283 version "7.6.1"2208 version "7.7.1"
2284 resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-7.6.1.tgz#60c86cfb43935b38a6512f3e7bab362ffe6bec1f"2209 resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-7.7.1.tgz#dc06d7a3cc6802de9c8449e437f5c10687cf8683"
2285 integrity sha512-nP8vHlL17SIuVinphuVbj2o3mfRWUTJqlhAYlA5RjO/sZ9TwYMvGTvL/1bOAfWdp/l451WLEWJtzSipzrVGBsg==2210 integrity sha512-P1ZBuPvTX+H6pBiIkPjgygIw4GsekicoAE2ew5R1s/WE4uS0YjiO+QTwkaaB1fNqk2fBRSI+eDHOGiGmr5MM2Q==
2286 dependencies:2211 dependencies:
2287 "@babel/runtime" "^7.15.4"2212 "@babel/runtime" "^7.15.4"
2288 "@polkadot/x-global" "7.6.1"2213 "@polkadot/x-global" "7.7.1"
2289 "@types/websocket" "^1.0.4"2214 "@types/websocket" "^1.0.4"
2290 websocket "^1.0.34"2215 websocket "^1.0.34"
22912216
2346 estree-walker "^1.0.1"2271 estree-walker "^1.0.1"
2347 picomatch "^2.2.2"2272 picomatch "^2.2.2"
23482273
2349"@rushstack/eslint-patch@^1.0.8":2274"@rushstack/eslint-patch@^1.0.9":
2350 version "1.0.8"2275 version "1.0.9"
2351 resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.8.tgz#be3e914e84eacf16dbebd311c0d0b44aa1174c64"2276 resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.9.tgz#1168db664faab4c3bb82c76124b393970e80bf89"
2352 integrity sha512-ZK5v4bJwgXldAUA8r3q9YKfCwOqoHTK/ZqRjSeRXQrBXWouoPnS4MQtgC4AXGiiBuUu5wxrRgTlv0ktmM4P1Aw==2277 integrity sha512-yk9Xj/3bUxyz3azMXW8qigLqXWEr2R0h9G7PVnnmjNQdlZLN+aESqCTnVN7ubtYUIQfW32/v8+AXsbpL1ryI1A==
23532278
2354"@sindresorhus/is@^0.14.0":2279"@sindresorhus/is@^0.14.0":
2355 version "0.14.0"2280 version "0.14.0"
2560 resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.15.tgz#10ee6a6a3f971966fddfa3f6e89ef7a73ec622df"2485 resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.15.tgz#10ee6a6a3f971966fddfa3f6e89ef7a73ec622df"
2561 integrity sha512-F6S4Chv4JicJmyrwlDkxUdGNSplsQdGwp1A0AJloEVDirWdZOAiRHhovDlsFkKUrquUXhz1imJhXHsf59auyAg==2486 integrity sha512-F6S4Chv4JicJmyrwlDkxUdGNSplsQdGwp1A0AJloEVDirWdZOAiRHhovDlsFkKUrquUXhz1imJhXHsf59auyAg==
25622487
2563"@types/node@^16.11.4":2488"@types/node@^16.11.6":
2564 version "16.11.4"2489 version "16.11.6"
2565 resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.4.tgz#90771124822d6663814f7c1c9b45a6654d8fd964"2490 resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
2566 integrity sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==2491 integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
25672492
2568"@types/pbkdf2@^3.0.0":2493"@types/pbkdf2@^3.0.0":
2569 version "3.1.0"2494 version "3.1.0"
2615 dependencies:2540 dependencies:
2616 "@types/yargs-parser" "*"2541 "@types/yargs-parser" "*"
26172542
2618"@typescript-eslint/eslint-plugin@5.1.0", "@typescript-eslint/eslint-plugin@^5.1.0":2543"@typescript-eslint/eslint-plugin@5.2.0":
2619 version "5.1.0"2544 version "5.2.0"
2620 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz#381c188dfab12f7a2c7b6a8ba2402d6273eadeaa"2545 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz#2bdb247cc2e2afce7efbce09afb9a6f0a8a08434"
2621 integrity sha512-bekODL3Tqf36Yz8u+ilha4zGxL9mdB6LIsIoMAvvC5FAuWo4NpZYXtCbv7B2CeR1LhI/lLtLk+q4tbtxuoVuCg==2546 integrity sha512-qQwg7sqYkBF4CIQSyRQyqsYvP+g/J0To9ZPVNJpfxfekl5RmdvQnFFTVVwpRtaUDFNvjfe/34TgY/dpc3MgNTw==
2622 dependencies:2547 dependencies:
2623 "@typescript-eslint/experimental-utils" "5.1.0"2548 "@typescript-eslint/experimental-utils" "5.2.0"
2624 "@typescript-eslint/scope-manager" "5.1.0"2549 "@typescript-eslint/scope-manager" "5.2.0"
2625 debug "^4.3.2"2550 debug "^4.3.2"
2626 functional-red-black-tree "^1.0.1"2551 functional-red-black-tree "^1.0.1"
2627 ignore "^5.1.8"2552 ignore "^5.1.8"
2628 regexpp "^3.2.0"2553 regexpp "^3.2.0"
2629 semver "^7.3.5"2554 semver "^7.3.5"
2630 tsutils "^3.21.0"2555 tsutils "^3.21.0"
26312556
2632"@typescript-eslint/experimental-utils@5.1.0":2557"@typescript-eslint/eslint-plugin@^5.3.0":
2633 version "5.1.0"2558 version "5.3.0"
2634 resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.1.0.tgz#918a1a3d30404cc1f8edcfdf0df200804ef90d31"2559 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz#a55ae72d28ffeb6badd817fe4566c9cced1f5e29"
2635 integrity sha512-ovE9qUiZMOMgxQAESZsdBT+EXIfx/YUYAbwGUI6V03amFdOOxI9c6kitkgRvLkJaLusgMZ2xBhss+tQ0Y1HWxA==2560 integrity sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g==
2636 dependencies:2561 dependencies:
2562 "@typescript-eslint/experimental-utils" "5.3.0"
2563 "@typescript-eslint/scope-manager" "5.3.0"
2564 debug "^4.3.2"
2565 functional-red-black-tree "^1.0.1"
2566 ignore "^5.1.8"
2567 regexpp "^3.2.0"
2568 semver "^7.3.5"
2569 tsutils "^3.21.0"
2570
2571"@typescript-eslint/experimental-utils@5.2.0":
2572 version "5.2.0"
2573 resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.2.0.tgz#e3b2cb9cd0aff9b50f68d9a414c299fd26b067e6"
2574 integrity sha512-fWyT3Agf7n7HuZZRpvUYdFYbPk3iDCq6fgu3ulia4c7yxmPnwVBovdSOX7RL+k8u6hLbrXcdAehlWUVpGh6IEw==
2575 dependencies:
2637 "@types/json-schema" "^7.0.9"2576 "@types/json-schema" "^7.0.9"
2638 "@typescript-eslint/scope-manager" "5.1.0"2577 "@typescript-eslint/scope-manager" "5.2.0"
2639 "@typescript-eslint/types" "5.1.0"2578 "@typescript-eslint/types" "5.2.0"
2640 "@typescript-eslint/typescript-estree" "5.1.0"2579 "@typescript-eslint/typescript-estree" "5.2.0"
2641 eslint-scope "^5.1.1"2580 eslint-scope "^5.1.1"
2642 eslint-utils "^3.0.0"2581 eslint-utils "^3.0.0"
26432582
2644"@typescript-eslint/parser@5.1.0", "@typescript-eslint/parser@^5.1.0":2583"@typescript-eslint/experimental-utils@5.3.0":
2645 version "5.1.0"2584 version "5.3.0"
2646 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.1.0.tgz#6c7f837d210d2bc0a811e7ea742af414f4e00908"2585 resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz#ee56b4957547ed2b0fc7451205e41502e664f546"
2647 integrity sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==2586 integrity sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w==
2648 dependencies:2587 dependencies:
2649 "@typescript-eslint/scope-manager" "5.1.0"2588 "@types/json-schema" "^7.0.9"
2589 "@typescript-eslint/scope-manager" "5.3.0"
2650 "@typescript-eslint/types" "5.1.0"2590 "@typescript-eslint/types" "5.3.0"
2591 "@typescript-eslint/typescript-estree" "5.3.0"
2592 eslint-scope "^5.1.1"
2593 eslint-utils "^3.0.0"
2594
2595"@typescript-eslint/parser@5.2.0":
2651 "@typescript-eslint/typescript-estree" "5.1.0"2596 version "5.2.0"
2597 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.2.0.tgz#dc081aa89de16b5676b10215519af3aa7b58fb72"
2598 integrity sha512-Uyy4TjJBlh3NuA8/4yIQptyJb95Qz5PX//6p8n7zG0QnN4o3NF9Je3JHbVU7fxf5ncSXTmnvMtd/LDQWDk0YqA==
2599 dependencies:
2600 "@typescript-eslint/scope-manager" "5.2.0"
2601 "@typescript-eslint/types" "5.2.0"
2602 "@typescript-eslint/typescript-estree" "5.2.0"
2652 debug "^4.3.2"2603 debug "^4.3.2"
26532604
2654"@typescript-eslint/scope-manager@5.1.0":2605"@typescript-eslint/parser@^5.3.0":
2655 version "5.1.0"2606 version "5.3.0"
2656 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz#6f1f26ad66a8f71bbb33b635e74fec43f76b44df"2607 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.3.0.tgz#7879f15e26d370ed3f653fb7dd06479531ed3ab9"
2657 integrity sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==2608 integrity sha512-rKu/yAReip7ovx8UwOAszJVO5MgBquo8WjIQcp1gx4pYQCwYzag+I5nVNHO4MqyMkAo0gWt2gWUi+36gWAVKcw==
2658 dependencies:2609 dependencies:
2659 "@typescript-eslint/types" "5.1.0"2610 "@typescript-eslint/scope-manager" "5.3.0"
2611 "@typescript-eslint/types" "5.3.0"
2660 "@typescript-eslint/visitor-keys" "5.1.0"2612 "@typescript-eslint/typescript-estree" "5.3.0"
2613 debug "^4.3.2"
26612614
2615"@typescript-eslint/scope-manager@5.2.0":
2616 version "5.2.0"
2617 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz#7ce8e4ab2baaa0ad5282913ea8e13ce03ec6a12a"
2618 integrity sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==
2619 dependencies:
2620 "@typescript-eslint/types" "5.2.0"
2621 "@typescript-eslint/visitor-keys" "5.2.0"
2622
2623"@typescript-eslint/scope-manager@5.3.0":
2624 version "5.3.0"
2625 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz#97d0ccc7c9158e89e202d5e24ce6ba49052d432e"
2626 integrity sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A==
2627 dependencies:
2628 "@typescript-eslint/types" "5.3.0"
2629 "@typescript-eslint/visitor-keys" "5.3.0"
2630
2662"@typescript-eslint/types@4.27.0":2631"@typescript-eslint/types@4.27.0":
2663 version "4.27.0"2632 version "4.27.0"
2664 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8"2633 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8"
2665 integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA==2634 integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA==
26662635
2667"@typescript-eslint/types@5.1.0":2636"@typescript-eslint/types@5.2.0":
2668 version "5.1.0"2637 version "5.2.0"
2669 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.1.0.tgz#a8a75ddfc611660de6be17d3ad950302385607a9"2638 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.2.0.tgz#7ad32d15abddb0ee968a330f0ea182ea544ef7cf"
2670 integrity sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==2639 integrity sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==
26712640
2672"@typescript-eslint/typescript-estree@5.1.0":2641"@typescript-eslint/types@5.3.0":
2642 version "5.3.0"
2643 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416"
2644 integrity sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg==
2645
2646"@typescript-eslint/typescript-estree@5.2.0":
2673 version "5.1.0"2647 version "5.2.0"
2674 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz#132aea34372df09decda961cb42457433aa6e83d"2648 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.2.0.tgz#c22e0ff6f8a4a3f78504a80ebd686fe2870a68ae"
2675 integrity sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==2649 integrity sha512-RsdXq2XmVgKbm9nLsE3mjNUM7BTr/K4DYR9WfFVMUuozHWtH5gMpiNZmtrMG8GR385EOSQ3kC9HiEMJWimxd/g==
2676 dependencies:2650 dependencies:
2677 "@typescript-eslint/types" "5.1.0"2651 "@typescript-eslint/types" "5.2.0"
2678 "@typescript-eslint/visitor-keys" "5.1.0"2652 "@typescript-eslint/visitor-keys" "5.2.0"
2679 debug "^4.3.2"2653 debug "^4.3.2"
2680 globby "^11.0.4"2654 globby "^11.0.4"
2681 is-glob "^4.0.3"2655 is-glob "^4.0.3"
2682 semver "^7.3.5"2656 semver "^7.3.5"
2683 tsutils "^3.21.0"2657 tsutils "^3.21.0"
26842658
2659"@typescript-eslint/typescript-estree@5.3.0":
2660 version "5.3.0"
2661 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz#4f68ddd46dc2983182402d2ab21fb44ad94988cf"
2662 integrity sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug==
2663 dependencies:
2664 "@typescript-eslint/types" "5.3.0"
2665 "@typescript-eslint/visitor-keys" "5.3.0"
2666 debug "^4.3.2"
2667 globby "^11.0.4"
2668 is-glob "^4.0.3"
2669 semver "^7.3.5"
2670 tsutils "^3.21.0"
2671
2685"@typescript-eslint/typescript-estree@^4.8.2":2672"@typescript-eslint/typescript-estree@^4.8.2":
2686 version "4.27.0"2673 version "4.27.0"
2687 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.27.0.tgz#189a7b9f1d0717d5cccdcc17247692dedf7a09da"2674 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.27.0.tgz#189a7b9f1d0717d5cccdcc17247692dedf7a09da"
2703 "@typescript-eslint/types" "4.27.0"2690 "@typescript-eslint/types" "4.27.0"
2704 eslint-visitor-keys "^2.0.0"2691 eslint-visitor-keys "^2.0.0"
27052692
2706"@typescript-eslint/visitor-keys@5.1.0":2693"@typescript-eslint/visitor-keys@5.2.0":
2707 version "5.1.0"2694 version "5.2.0"
2708 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz#e01a01b27eb173092705ae983aa1451bd1842630"2695 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz#03522d35df98474f08e0357171a7d1b259a88f55"
2709 integrity sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==2696 integrity sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==
2710 dependencies:2697 dependencies:
2711 "@typescript-eslint/types" "5.1.0"2698 "@typescript-eslint/types" "5.2.0"
2712 eslint-visitor-keys "^3.0.0"2699 eslint-visitor-keys "^3.0.0"
27132700
2701"@typescript-eslint/visitor-keys@5.3.0":
2702 version "5.3.0"
2703 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz#a6258790f3b7b2547f70ed8d4a1e0c3499994523"
2704 integrity sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw==
2705 dependencies:
2706 "@typescript-eslint/types" "5.3.0"
2707 eslint-visitor-keys "^3.0.0"
2708
2714"@ungap/promise-all-settled@1.1.2":2709"@ungap/promise-all-settled@1.1.2":
2715 version "1.1.2"2710 version "1.1.2"
2716 resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"2711 resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
2717 integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==2712 integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
27182713
2719"@vue/component-compiler-utils@^3.2.2":2714"@vue/component-compiler-utils@^3.3.0":
2720 version "3.2.2"2715 version "3.3.0"
2721 resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.2.2.tgz#2f7ed5feed82ff7f0284acc11d525ee7eff22460"2716 resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz#f9f5fb53464b0c37b2c8d2f3fbfe44df60f61dc9"
2722 integrity sha512-rAYMLmgMuqJFWAOb3Awjqqv5X3Q3hVr4jH/kgrFJpiU0j3a90tnNBplqbj+snzrgZhC9W128z+dtgMifOiMfJg==2717 integrity sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==
2723 dependencies:2718 dependencies:
2724 consolidate "^0.15.1"2719 consolidate "^0.15.1"
2725 hash-sum "^1.0.2"2720 hash-sum "^1.0.2"
2730 source-map "~0.6.1"2725 source-map "~0.6.1"
2731 vue-template-es2015-compiler "^1.9.0"2726 vue-template-es2015-compiler "^1.9.0"
2732 optionalDependencies:2727 optionalDependencies:
2733 prettier "^1.18.2"2728 prettier "^1.18.2 || ^2.0.0"
27342729
2735abab@^2.0.3, abab@^2.0.5:2730abab@^2.0.3, abab@^2.0.5:
2736 version "2.0.5"2731 version "2.0.5"
3383 escalade "^3.1.1"3378 escalade "^3.1.1"
3384 node-releases "^1.1.73"3379 node-releases "^1.1.73"
33853380
3386browserslist@^4.17.4, browserslist@^4.17.5:3381browserslist@^4.17.5:
3387 version "4.17.5"3382 version "4.17.5"
3388 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.5.tgz#c827bbe172a4c22b123f5e337533ceebadfdd559"3383 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.5.tgz#c827bbe172a4c22b123f5e337533ceebadfdd559"
3389 integrity sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==3384 integrity sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==
4681 resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz#a1dad262f46d2184a90095a60c66fef74727f0f8"4676 resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz#a1dad262f46d2184a90095a60c66fef74727f0f8"
4682 integrity sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==4677 integrity sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==
46834678
4684eslint-plugin-sort-destructure-keys@^1.3.5:4679eslint-plugin-sort-destructure-keys@^1.4.0:
4685 version "1.3.5"4680 version "1.4.0"
4686 resolved "https://registry.yarnpkg.com/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-1.3.5.tgz#c6f45c3e58d4435564025a6ca5f4a838010800fd"4681 resolved "https://registry.yarnpkg.com/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-1.4.0.tgz#45924521e556692002522468a75b6a9fbac11316"
4687 integrity sha512-JmVpidhDsLwZsmRDV7Tf/vZgOAOEQGkLtwToSvX5mD8fuWYS/xkgMRBsalW1fGlc8CgJJwnzropt4oMQ7YCHLg==4682 integrity sha512-txU9l22mblz7YpyjJNYFy4wb5PVXiRMbc9lqFPPhvY4wKyBBYQvb31TIcduf7iRb4Bv01aiXcJiuCkOOrVY48Q==
4688 dependencies:4683 dependencies:
4689 natural-compare-lite "^1.4.0"4684 natural-compare-lite "^1.4.0"
46904685
8110 version "2.0.0"8105 version "2.0.0"
8111 resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"8106 resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
8112 integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=8107 integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
8113
8114prettier@^1.18.2:
8115 version "1.19.1"
8116 resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
8117 integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
81188108
8119prettier@^2.4.1:8109"prettier@^1.18.2 || ^2.0.0", prettier@^2.4.1:
8120 version "2.4.1"8110 version "2.4.1"
8121 resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"8111 resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
8122 integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==8112 integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
8595 dependencies:8585 dependencies:
8596 bn.js "^5.2.0"8586 bn.js "^5.2.0"
85978587
8598rollup@^2.58.0:8588rollup@^2.58.3:
8599 version "2.58.3"8589 version "2.59.0"
8600 resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.58.3.tgz#71a08138d9515fb65043b6a18618b2ed9ac8d239"8590 resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.59.0.tgz#108c61b0fa0a37ebc8d1f164f281622056f0db59"
8601 integrity sha512-ei27MSw1KhRur4p87Q0/Va2NAYqMXOX++FNEumMBcdreIRLURKy+cE2wcDJKBn0nfmhP2ZGrJkP1XPO+G8FJQw==8591 integrity sha512-l7s90JQhCQ6JyZjKgo7Lq1dKh2RxatOM+Jr6a9F7WbS9WgKbocyUSeLmZl8evAse7y96Ae98L2k1cBOwWD8nHw==
8602 optionalDependencies:8592 optionalDependencies:
8603 fsevents "~2.3.2"8593 fsevents "~2.3.2"
86048594