git.delta.rocks / unique-network / refs/commits / 9844c489516c

difftreelog

Merge branch 'develop' into test/playground-migration

rkv2022-09-14parents: #3d71464 #61c518e.patch.diff
in: master

142 files changed

added.github/workflows/canary.ymldiffbeforeafterboth

no changes

added.github/workflows/ci-develop.ymldiffbeforeafterboth

no changes

added.github/workflows/ci-master.ymldiffbeforeafterboth

no changes

deleted.github/workflows/codestyle.ymldiffbeforeafterboth

no changes

added.github/workflows/codestyle_v2.ymldiffbeforeafterboth

no changes

deleted.github/workflows/dev-build-tests.ymldiffbeforeafterboth

no changes

added.github/workflows/dev-build-tests_v2.ymldiffbeforeafterboth

no changes

added.github/workflows/execution-matrix.ymldiffbeforeafterboth

no changes

deleted.github/workflows/forkless-update-data.ymldiffbeforeafterboth

no changes

added.github/workflows/forkless-update-data_v2.ymldiffbeforeafterboth

no changes

deleted.github/workflows/forkless-update-nodata.ymldiffbeforeafterboth

no changes

added.github/workflows/forkless-update-nodata_v2.ymldiffbeforeafterboth

no changes

added.github/workflows/forkless.ymldiffbeforeafterboth

no changes

added.github/workflows/generate-execution-matrix.ymldiffbeforeafterboth

no changes

added.github/workflows/market-test_v2.ymldiffbeforeafterboth

no changes

added.github/workflows/node-only-update_v2.ymldiffbeforeafterboth

no changes

deleted.github/workflows/nodes-only-update.ymldiffbeforeafterboth

no changes

added.github/workflows/test_codestyle_v2.ymldiffbeforeafterboth

no changes

deleted.github/workflows/tests_codestyle.ymldiffbeforeafterboth

no changes

deleted.github/workflows/try-runtime.ymldiffbeforeafterboth

no changes

added.github/workflows/try-runtime_v2.ymldiffbeforeafterboth

no changes

deleted.github/workflows/unit-test.ymldiffbeforeafterboth

no changes

added.github/workflows/unit-test_v2.ymldiffbeforeafterboth

no changes

added.github/workflows/xcm-testnet-build.ymldiffbeforeafterboth

no changes

added.github/workflows/xcm-tests_v2.ymldiffbeforeafterboth

no changes

added.github/workflows/xcm.ymldiffbeforeafterboth

no changes

modified.maintain/scripts/generate_sol.shdiffbeforeafterboth
1#!/bin/sh1#!/bin/sh
2set -eu2set -eu
3
4PRETTIER_CONFIG="$(pwd)""/.prettierrc"
35
4tmp=$(mktemp)6tmp=$(mktemp)
5cargo test --package $PACKAGE -- $NAME --exact --nocapture --ignored | tee $tmp7cargo test --package $PACKAGE -- $NAME --exact --nocapture --ignored | tee $tmp
6raw=$(mktemp --suffix .sol)8raw=$(mktemp --suffix .sol)
7sed -n '/=== SNIP START ===/, /=== SNIP END ===/{ /=== SNIP START ===/! { /=== SNIP END ===/! p } }' $tmp > $raw9sed -n '/=== SNIP START ===/, /=== SNIP END ===/{ /=== SNIP START ===/! { /=== SNIP END ===/! p } }' $tmp > $raw
10
8formatted=$(mktemp)11formatted=$(mktemp)
9prettier --use-tabs $raw > $formatted12prettier --config $PRETTIER_CONFIG $raw > $formatted
1013
11mv $formatted $OUTPUT14mv $formatted $OUTPUT
1215
added.prettierignorediffbeforeafterboth

no changes

added.prettierrcdiffbeforeafterboth

no changes

modifiedCargo.lockdiffbeforeafterboth
2324[[package]]2324[[package]]
2325name = "fc-consensus"2325name = "fc-consensus"
2326version = "2.0.0-dev"2326version = "2.0.0-dev"
2327source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2327source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2328dependencies = [2328dependencies = [
2329 "async-trait",2329 "async-trait",
2330 "fc-db",2330 "fc-db",
2343[[package]]2343[[package]]
2344name = "fc-db"2344name = "fc-db"
2345version = "2.0.0-dev"2345version = "2.0.0-dev"
2346source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2346source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2347dependencies = [2347dependencies = [
2348 "fp-storage",2348 "fp-storage",
2349 "kvdb-rocksdb",2349 "kvdb-rocksdb",
2359[[package]]2359[[package]]
2360name = "fc-mapping-sync"2360name = "fc-mapping-sync"
2361version = "2.0.0-dev"2361version = "2.0.0-dev"
2362source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2362source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2363dependencies = [2363dependencies = [
2364 "fc-db",2364 "fc-db",
2365 "fp-consensus",2365 "fp-consensus",
2376[[package]]2376[[package]]
2377name = "fc-rpc"2377name = "fc-rpc"
2378version = "2.0.0-dev"2378version = "2.0.0-dev"
2379source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2379source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2380dependencies = [2380dependencies = [
2381 "ethereum",2381 "ethereum",
2382 "ethereum-types",2382 "ethereum-types",
2416[[package]]2416[[package]]
2417name = "fc-rpc-core"2417name = "fc-rpc-core"
2418version = "1.1.0-dev"2418version = "1.1.0-dev"
2419source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2419source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2420dependencies = [2420dependencies = [
2421 "ethereum",2421 "ethereum",
2422 "ethereum-types",2422 "ethereum-types",
2557[[package]]2557[[package]]
2558name = "fp-consensus"2558name = "fp-consensus"
2559version = "2.0.0-dev"2559version = "2.0.0-dev"
2560source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2560source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2561dependencies = [2561dependencies = [
2562 "ethereum",2562 "ethereum",
2563 "parity-scale-codec 3.1.5",2563 "parity-scale-codec 3.1.5",
2569[[package]]2569[[package]]
2570name = "fp-evm"2570name = "fp-evm"
2571version = "3.0.0-dev"2571version = "3.0.0-dev"
2572source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2572source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2573dependencies = [2573dependencies = [
2574 "evm",2574 "evm",
2575 "frame-support",2575 "frame-support",
2583[[package]]2583[[package]]
2584name = "fp-evm-mapping"2584name = "fp-evm-mapping"
2585version = "0.1.0"2585version = "0.1.0"
2586source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2586source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2587dependencies = [2587dependencies = [
2588 "frame-support",2588 "frame-support",
2589 "sp-core",2589 "sp-core",
2592[[package]]2592[[package]]
2593name = "fp-rpc"2593name = "fp-rpc"
2594version = "3.0.0-dev"2594version = "3.0.0-dev"
2595source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2595source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2596dependencies = [2596dependencies = [
2597 "ethereum",2597 "ethereum",
2598 "ethereum-types",2598 "ethereum-types",
2609[[package]]2609[[package]]
2610name = "fp-self-contained"2610name = "fp-self-contained"
2611version = "1.0.0-dev"2611version = "1.0.0-dev"
2612source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2612source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2613dependencies = [2613dependencies = [
2614 "ethereum",2614 "ethereum",
2615 "frame-support",2615 "frame-support",
2625[[package]]2625[[package]]
2626name = "fp-storage"2626name = "fp-storage"
2627version = "2.0.0"2627version = "2.0.0"
2628source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2628source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2629dependencies = [2629dependencies = [
2630 "parity-scale-codec 3.1.5",2630 "parity-scale-codec 3.1.5",
2631]2631]
5445[[package]]5445[[package]]
5446name = "pallet-base-fee"5446name = "pallet-base-fee"
5447version = "1.0.0"5447version = "1.0.0"
5448source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"5448source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
5449dependencies = [5449dependencies = [
5450 "fp-evm",5450 "fp-evm",
5451 "frame-support",5451 "frame-support",
5660[[package]]5660[[package]]
5661name = "pallet-ethereum"5661name = "pallet-ethereum"
5662version = "4.0.0-dev"5662version = "4.0.0-dev"
5663source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"5663source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
5664dependencies = [5664dependencies = [
5665 "ethereum",5665 "ethereum",
5666 "ethereum-types",5666 "ethereum-types",
5689[[package]]5689[[package]]
5690name = "pallet-evm"5690name = "pallet-evm"
5691version = "6.0.0-dev"5691version = "6.0.0-dev"
5692source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"5692source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
5693dependencies = [5693dependencies = [
5694 "evm",5694 "evm",
5695 "fp-evm",5695 "fp-evm",
57335733
5734[[package]]5734[[package]]
5735name = "pallet-evm-contract-helpers"5735name = "pallet-evm-contract-helpers"
5736version = "0.2.0"5736version = "0.3.0"
5737dependencies = [5737dependencies = [
5738 "ethereum",5738 "ethereum",
5739 "evm-coder",5739 "evm-coder",
5744 "pallet-common",5744 "pallet-common",
5745 "pallet-evm",5745 "pallet-evm",
5746 "pallet-evm-coder-substrate",5746 "pallet-evm-coder-substrate",
5747 "pallet-evm-transaction-payment",
5747 "parity-scale-codec 3.1.5",5748 "parity-scale-codec 3.1.5",
5748 "scale-info",5749 "scale-info",
5749 "sp-core",5750 "sp-core",
1231612317
12317[[package]]12318[[package]]
12318name = "unique-rpc"12319name = "unique-rpc"
12319version = "0.1.1"12320version = "0.1.2"
12320dependencies = [12321dependencies = [
12321 "app-promotion-rpc",12322 "app-promotion-rpc",
12322 "fc-db",12323 "fc-db",
modifiedclient/rpc/Cargo.tomldiffbeforeafterboth
19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
20sp-rpc = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }20sp-rpc = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
21sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }21sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2323
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
577 BlockNumber: Decode + Member + AtLeast32BitUnsigned,577 BlockNumber: Decode + Member + AtLeast32BitUnsigned,
578 AccountId: Decode,578 AccountId: Decode,
579 C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,579 C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
580 C::Api: AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>,
581 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,580 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,
581 C::Api: AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>,
582{582{
583 pass_method!(total_staked(staker: Option<CrossAccountId>) -> String => |v| v.to_string(), app_promotion_api);583 pass_method!(total_staked(staker: Option<CrossAccountId>) -> String => |v| v.to_string(), app_promotion_api);
584 pass_method!(total_staked_per_block(staker: CrossAccountId) -> Vec<(BlockNumber, String)> =>584 pass_method!(total_staked_per_block(staker: CrossAccountId) -> Vec<(BlockNumber, String)> =>
addeddoc/sponsoring-flow.drawio.svgdiffbeforeafterboth

no changes

addeddoc/sponsoring.mddiffbeforeafterboth

no changes

modifiednode/cli/CHANGELOG.mddiffbeforeafterboth
1<!-- bureaucrate goes here -->1<!-- bureaucrate goes here -->
2
3## [v0.9.27] 2022-09-08
4
5### Added
6- Support RPC for `AppPromotion` pallet.
7
2## [v0.9.27] 2022-08-168## [v0.9.27] 2022-08-16
39
4### Other changes10### Other changes
modifiednode/cli/Cargo.tomldiffbeforeafterboth
309jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }309jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }
310tokio = { version = "1.19.2", features = ["time"] }310tokio = { version = "1.19.2", features = ["time"] }
311311
312fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }312fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
313fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }313fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
314fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }314fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
315fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }315fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
316fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }316fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
317fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }317fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
318pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }318pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
319319
320unique-rpc = { default-features = false, path = "../rpc" }320unique-rpc = { default-features = false, path = "../rpc" }
321app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}321app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
modifiednode/rpc/CHANGELOG.mddiffbeforeafterboth
1<!-- bureaucrate goes here -->1<!-- bureaucrate goes here -->
2## [v0.1.2] 2022-09-08
3
4### Added
5- Support RPC for `AppPromotion` pallet.
6
2## [v0.1.1] 2022-08-167## [v0.1.1] 2022-08-16
38
4### Other changes9### Other changes
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "unique-rpc"2name = "unique-rpc"
3version = "0.1.1"3version = "0.1.2"
4authors = ['Unique Network <support@uniquenetwork.io>']4authors = ['Unique Network <support@uniquenetwork.io>']
5license = 'GPLv3'5license = 'GPLv3'
6edition = "2021"6edition = "2021"
40substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }40substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
41tokio = { version = "1.19.2", features = ["macros", "sync"] }41tokio = { version = "1.19.2", features = ["macros", "sync"] }
4242
43pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }43pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
44fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }44fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
45fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }45fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
46fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }46fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
47fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }47fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
48fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }48fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
5050
51pallet-common = { default-features = false, path = "../../pallets/common" }51pallet-common = { default-features = false, path = "../../pallets/common" }
52up-common = { path = "../../primitives/common" }52up-common = { path = "../../primitives/common" }
modifiedpallets/app-promotion/Cargo.tomldiffbeforeafterboth
52pallet-balances ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }52pallet-balances ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
53pallet-timestamp ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }53pallet-timestamp ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
54pallet-randomness-collective-flip ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }54pallet-randomness-collective-flip ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
55pallet-evm ={ default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }55pallet-evm ={ default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
56sp-std ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }56sp-std ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
57sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }57sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
58sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }58sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
modifiedpallets/app-promotion/src/benchmarking.rsdiffbeforeafterboth
112 let share = Perbill::from_rational(1u32, 20);112 let share = Perbill::from_rational(1u32, 20);
113 let _ = <T as Config>::Currency::make_free_balance_be(&caller, Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());113 let _ = <T as Config>::Currency::make_free_balance_be(&caller, Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
114 (0..10).map(|_| {114 (0..10).map(|_| {
115 // used to change block number
115 <frame_system::Pallet<T>>::finalize();116 <frame_system::Pallet<T>>::finalize();
116 PromototionPallet::<T>::stake(RawOrigin::Signed(caller.clone()).into(), share * <T as Config>::Currency::total_balance(&caller))117 PromototionPallet::<T>::stake(RawOrigin::Signed(caller.clone()).into(), share * <T as Config>::Currency::total_balance(&caller))
117 }).collect::<Result<Vec<_>, _>>()?;118 }).collect::<Result<Vec<_>, _>>()?;
modifiedpallets/app-promotion/src/lib.rsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17//! # App promotion17//! # App Promotion pallet
18//!18//!
19//! The app promotion pallet is designed to ... .19//! The pallet implements the mechanics of staking and sponsoring collections/contracts.
20//!
21//! - [`Config`]
22//! - [`Pallet`]
23//! - [`Error`]
24//! - [`Event`]
25//!
26//! ## Overview
27//! The App Promotion pallet allows fund holders to stake at a certain daily rate of return.
28//! The mechanics implemented in the pallet allow it to act as a sponsor for collections / contracts,
29//! the list of which is set by the pallet administrator.
30//!
20//!31//!
21//! ## Interface32//! ## Interface
33//! The pallet provides interfaces for funds, collection/contract operations (see [types] module).
34
22//!35//!
23//! ### Dispatchable Functions36//! ### Dispatchable Functions
37//! - [`set_admin_address`][`Pallet::set_admin_address`] - sets an address as the the admin.
38//! - [`stake`][`Pallet::stake`] - stakes the amount of native tokens.
39//! - [`unstake`][`Pallet::unstake`] - unstakes all stakes.
40//! - [`sponsor_collection`][`Pallet::sponsor_collection`] - sets the pallet to be the sponsor for the collection.
41//! - [`stop_sponsoring_collection`][`Pallet::stop_sponsoring_collection`] - removes the pallet as the sponsor for the collection.
42//! - [`sponsor_contract`][`Pallet::sponsor_contract`] - sets the pallet to be the sponsor for the contract.
43//! - [`stop_sponsoring_contract`][`Pallet::stop_sponsoring_contract`] - removes the pallet as the sponsor for the contract.
44//! - [`payout_stakers`][`Pallet::payout_stakers`] - recalculates interest for the specified number of stakers.
24//!45//!
2546
26// #![recursion_limit = "1024"]47// #![recursion_limit = "1024"]
95 /// Type for interacting with conrtacts116 /// Type for interacting with conrtacts
96 type ContractHandler: ContractHandler<AccountId = Self::CrossAccountId, ContractId = H160>;117 type ContractHandler: ContractHandler<AccountId = Self::CrossAccountId, ContractId = H160>;
97118
98 /// ID for treasury119 /// `AccountId` for treasury
99 type TreasuryAccountId: Get<Self::AccountId>;120 type TreasuryAccountId: Get<Self::AccountId>;
100121
101 /// The app's pallet id, used for deriving its sovereign account ID.122 /// The app's pallet id, used for deriving its sovereign account address.
102 #[pallet::constant]123 #[pallet::constant]
103 type PalletId: Get<PalletId>;124 type PalletId: Get<PalletId>;
104125
138 /// Staking recalculation was performed159 /// Staking recalculation was performed
139 ///160 ///
140 /// # Arguments161 /// # Arguments
141 /// * AccountId: ID of the staker.162 /// * AccountId: account of the staker.
142 /// * Balance : recalculation base163 /// * Balance : recalculation base
143 /// * Balance : total income164 /// * Balance : total income
144 StakingRecalculation(165 StakingRecalculation(
153 /// Staking was performed174 /// Staking was performed
154 ///175 ///
155 /// # Arguments176 /// # Arguments
156 /// * AccountId: ID of the staker177 /// * AccountId: account of the staker
157 /// * Balance : staking amount178 /// * Balance : staking amount
158 Stake(T::AccountId, BalanceOf<T>),179 Stake(T::AccountId, BalanceOf<T>),
159180
160 /// Unstaking was performed181 /// Unstaking was performed
161 ///182 ///
162 /// # Arguments183 /// # Arguments
163 /// * AccountId: ID of the staker184 /// * AccountId: account of the staker
164 /// * Balance : unstaking amount185 /// * Balance : unstaking amount
165 Unstake(T::AccountId, BalanceOf<T>),186 Unstake(T::AccountId, BalanceOf<T>),
166187
167 /// The admin was set188 /// The admin was set
168 ///189 ///
169 /// # Arguments190 /// # Arguments
170 /// * AccountId: ID of the admin191 /// * AccountId: account address of the admin
171 SetAdmin(T::AccountId),192 SetAdmin(T::AccountId),
172 }193 }
173194
187 IncorrectLockedBalanceOperation,208 IncorrectLockedBalanceOperation,
188 }209 }
189210
211 /// Stores the total staked amount.
190 #[pallet::storage]212 #[pallet::storage]
191 pub type TotalStaked<T: Config> = StorageValue<Value = BalanceOf<T>, QueryKind = ValueQuery>;213 pub type TotalStaked<T: Config> = StorageValue<Value = BalanceOf<T>, QueryKind = ValueQuery>;
192214
215 /// Stores the `admin` account. Some extrinsics can only be executed if they were signed by `admin`.
193 #[pallet::storage]216 #[pallet::storage]
194 pub type Admin<T: Config> = StorageValue<Value = T::AccountId, QueryKind = OptionQuery>;217 pub type Admin<T: Config> = StorageValue<Value = T::AccountId, QueryKind = OptionQuery>;
195218
196 /// Amount of tokens staked by account in the blocknumber.219 /// Stores the amount of tokens staked by account in the blocknumber.
220 ///
221 /// * **Key1** - Staker account.
222 /// * **Key2** - Relay block number when the stake was made.
223 /// * **(Balance, BlockNumber)** - Balance of the stake.
224 /// The number of the relay block in which we must perform the interest recalculation
197 #[pallet::storage]225 #[pallet::storage]
198 pub type Staked<T: Config> = StorageNMap<226 pub type Staked<T: Config> = StorageNMap<
199 Key = (227 Key = (
204 QueryKind = ValueQuery,232 QueryKind = ValueQuery,
205 >;233 >;
234
206 /// Amount of stakes for an Account235 /// Stores amount of stakes for an `Account`.
236 ///
237 /// * **Key** - Staker account.
238 /// * **Value** - Amount of stakes.
207 #[pallet::storage]239 #[pallet::storage]
208 pub type StakesPerAccount<T: Config> =240 pub type StakesPerAccount<T: Config> =
209 StorageMap<_, Blake2_128Concat, T::AccountId, u8, ValueQuery>;241 StorageMap<_, Blake2_128Concat, T::AccountId, u8, ValueQuery>;
210242
243 /// Stores amount of stakes for an `Account`.
244 ///
245 /// * **Key** - Staker account.
246 /// * **Value** - Amount of stakes.
211 #[pallet::storage]247 #[pallet::storage]
212 pub type PendingUnstake<T: Config> = StorageMap<248 pub type PendingUnstake<T: Config> = StorageMap<
213 _,249 _,
252 T::BlockNumber: From<u32> + Into<u32>,288 T::BlockNumber: From<u32> + Into<u32>,
253 <<T as Config>::Currency as Currency<T::AccountId>>::Balance: Sum + From<u128>,289 <<T as Config>::Currency as Currency<T::AccountId>>::Balance: Sum + From<u128>,
254 {290 {
291 /// Sets an address as the the admin.
292 ///
293 /// # Permissions
294 ///
295 /// * Sudo
296 ///
297 /// # Arguments
298 ///
299 /// * `admin`: account of the new admin.
255 #[pallet::weight(T::WeightInfo::set_admin_address())]300 #[pallet::weight(T::WeightInfo::set_admin_address())]
256 pub fn set_admin_address(origin: OriginFor<T>, admin: T::CrossAccountId) -> DispatchResult {301 pub fn set_admin_address(origin: OriginFor<T>, admin: T::CrossAccountId) -> DispatchResult {
257 ensure_root(origin)?;302 ensure_root(origin)?;
263 Ok(())308 Ok(())
264 }309 }
265310
311 /// Stakes the amount of native tokens.
312 /// Sets `amount` to the locked state.
313 /// The maximum number of stakes for a staker is 10.
314 ///
315 /// # Arguments
316 ///
317 /// * `amount`: in native tokens.
266 #[pallet::weight(T::WeightInfo::stake())]318 #[pallet::weight(T::WeightInfo::stake())]
267 pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {319 pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {
268 let staker_id = ensure_signed(staker)?;320 let staker_id = ensure_signed(staker)?;
280 let balance =332 let balance =
281 <<T as Config>::Currency as Currency<T::AccountId>>::free_balance(&staker_id);333 <<T as Config>::Currency as Currency<T::AccountId>>::free_balance(&staker_id);
282334
335 // checks that we can lock `amount` on the `staker` account.
283 <<T as Config>::Currency as Currency<T::AccountId>>::ensure_can_withdraw(336 <<T as Config>::Currency as Currency<T::AccountId>>::ensure_can_withdraw(
284 &staker_id,337 &staker_id,
285 amount,338 amount,
293346
294 let block_number = T::RelayBlockNumberProvider::current_block_number();347 let block_number = T::RelayBlockNumberProvider::current_block_number();
295348
349 // Calculation of the number of recalculation periods,
350 // after how much the first interest calculation should be performed for the stake
296 let recalculate_after_interval: T::BlockNumber =351 let recalculate_after_interval: T::BlockNumber =
297 if block_number % T::RecalculationInterval::get() == 0u32.into() {352 if block_number % T::RecalculationInterval::get() == 0u32.into() {
298 1u32.into()353 1u32.into()
299 } else {354 } else {
300 2u32.into()355 2u32.into()
301 };356 };
302357
358 // Сalculation of the number of the relay block
359 // in which it is necessary to accrue remuneration for the stake.
303 let recalc_block = (block_number / T::RecalculationInterval::get()360 let recalc_block = (block_number / T::RecalculationInterval::get()
304 + recalculate_after_interval)361 + recalculate_after_interval)
305 * T::RecalculationInterval::get();362 * T::RecalculationInterval::get();
327 Ok(())384 Ok(())
328 }385 }
329386
387 /// Unstakes all stakes.
388 /// Moves the sum of all stakes to the `reserved` state.
389 /// After the end of `PendingInterval` this sum becomes completely
390 /// free for further use.
330 #[pallet::weight(T::WeightInfo::unstake())]391 #[pallet::weight(T::WeightInfo::unstake())]
331 pub fn unstake(staker: OriginFor<T>) -> DispatchResultWithPostInfo {392 pub fn unstake(staker: OriginFor<T>) -> DispatchResultWithPostInfo {
332 let staker_id = ensure_signed(staker)?;393 let staker_id = ensure_signed(staker)?;
394
395 // calculate block number where the sum would be free
333 let block = <frame_system::Pallet<T>>::block_number() + T::PendingInterval::get();396 let block = <frame_system::Pallet<T>>::block_number() + T::PendingInterval::get();
397
334 let mut pendings = <PendingUnstake<T>>::get(block);398 let mut pendings = <PendingUnstake<T>>::get(block);
335399
400 // checks that we can do unreserve stakes in the block
336 ensure!(!pendings.is_full(), Error::<T>::PendingForBlockOverflow);401 ensure!(!pendings.is_full(), Error::<T>::PendingForBlockOverflow);
337402
338 let mut total_stakes = 0u64;403 let mut total_stakes = 0u64;
371 Ok(None.into())436 Ok(None.into())
372 }437 }
373438
439 /// Sets the pallet to be the sponsor for the collection.
440 ///
441 /// # Permissions
442 ///
443 /// * Pallet admin
444 ///
445 /// # Arguments
446 ///
447 /// * `collection_id`: ID of the collection that will be sponsored by `pallet_id`
374 #[pallet::weight(T::WeightInfo::sponsor_collection())]448 #[pallet::weight(T::WeightInfo::sponsor_collection())]
375 pub fn sponsor_collection(449 pub fn sponsor_collection(
376 admin: OriginFor<T>,450 admin: OriginFor<T>,
385 T::CollectionHandler::set_sponsor(Self::account_id(), collection_id)459 T::CollectionHandler::set_sponsor(Self::account_id(), collection_id)
386 }460 }
461
462 /// Removes the pallet as the sponsor for the collection.
463 /// Returns [`NoPermission`][`Error::NoPermission`]
464 /// if the pallet wasn't the sponsor.
465 ///
466 /// # Permissions
467 ///
468 /// * Pallet admin
469 ///
470 /// # Arguments
471 ///
472 /// * `collection_id`: ID of the collection that is sponsored by `pallet_id`
387 #[pallet::weight(T::WeightInfo::stop_sponsoring_collection())]473 #[pallet::weight(T::WeightInfo::stop_sponsoring_collection())]
388 pub fn stop_sponsoring_collection(474 pub fn stop_sponsoring_collection(
389 admin: OriginFor<T>,475 admin: OriginFor<T>,
404 T::CollectionHandler::remove_collection_sponsor(collection_id)490 T::CollectionHandler::remove_collection_sponsor(collection_id)
405 }491 }
406492
493 /// Sets the pallet to be the sponsor for the contract.
494 ///
495 /// # Permissions
496 ///
497 /// * Pallet admin
498 ///
499 /// # Arguments
500 ///
501 /// * `contract_id`: the contract address that will be sponsored by `pallet_id`
407 #[pallet::weight(T::WeightInfo::sponsor_contract())]502 #[pallet::weight(T::WeightInfo::sponsor_contract())]
408 pub fn sponsor_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {503 pub fn sponsor_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {
409 let admin_id = ensure_signed(admin)?;504 let admin_id = ensure_signed(admin)?;
419 )514 )
420 }515 }
421516
517 /// Removes the pallet as the sponsor for the contract.
518 /// Returns [`NoPermission`][`Error::NoPermission`]
519 /// if the pallet wasn't the sponsor.
520 ///
521 /// # Permissions
522 ///
523 /// * Pallet admin
524 ///
525 /// # Arguments
526 ///
527 /// * `contract_id`: the contract address that is sponsored by `pallet_id`
422 #[pallet::weight(T::WeightInfo::stop_sponsoring_contract())]528 #[pallet::weight(T::WeightInfo::stop_sponsoring_contract())]
423 pub fn stop_sponsoring_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {529 pub fn stop_sponsoring_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {
424 let admin_id = ensure_signed(admin)?;530 let admin_id = ensure_signed(admin)?;
437 T::ContractHandler::remove_contract_sponsor(contract_id)543 T::ContractHandler::remove_contract_sponsor(contract_id)
438 }544 }
439545
546 /// Recalculates interest for the specified number of stakers.
547 /// If all stakers are not recalculated, the next call of the extrinsic
548 /// will continue the recalculation, from those stakers for whom this
549 /// was not perform in last call.
550 ///
551 /// # Permissions
552 ///
553 /// * Pallet admin
554 ///
555 /// # Arguments
556 ///
557 /// * `stakers_number`: the number of stakers for which recalculation will be performed
440 #[pallet::weight(T::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]558 #[pallet::weight(T::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]
441 pub fn payout_stakers(admin: OriginFor<T>, stakers_number: Option<u8>) -> DispatchResult {559 pub fn payout_stakers(admin: OriginFor<T>, stakers_number: Option<u8>) -> DispatchResult {
442 let admin_id = ensure_signed(admin)?;560 let admin_id = ensure_signed(admin)?;
446 Error::<T>::NoPermission564 Error::<T>::NoPermission
447 );565 );
448566
567 // calculate the number of the current recalculation block,
568 // this is necessary in order to understand which stakers we should calculate interest
449 let current_recalc_block =569 let current_recalc_block =
450 Self::get_current_recalc_block(T::RelayBlockNumberProvider::current_block_number());570 Self::get_current_recalc_block(T::RelayBlockNumberProvider::current_block_number());
571
572 // calculate the number of the next recalculation block,
573 // this value is set for the stakers to whom the recalculation will be performed
451 let next_recalc_block = current_recalc_block + T::RecalculationInterval::get();574 let next_recalc_block = current_recalc_block + T::RecalculationInterval::get();
452575
453 let mut storage_iterator = Self::get_next_calculated_key()576 let mut storage_iterator = Self::get_next_calculated_key()
454 .map_or(Staked::<T>::iter(), |key| Staked::<T>::iter_from(key));577 .map_or(Staked::<T>::iter(), |key| Staked::<T>::iter_from(key));
455578
456 NextCalculatedRecord::<T>::set(None);579 NextCalculatedRecord::<T>::set(None);
457
458 // {
459 // let mut stakers_number = stakers_number.unwrap_or(20);
460 // let mut last_id = admin_id;
461 // let mut income_acc = BalanceOf::<T>::default();
462 // let mut amount_acc = BalanceOf::<T>::default();
463
464 // while let Some((
465 // (current_id, staked_block),
466 // (amount, next_recalc_block_for_stake),
467 // )) = storage_iterator.next()
468 // {
469 // if last_id != current_id {
470 // if income_acc != BalanceOf::<T>::default() {
471 // <T::Currency as Currency<T::AccountId>>::transfer(
472 // &T::TreasuryAccountId::get(),
473 // &last_id,
474 // income_acc,
475 // ExistenceRequirement::KeepAlive,
476 // )
477 // .and_then(|_| Self::add_lock_balance(&last_id, income_acc))?;
478
479 // Self::deposit_event(Event::StakingRecalculation(
480 // last_id, amount, income_acc,
481 // ));
482 // }
483
484 // if stakers_number == 0 {
485 // NextCalculatedRecord::<T>::set(Some((current_id, staked_block)));
486 // break;
487 // }
488 // stakers_number -= 1;
489 // income_acc = BalanceOf::<T>::default();
490 // last_id = current_id;
491 // };
492 // if current_recalc_block >= next_recalc_block_for_stake {
493 // Self::recalculate_and_insert_stake(
494 // &last_id,
495 // staked_block,
496 // next_recalc_block,
497 // amount,
498 // ((current_recalc_block - next_recalc_block_for_stake)
499 // / T::RecalculationInterval::get())
500 // .into() + 1,
501 // &mut income_acc,
502 // );
503 // }
504 // }
505 // }
506580
507 {581 {
508 let mut stakers_number = stakers_number.unwrap_or(20);582 let mut stakers_number = stakers_number.unwrap_or(20);
509 let last_id = RefCell::new(None);583 let last_id = RefCell::new(None);
510 let income_acc = RefCell::new(BalanceOf::<T>::default());584 let income_acc = RefCell::new(BalanceOf::<T>::default());
511 let amount_acc = RefCell::new(BalanceOf::<T>::default());585 let amount_acc = RefCell::new(BalanceOf::<T>::default());
512586
587 // this closure is used to perform some of the actions if we break the loop because we reached the number of stakers for recalculation,
588 // but there were unrecalculated records in the storage.
513 let flush_stake = || -> DispatchResult {589 let flush_stake = || -> DispatchResult {
514 if let Some(last_id) = &*last_id.borrow() {590 if let Some(last_id) = &*last_id.borrow() {
515 if !income_acc.borrow().is_zero() {591 if !income_acc.borrow().is_zero() {
578}654}
579655
580impl<T: Config> Pallet<T> {656impl<T: Config> Pallet<T> {
657 /// The account address of the app promotion pot.
658 ///
659 /// This actually does computation. If you need to keep using it, then make sure you cache the
660 /// value and only call this once.
581 pub fn account_id() -> T::AccountId {661 pub fn account_id() -> T::AccountId {
582 T::PalletId::get().into_account_truncating()662 T::PalletId::get().into_account_truncating()
583 }663 }
584664
665 /// Unlocks the balance that was locked by the pallet.
666 ///
667 /// - `staker`: staker account.
668 /// - `amount`: amount of unlocked funds.
585 fn unlock_balance(staker: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {669 fn unlock_balance(staker: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
586 let locked_balance = Self::get_locked_balance(staker)670 let locked_balance = Self::get_locked_balance(staker)
587 .map(|l| l.amount)671 .map(|l| l.amount)
598 Ok(())682 Ok(())
599 }683 }
600684
685 /// Adds the balance to locked by the pallet.
686 ///
687 /// - `staker`: staker account.
688 /// - `amount`: amount of added locked funds.
601 fn add_lock_balance(staker: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {689 fn add_lock_balance(staker: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
602 Self::get_locked_balance(staker)690 Self::get_locked_balance(staker)
603 .map_or(<BalanceOf<T>>::default(), |l| l.amount)691 .map_or(<BalanceOf<T>>::default(), |l| l.amount)
606 .ok_or(ArithmeticError::Overflow.into())694 .ok_or(ArithmeticError::Overflow.into())
607 }695 }
608696
697 /// Sets the new state of a balance locked by the pallet.
698 ///
699 /// - `staker`: staker account.
700 /// - `amount`: amount of locked funds.
609 fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {701 fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {
610 if amount.is_zero() {702 if amount.is_zero() {
611 <T::Currency as LockableCurrency<T::AccountId>>::remove_lock(LOCK_IDENTIFIER, &staker);703 <T::Currency as LockableCurrency<T::AccountId>>::remove_lock(LOCK_IDENTIFIER, &staker);
619 }711 }
620 }712 }
621713
714 /// Returns the balance locked by the pallet for the staker.
715 ///
716 /// - `staker`: staker account.
622 pub fn get_locked_balance(717 pub fn get_locked_balance(
623 staker: impl EncodeLike<T::AccountId>,718 staker: impl EncodeLike<T::AccountId>,
624 ) -> Option<BalanceLock<BalanceOf<T>>> {719 ) -> Option<BalanceLock<BalanceOf<T>>> {
627 .find(|l| l.id == LOCK_IDENTIFIER)722 .find(|l| l.id == LOCK_IDENTIFIER)
628 }723 }
629724
725 /// Returns the total staked balance for the staker.
726 ///
727 /// - `staker`: staker account.
630 pub fn total_staked_by_id(staker: impl EncodeLike<T::AccountId>) -> Option<BalanceOf<T>> {728 pub fn total_staked_by_id(staker: impl EncodeLike<T::AccountId>) -> Option<BalanceOf<T>> {
631 let staked = Staked::<T>::iter_prefix((staker,))729 let staked = Staked::<T>::iter_prefix((staker,))
632 .into_iter()730 .into_iter()
640 }738 }
641 }739 }
642740
741 /// Returns all relay block numbers when stake was made,
742 /// the amount of the stake.
743 ///
744 /// - `staker`: staker account.
643 pub fn total_staked_by_id_per_block(745 pub fn total_staked_by_id_per_block(
644 staker: impl EncodeLike<T::AccountId>,746 staker: impl EncodeLike<T::AccountId>,
645 ) -> Option<Vec<(T::BlockNumber, BalanceOf<T>)>> {747 ) -> Option<Vec<(T::BlockNumber, BalanceOf<T>)>> {
655 }757 }
656 }758 }
657759
760 /// Returns the total staked balance for the staker.
761 /// If `staker` is `None`, returns the total amount staked.
762 /// - `staker`: staker account.
658 pub fn cross_id_total_staked(staker: Option<T::CrossAccountId>) -> Option<BalanceOf<T>> {763 pub fn cross_id_total_staked(staker: Option<T::CrossAccountId>) -> Option<BalanceOf<T>> {
659 staker.map_or(Some(<TotalStaked<T>>::get()), |s| {764 staker.map_or(Some(<TotalStaked<T>>::get()), |s| {
660 Self::total_staked_by_id(s.as_sub())765 Self::total_staked_by_id(s.as_sub())
667 // .unwrap_or_default()772 // .unwrap_or_default()
668 // }773 // }
669774
775 /// Returns all relay block numbers when stake was made,
776 /// the amount of the stake.
777 ///
778 /// - `staker`: staker account.
670 pub fn cross_id_total_staked_per_block(779 pub fn cross_id_total_staked_per_block(
671 staker: T::CrossAccountId,780 staker: T::CrossAccountId,
672 ) -> Vec<(T::BlockNumber, BalanceOf<T>)> {781 ) -> Vec<(T::BlockNumber, BalanceOf<T>)> {
704 (current_relay_block / T::RecalculationInterval::get()) * T::RecalculationInterval::get()813 (current_relay_block / T::RecalculationInterval::get()) * T::RecalculationInterval::get()
705 }814 }
706
707 // fn get_next_recalc_block(current_relay_block: T::BlockNumber) -> T::BlockNumber {
708 // Self::get_current_recalc_block(current_relay_block) + T::RecalculationInterval::get()
709 // }
710815
711 fn get_next_calculated_key() -> Option<Vec<u8>> {816 fn get_next_calculated_key() -> Option<Vec<u8>> {
712 Self::get_next_calculated_record().map(|key| Staked::<T>::hashed_key_for(key))817 Self::get_next_calculated_record().map(|key| Staked::<T>::hashed_key_for(key))
717where822where
718 <<T as Config>::Currency as Currency<T::AccountId>>::Balance: Sum,823 <<T as Config>::Currency as Currency<T::AccountId>>::Balance: Sum,
719{824{
825 /// Returns the amount reserved by the pending.
826 /// If `staker` is `None`, returns the total pending.
827 ///
828 /// -`staker`: staker account.
829 ///
720 /// Since user funds are not transferred anywhere by staking, overflow protection is provided830 /// Since user funds are not transferred anywhere by staking, overflow protection is provided
721 /// at the level of the associated type `Balance` of `Currency` trait. In order to overflow,831 /// at the level of the associated type `Balance` of `Currency` trait. In order to overflow,
722 /// the staker must have more funds on his account than the maximum set for `Balance` type.832 /// the staker must have more funds on his account than the maximum set for `Balance` type.
740 )850 )
741 }851 }
742852
853 /// Returns all parachain block numbers when unreserve is expected,
854 /// the amount of the unreserved funds.
855 ///
856 /// - `staker`: staker account.
743 pub fn cross_id_pending_unstake_per_block(857 pub fn cross_id_pending_unstake_per_block(
744 staker: T::CrossAccountId,858 staker: T::CrossAccountId,
745 ) -> Vec<(T::BlockNumber, BalanceOf<T>)> {859 ) -> Vec<(T::BlockNumber, BalanceOf<T>)> {
modifiedpallets/app-promotion/src/types.rsdiffbeforeafterboth
9use sp_std::borrow::ToOwned;9use sp_std::borrow::ToOwned;
10use pallet_evm_contract_helpers::{Pallet as EvmHelpersPallet, Config as EvmHelpersConfig};10use pallet_evm_contract_helpers::{Pallet as EvmHelpersPallet, Config as EvmHelpersConfig};
1111
12/// This trait was defined because `LockableCurrency`
13/// has no way to know the state of the lock for an account.
12pub trait ExtendedLockableCurrency<AccountId: Parameter>: LockableCurrency<AccountId> {14pub trait ExtendedLockableCurrency<AccountId: Parameter>: LockableCurrency<AccountId> {
15 /// Returns lock balance for an account. Allows to determine the cause of the lock.
13 fn locks<KArg>(who: KArg) -> WeakBoundedVec<BalanceLock<Self::Balance>, Self::MaxLocks>16 fn locks<KArg>(who: KArg) -> WeakBoundedVec<BalanceLock<Self::Balance>, Self::MaxLocks>
14 where17 where
15 KArg: EncodeLike<AccountId>;18 KArg: EncodeLike<AccountId>;
25 Self::locks(who)28 Self::locks(who)
26 }29 }
27}30}
2831/// Trait for interacting with collections.
29pub trait CollectionHandler {32pub trait CollectionHandler {
30 type CollectionId;33 type CollectionId;
31 type AccountId;34 type AccountId;
3235
36 /// Sets sponsor for a collection.
37 ///
38 /// - `sponsor_id`: the account of the sponsor-to-be.
39 /// - `collection_id`: ID of the modified collection.
33 fn set_sponsor(40 fn set_sponsor(
34 sponsor_id: Self::AccountId,41 sponsor_id: Self::AccountId,
35 collection_id: Self::CollectionId,42 collection_id: Self::CollectionId,
36 ) -> DispatchResult;43 ) -> DispatchResult;
3744
45 /// Removes sponsor for a collection.
46 ///
47 /// - `collection_id`: ID of the modified collection.
38 fn remove_collection_sponsor(collection_id: Self::CollectionId) -> DispatchResult;48 fn remove_collection_sponsor(collection_id: Self::CollectionId) -> DispatchResult;
3949
50 /// Retuns the current sponsor for a collection if one is set.
51 ///
52 /// - `collection_id`: ID of the collection.
40 fn sponsor(collection_id: Self::CollectionId)53 fn sponsor(collection_id: Self::CollectionId)
41 -> Result<Option<Self::AccountId>, DispatchError>;54 -> Result<Option<Self::AccountId>, DispatchError>;
42}55}
66 .map(|acc| acc.to_owned()))79 .map(|acc| acc.to_owned()))
67 }80 }
68}81}
6982/// Trait for interacting with contracts.
70pub trait ContractHandler {83pub trait ContractHandler {
71 type ContractId;84 type ContractId;
72 type AccountId;85 type AccountId;
7386
87 /// Sets sponsor for a contract.
88 ///
89 /// - `sponsor_id`: the account of the sponsor-to-be.
90 /// - `contract_address`: the address of the modified contract.
74 fn set_sponsor(91 fn set_sponsor(
75 sponsor_id: Self::AccountId,92 sponsor_id: Self::AccountId,
76 contract_address: Self::ContractId,93 contract_address: Self::ContractId,
77 ) -> DispatchResult;94 ) -> DispatchResult;
7895
96 /// Removes sponsor for a contract.
97 ///
98 /// - `contract_address`: the address of the modified contract.
79 fn remove_contract_sponsor(contract_address: Self::ContractId) -> DispatchResult;99 fn remove_contract_sponsor(contract_address: Self::ContractId) -> DispatchResult;
80100
101 /// Retuns the current sponsor for a contract if one is set.
102 ///
103 /// - `contract_address`: the contract address.
81 fn sponsor(104 fn sponsor(
82 contract_address: Self::ContractId,105 contract_address: Self::ContractId,
83 ) -> Result<Option<Self::AccountId>, DispatchError>;106 ) -> Result<Option<Self::AccountId>, DispatchError>;
modifiedpallets/common/Cargo.tomldiffbeforeafterboth
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
20fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }20fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
22pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }22pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
23evm-coder = { default-features = false, path = '../../crates/evm-coder' }23evm-coder = { default-features = false, path = '../../crates/evm-coder' }
24ethereum = { version = "0.12.0", default-features = false }24ethereum = { version = "0.12.0", default-features = false }
25pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }25pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2626
27serde = { version = "1.0.130", default-features = false }27serde = { version = "1.0.130", default-features = false }
28scale-info = { version = "2.0.1", default-features = false, features = [28scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
20 solidity_interface, solidity, ToLog,20 solidity_interface, solidity, ToLog,
21 types::*,21 types::*,
22 execution::{Result, Error},22 execution::{Result, Error},
23 weight,
23};24};
24pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};25pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
25use pallet_evm_coder_substrate::dispatch_to_evm;26use pallet_evm_coder_substrate::dispatch_to_evm;
31use alloc::format;32use alloc::format;
3233
33use crate::{34use crate::{
34 Pallet, CollectionHandle, Config, CollectionProperties,35 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
35 eth::{convert_cross_account_to_uint256, convert_uint256_to_cross_account},36 eth::{
37 convert_cross_account_to_uint256, convert_uint256_to_cross_account,
38 convert_cross_account_to_tuple,
39 },
40 weights::WeightInfo,
36};41};
3742
38/// Events for ethereum collection helper.43/// Events for ethereum collection helper.
69 ///74 ///
70 /// @param key Property key.75 /// @param key Property key.
71 /// @param value Propery value.76 /// @param value Propery value.
77 #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]
72 fn set_collection_property(78 fn set_collection_property(
73 &mut self,79 &mut self,
74 caller: caller,80 caller: caller,
88 /// Delete collection property.94 /// Delete collection property.
89 ///95 ///
90 /// @param key Property key.96 /// @param key Property key.
97 #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]
91 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {98 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {
99 self.consume_store_reads_and_writes(1, 1)?;
100
92 let caller = T::CrossAccountId::from_eth(caller);101 let caller = T::CrossAccountId::from_eth(caller);
93 let key = <Vec<u8>>::from(key)102 let key = <Vec<u8>>::from(key)
94 .try_into()103 .try_into()
120 ///129 ///
121 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.130 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
122 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {131 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
132 self.consume_store_reads_and_writes(1, 1)?;
133
123 check_is_owner_or_admin(caller, self)?;134 check_is_owner_or_admin(caller, self)?;
124135
125 let sponsor = T::CrossAccountId::from_eth(sponsor);136 let sponsor = T::CrossAccountId::from_eth(sponsor);
138 caller: caller,149 caller: caller,
139 sponsor: uint256,150 sponsor: uint256,
140 ) -> Result<void> {151 ) -> Result<void> {
152 self.consume_store_reads_and_writes(1, 1)?;
153
141 check_is_owner_or_admin(caller, self)?;154 check_is_owner_or_admin(caller, self)?;
142155
143 let sponsor = convert_uint256_to_cross_account::<T>(sponsor);156 let sponsor = convert_uint256_to_cross_account::<T>(sponsor);
146 save(self)159 save(self)
147 }160 }
148161
149 // /// Whether there is a pending sponsor.162 /// Whether there is a pending sponsor.
150 fn has_collection_pending_sponsor(&self) -> Result<bool> {163 fn has_collection_pending_sponsor(&self) -> Result<bool> {
151 Ok(matches!(164 Ok(matches!(
152 self.collection.sponsorship,165 self.collection.sponsorship,
158 ///171 ///
159 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.172 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.
160 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {173 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {
174 self.consume_store_writes(1)?;
175
161 let caller = T::CrossAccountId::from_eth(caller);176 let caller = T::CrossAccountId::from_eth(caller);
162 if !self177 if !self
163 .confirm_sponsorship(caller.as_sub())178 .confirm_sponsorship(caller.as_sub())
170185
171 /// Remove collection sponsor.186 /// Remove collection sponsor.
172 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {187 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {
188 self.consume_store_reads_and_writes(1, 1)?;
173 check_is_owner_or_admin(caller, self)?;189 check_is_owner_or_admin(caller, self)?;
174 self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;190 self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;
175 save(self)191 save(self)
206 /// @param value Value of the limit.222 /// @param value Value of the limit.
207 #[solidity(rename_selector = "setCollectionLimit")]223 #[solidity(rename_selector = "setCollectionLimit")]
208 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {224 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {
225 self.consume_store_reads_and_writes(1, 1)?;
226
209 check_is_owner_or_admin(caller, self)?;227 check_is_owner_or_admin(caller, self)?;
210 let mut limits = self.limits.clone();228 let mut limits = self.limits.clone();
211229
249 /// @param value Value of the limit.267 /// @param value Value of the limit.
250 #[solidity(rename_selector = "setCollectionLimit")]268 #[solidity(rename_selector = "setCollectionLimit")]
251 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {269 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {
270 self.consume_store_reads_and_writes(1, 1)?;
271
252 check_is_owner_or_admin(caller, self)?;272 check_is_owner_or_admin(caller, self)?;
253 let mut limits = self.limits.clone();273 let mut limits = self.limits.clone();
254274
275 }295 }
276296
277 /// Get contract address.297 /// Get contract address.
278 fn contract_address(&self, _caller: caller) -> Result<address> {298 fn contract_address(&self) -> Result<address> {
279 Ok(crate::eth::collection_id_to_address(self.id))299 Ok(crate::eth::collection_id_to_address(self.id))
280 }300 }
281301
286 caller: caller,306 caller: caller,
287 new_admin: uint256,307 new_admin: uint256,
288 ) -> Result<void> {308 ) -> Result<void> {
309 self.consume_store_writes(2)?;
310
289 let caller = T::CrossAccountId::from_eth(caller);311 let caller = T::CrossAccountId::from_eth(caller);
290 let new_admin = convert_uint256_to_cross_account::<T>(new_admin);312 let new_admin = convert_uint256_to_cross_account::<T>(new_admin);
291 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
299 caller: caller,321 caller: caller,
300 admin: uint256,322 admin: uint256,
301 ) -> Result<void> {323 ) -> Result<void> {
324 self.consume_store_writes(2)?;
325
302 let caller = T::CrossAccountId::from_eth(caller);326 let caller = T::CrossAccountId::from_eth(caller);
303 let admin = convert_uint256_to_cross_account::<T>(admin);327 let admin = convert_uint256_to_cross_account::<T>(admin);
304 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;328 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
308 /// Add collection admin.332 /// Add collection admin.
309 /// @param newAdmin Address of the added administrator.333 /// @param newAdmin Address of the added administrator.
310 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {334 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {
335 self.consume_store_writes(2)?;
336
311 let caller = T::CrossAccountId::from_eth(caller);337 let caller = T::CrossAccountId::from_eth(caller);
312 let new_admin = T::CrossAccountId::from_eth(new_admin);338 let new_admin = T::CrossAccountId::from_eth(new_admin);
313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;339 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
318 ///344 ///
319 /// @param admin Address of the removed administrator.345 /// @param admin Address of the removed administrator.
320 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {346 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {
347 self.consume_store_writes(2)?;
348
321 let caller = T::CrossAccountId::from_eth(caller);349 let caller = T::CrossAccountId::from_eth(caller);
322 let admin = T::CrossAccountId::from_eth(admin);350 let admin = T::CrossAccountId::from_eth(admin);
323 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;351 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
329 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'357 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
330 #[solidity(rename_selector = "setCollectionNesting")]358 #[solidity(rename_selector = "setCollectionNesting")]
331 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {359 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {
360 self.consume_store_reads_and_writes(1, 1)?;
361
332 check_is_owner_or_admin(caller, self)?;362 check_is_owner_or_admin(caller, self)?;
333363
334 let mut permissions = self.collection.permissions.clone();364 let mut permissions = self.collection.permissions.clone();
358 enable: bool,388 enable: bool,
359 collections: Vec<address>,389 collections: Vec<address>,
360 ) -> Result<void> {390 ) -> Result<void> {
391 self.consume_store_reads_and_writes(1, 1)?;
392
361 if collections.is_empty() {393 if collections.is_empty() {
362 return Err("no addresses provided".into());394 return Err("no addresses provided".into());
363 }395 }
401 /// 0 for Normal433 /// 0 for Normal
402 /// 1 for AllowList434 /// 1 for AllowList
403 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {435 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {
436 self.consume_store_reads_and_writes(1, 1)?;
437
404 check_is_owner_or_admin(caller, self)?;438 check_is_owner_or_admin(caller, self)?;
405 let permissions = CollectionPermissions {439 let permissions = CollectionPermissions {
406 access: Some(match mode {440 access: Some(match mode {
420 save(self)454 save(self)
421 }455 }
422456
457 /// Checks that user allowed to operate with collection.
458 ///
459 /// @param user User address to check.
460 fn allowed(&self, user: address) -> Result<bool> {
461 Ok(Pallet::<T>::allowed(
462 self.id,
463 T::CrossAccountId::from_eth(user),
464 ))
465 }
466
423 /// Add the user to the allowed list.467 /// Add the user to the allowed list.
424 ///468 ///
425 /// @param user Address of a trusted user.469 /// @param user Address of a trusted user.
426 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {470 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
471 self.consume_store_writes(1)?;
472
427 let caller = T::CrossAccountId::from_eth(caller);473 let caller = T::CrossAccountId::from_eth(caller);
428 let user = T::CrossAccountId::from_eth(user);474 let user = T::CrossAccountId::from_eth(user);
429 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;475 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
430 Ok(())476 Ok(())
431 }477 }
432478
479 /// Add substrate user to allowed list.
480 ///
481 /// @param user User substrate address.
482 fn add_to_collection_allow_list_substrate(
483 &mut self,
484 caller: caller,
485 user: uint256,
486 ) -> Result<void> {
487 self.consume_store_writes(1)?;
488
489 let caller = T::CrossAccountId::from_eth(caller);
490 let user = convert_uint256_to_cross_account::<T>(user);
491 Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
492 Ok(())
493 }
494
433 /// Remove the user from the allowed list.495 /// Remove the user from the allowed list.
434 ///496 ///
435 /// @param user Address of a removed user.497 /// @param user Address of a removed user.
436 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {498 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
499 self.consume_store_writes(1)?;
500
437 let caller = T::CrossAccountId::from_eth(caller);501 let caller = T::CrossAccountId::from_eth(caller);
438 let user = T::CrossAccountId::from_eth(user);502 let user = T::CrossAccountId::from_eth(user);
439 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;503 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
440 Ok(())504 Ok(())
441 }505 }
442506
507 /// Remove substrate user from allowed list.
508 ///
509 /// @param user User substrate address.
510 fn remove_from_collection_allow_list_substrate(
511 &mut self,
512 caller: caller,
513 user: uint256,
514 ) -> Result<void> {
515 self.consume_store_writes(1)?;
516
517 let caller = T::CrossAccountId::from_eth(caller);
518 let user = convert_uint256_to_cross_account::<T>(user);
519 Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
520 Ok(())
521 }
522
443 /// Switch permission for minting.523 /// Switch permission for minting.
444 ///524 ///
445 /// @param mode Enable if "true".525 /// @param mode Enable if "true".
446 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {526 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {
527 self.consume_store_reads_and_writes(1, 1)?;
528
447 check_is_owner_or_admin(caller, self)?;529 check_is_owner_or_admin(caller, self)?;
448 let permissions = CollectionPermissions {530 let permissions = CollectionPermissions {
449 mint_mode: Some(mode),531 mint_mode: Some(mode),
481 /// Returns collection type563 /// Returns collection type
482 ///564 ///
483 /// @return `Fungible` or `NFT` or `ReFungible`565 /// @return `Fungible` or `NFT` or `ReFungible`
484 fn unique_collection_type(&mut self) -> Result<string> {566 fn unique_collection_type(&self) -> Result<string> {
485 let mode = match self.collection.mode {567 let mode = match self.collection.mode {
486 CollectionMode::Fungible(_) => "Fungible",568 CollectionMode::Fungible(_) => "Fungible",
487 CollectionMode::NFT => "NFT",569 CollectionMode::NFT => "NFT",
490 Ok(mode.into())572 Ok(mode.into())
491 }573 }
492574
575 /// Get collection owner.
576 ///
577 /// @return Tuble with sponsor address and his substrate mirror.
578 /// If address is canonical then substrate mirror is zero and vice versa.
579 fn collection_owner(&self) -> Result<(address, uint256)> {
580 Ok(convert_cross_account_to_tuple::<T>(
581 &T::CrossAccountId::from_sub(self.owner.clone()),
582 ))
583 }
584
493 /// Changes collection owner to another account585 /// Changes collection owner to another account
494 ///586 ///
495 /// @dev Owner can be changed only by current owner587 /// @dev Owner can be changed only by current owner
496 /// @param newOwner new owner account588 /// @param newOwner new owner account
497 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {589 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
590 self.consume_store_writes(1)?;
591
498 let caller = T::CrossAccountId::from_eth(caller);592 let caller = T::CrossAccountId::from_eth(caller);
499 let new_owner = T::CrossAccountId::from_eth(new_owner);593 let new_owner = T::CrossAccountId::from_eth(new_owner);
500 self.set_owner_internal(caller, new_owner)594 self.set_owner_internal(caller, new_owner)
506 /// @dev Owner can be changed only by current owner600 /// @dev Owner can be changed only by current owner
507 /// @param newOwner new owner substrate account601 /// @param newOwner new owner substrate account
508 fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {602 fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {
603 self.consume_store_writes(1)?;
604
509 let caller = T::CrossAccountId::from_eth(caller);605 let caller = T::CrossAccountId::from_eth(caller);
510 let new_owner = convert_uint256_to_cross_account::<T>(new_owner);606 let new_owner = convert_uint256_to_cross_account::<T>(new_owner);
511 self.set_owner_internal(caller, new_owner)607 self.set_owner_internal(caller, new_owner)
512 .map_err(dispatch_to_evm::<T>)608 .map_err(dispatch_to_evm::<T>)
513 }609 }
610
611 // TODO: need implement AbiWriter for &Vec<T>
612 // fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
613 // let result = pallet_common::IsAdmin::<T>::iter_prefix((self.id,))
614 // .map(|(admin, _)| pallet_common::eth::convert_cross_account_to_tuple::<T>(&admin))
615 // .collect();
616 // Ok(result)
617 // }
514}618}
515619
620/// ### Note
621/// Do not forget to add: `self.consume_store_reads(1)?;`
516fn check_is_owner_or_admin<T: Config>(622fn check_is_owner_or_admin<T: Config>(
517 caller: caller,623 caller: caller,
518 collection: &CollectionHandle<T>,624 collection: &CollectionHandle<T>,
524 Ok(caller)630 Ok(caller)
525}631}
526632
633/// ### Note
634/// Do not forget to add: `self.consume_store_writes(1)?;`
527fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {635fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {
528 // TODO possibly delete for the lack of transaction
529 collection.consume_store_writes(1)?;
530 collection636 collection
531 .check_is_internal()637 .check_is_internal()
532 .map_err(dispatch_to_evm::<T>)?;638 .map_err(dispatch_to_evm::<T>)?;
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
1616
17//! The module contains a number of functions for converting and checking ethereum identifiers.17//! The module contains a number of functions for converting and checking ethereum identifiers.
1818
19use evm_coder::types::uint256;19use evm_coder::types::{uint256, address};
20pub use pallet_evm::account::{Config, CrossAccountId};20pub use pallet_evm::account::{Config, CrossAccountId};
21use sp_core::H160;21use sp_core::H160;
22use up_data_structs::CollectionId;22use up_data_structs::CollectionId;
70 T::CrossAccountId::from_sub(account_id)70 T::CrossAccountId::from_sub(account_id)
71}71}
72
73/// Convert `CrossAccountId` to `(address, uint256)`.
74pub fn convert_cross_account_to_tuple<T: Config>(
75 cross_account_id: &T::CrossAccountId,
76) -> (address, uint256)
77where
78 T::AccountId: AsRef<[u8; 32]>,
79{
80 if cross_account_id.is_canonical_substrate() {
81 let sub = convert_cross_account_to_uint256::<T>(cross_account_id);
82 (Default::default(), sub)
83 } else {
84 let eth = *cross_account_id.as_eth();
85 (eth, Default::default())
86 }
87}
7288
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
112 RmrkBoundedTheme,112 RmrkBoundedTheme,
113 RmrkNftChild,113 RmrkNftChild,
114 CollectionPermissions,114 CollectionPermissions,
115 SchemaVersion,
116};115};
117116
118pub use pallet::*;117pub use pallet::*;
202 ))201 ))
203 }202 }
203
204 /// Consume gas for reading and writing.
205 pub fn consume_store_reads_and_writes(
206 &self,
207 reads: u64,
208 writes: u64,
209 ) -> evm_coder::execution::Result<()> {
210 let weight = <T as frame_system::Config>::DbWeight::get();
211 let reads = weight.read.saturating_mul(reads);
212 let writes = weight.read.saturating_mul(writes);
213 self.recorder
214 .consume_gas(T::GasWeightMapping::weight_to_gas(
215 reads.saturating_add(writes),
216 ))
217 }
204218
205 /// Save collection to storage.219 /// Save collection to storage.
206 pub fn save(&self) -> DispatchResult {220 pub fn save(&self) -> DispatchResult {
310 }324 }
311325
312 /// Changes collection owner to another account326 /// Changes collection owner to another account
327 /// #### Store read/writes
328 /// 1 writes
313 fn set_owner_internal(329 fn set_owner_internal(
314 &mut self,330 &mut self,
315 caller: T::CrossAccountId,331 caller: T::CrossAccountId,
1292 }1308 }
12931309
1294 /// Toggle `user` participation in the `collection`'s allow list.1310 /// Toggle `user` participation in the `collection`'s allow list.
1311 /// #### Store read/writes
1312 /// 1 writes
1295 pub fn toggle_allowlist(1313 pub fn toggle_allowlist(
1296 collection: &CollectionHandle<T>,1314 collection: &CollectionHandle<T>,
1297 sender: &T::CrossAccountId,1315 sender: &T::CrossAccountId,
1312 }1330 }
13131331
1314 /// Toggle `user` participation in the `collection`'s admin list.1332 /// Toggle `user` participation in the `collection`'s admin list.
1333 /// #### Store read/writes
1334 /// 2 writes
1315 pub fn toggle_admin(1335 pub fn toggle_admin(
1316 collection: &CollectionHandle<T>,1336 collection: &CollectionHandle<T>,
1317 sender: &T::CrossAccountId,1337 sender: &T::CrossAccountId,
modifiedpallets/configuration/Cargo.tomldiffbeforeafterboth
16sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20smallvec = "1.6.1"20smallvec = "1.6.1"
2121
22[features]22[features]
modifiedpallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth
12sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }12sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
13ethereum = { version = "0.12.0", default-features = false }13ethereum = { version = "0.12.0", default-features = false }
14evm-coder = { default-features = false, path = "../../crates/evm-coder" }14evm-coder = { default-features = false, path = "../../crates/evm-coder" }
15pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }15pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
16pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }16pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
17frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
modifiedpallets/evm-contract-helpers/CHANGELOG.mddiffbeforeafterboth
22
3All notable changes to this project will be documented in this file.3All notable changes to this project will be documented in this file.
44
5## [v0.3.0] 2022-09-05
6
7### Added
8
9- Methods `force_set_sponsor` , `force_remove_sponsor` to be able to administer sponsorships with other pallets. Added to implement `AppPromotion` pallet logic.
10
5## [v0.2.0] - 2022-08-1911## [v0.2.0] - 2022-08-19
612
7### Added13### Added
814
9 - Set arbitrary evm address as contract sponsor.15- Set arbitrary evm address as contract sponsor.
10 - Ability to remove current sponsor.16- Ability to remove current sponsor.
1117
12### Removed18### Removed
13 - Remove methods
14 + sponsoring_enabled
15 + toggle_sponsoring
1619
17 ### Changed20- Remove methods
21 - sponsoring_enabled
22 - toggle_sponsoring
1823
19 - Change `toggle_sponsoring` to `self_sponsored_enable`.24### Changed
2025
26- Change `toggle_sponsoring` to `self_sponsored_enable`.
2127
22## [v0.1.2] 2022-08-1628## [v0.1.2] 2022-08-16
2329
24### Other changes30### Other changes
2531
26- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a32- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
2733
28- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf834- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
2935
30- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b36- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
37
modifiedpallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "pallet-evm-contract-helpers"2name = "pallet-evm-contract-helpers"
3version = "0.2.0"3version = "0.3.0"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
2020
21# Unique21# Unique
22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
23fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }23fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
24up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }24up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
2525
26# Locals26# Locals
27evm-coder = { default-features = false, path = '../../crates/evm-coder' }27evm-coder = { default-features = false, path = '../../crates/evm-coder' }
28pallet-common = { default-features = false, path = '../../pallets/common' }28pallet-common = { default-features = false, path = '../../pallets/common' }
29pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }29pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
30pallet-evm-transaction-payment = { default-features = false, path = '../../pallets/evm-transaction-payment' }
30up-data-structs = { default-features = false, path = '../../primitives/data-structs', features = [31up-data-structs = { default-features = false, path = '../../primitives/data-structs', features = [
31 'serde1',32 'serde1',
32] }33] }
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
20use evm_coder::{20use evm_coder::{
21 abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*, ToLog,21 abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*, ToLog,
22};22};
23use pallet_evm::{
24 ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
25 account::CrossAccountId,
26};
23use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};27use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};
24use pallet_evm::{28use pallet_evm_transaction_payment::CallContext;
25 ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
26 account::CrossAccountId,
27};
28use sp_core::H160;29use sp_core::{H160, U256};
29use up_data_structs::SponsorshipState;30use up_data_structs::SponsorshipState;
30use crate::{31use crate::{
31 AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringRateLimit, SponsoringModeT,32 AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringFeeLimit,
32 Sponsoring,33 SponsoringRateLimit, SponsoringModeT, Sponsoring,
33};34};
34use frame_support::traits::Get;35use frame_support::traits::Get;
171 fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {172 fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {
172 let sponsor =173 let sponsor =
173 Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;174 Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;
174 let result: (address, uint256) = if sponsor.is_canonical_substrate() {
175 let sponsor = pallet_common::eth::convert_cross_account_to_uint256::<T>(&sponsor);175 Ok(pallet_common::eth::convert_cross_account_to_tuple::<T>(
176 (Default::default(), sponsor)176 &sponsor,
177 } else {177 ))
178 let sponsor = *sponsor.as_eth();
179 (sponsor, Default::default())
180 };
181 Ok(result)
182 }178 }
183179
184 /// Check tat contract has confirmed sponsor.180 /// Check tat contract has confirmed sponsor.
222 }218 }
223219
224 /// Get current contract sponsoring rate limit220 /// Get current contract sponsoring rate limit
225 /// @param contractAddress Contract to get sponsoring mode of221 /// @param contractAddress Contract to get sponsoring rate limit of
226 /// @return uint32 Amount of blocks between two sponsored transactions222 /// @return uint32 Amount of blocks between two sponsored transactions
227 fn get_sponsoring_rate_limit(&self, contract_address: address) -> Result<uint32> {223 fn get_sponsoring_rate_limit(&self, contract_address: address) -> Result<uint32> {
224 self.recorder().consume_sload()?;
225
228 Ok(<SponsoringRateLimit<T>>::get(contract_address)226 Ok(<SponsoringRateLimit<T>>::get(contract_address)
229 .try_into()227 .try_into()
250 Ok(())248 Ok(())
251 }249 }
250
251 /// Set contract sponsoring fee limit
252 /// @dev Sponsoring fee limit - is maximum fee that could be spent by
253 /// single transaction
254 /// @param contractAddress Contract to change sponsoring fee limit of
255 /// @param feeLimit Fee limit
256 /// @dev Only contract owner can change this setting
257 fn set_sponsoring_fee_limit(
258 &mut self,
259 caller: caller,
260 contract_address: address,
261 fee_limit: uint256,
262 ) -> Result<void> {
263 self.recorder().consume_sload()?;
264 self.recorder().consume_sstore()?;
265
266 <Pallet<T>>::ensure_owner(contract_address, caller).map_err(dispatch_to_evm::<T>)?;
267 <Pallet<T>>::set_sponsoring_fee_limit(contract_address, fee_limit.into())
268 .map_err(dispatch_to_evm::<T>)?;
269 Ok(())
270 }
271
272 /// Get current contract sponsoring fee limit
273 /// @param contractAddress Contract to get sponsoring fee limit of
274 /// @return uint256 Maximum amount of fee that could be spent by single
275 /// transaction
276 fn get_sponsoring_fee_limit(&self, contract_address: address) -> Result<uint256> {
277 self.recorder().consume_sload()?;
278
279 Ok(get_sponsoring_fee_limit::<T>(contract_address))
280 }
252281
253 /// Is specified user present in contract allow list282 /// Is specified user present in contract allow list
254 /// @dev Contract owner always implicitly included283 /// @dev Contract owner always implicitly included
363392
364/// Bridge to pallet-sponsoring393/// Bridge to pallet-sponsoring
365pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);394pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);
366impl<T: Config> SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)>395impl<T: Config> SponsorshipHandler<T::CrossAccountId, CallContext>
367 for HelpersContractSponsoring<T>396 for HelpersContractSponsoring<T>
368{397{
369 fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {398 fn get_sponsor(
399 who: &T::CrossAccountId,
400 call_context: &CallContext,
401 ) -> Option<T::CrossAccountId> {
370 let (contract_address, _) = call;402 let contract_address = call_context.contract_address;
371 let mode = <Pallet<T>>::sponsoring_mode(*contract_address);403 let mode = <Pallet<T>>::sponsoring_mode(contract_address);
372 if mode == SponsoringModeT::Disabled {404 if mode == SponsoringModeT::Disabled {
373 return None;405 return None;
374 }406 }
375407
376 let sponsor = match <Pallet<T>>::get_sponsor(*contract_address) {408 let sponsor = match <Pallet<T>>::get_sponsor(contract_address) {
377 Some(sponsor) => sponsor,409 Some(sponsor) => sponsor,
378 None => return None,410 None => return None,
379 };411 };
380412
381 if mode == SponsoringModeT::Allowlisted413 if mode == SponsoringModeT::Allowlisted
382 && !<Pallet<T>>::allowed(*contract_address, *who.as_eth())414 && !<Pallet<T>>::allowed(contract_address, *who.as_eth())
383 {415 {
384 return None;416 return None;
385 }417 }
394 }426 }
395 }427 }
428
429 let sponsored_fee_limit = get_sponsoring_fee_limit::<T>(contract_address);
430
431 if call_context.max_fee > sponsored_fee_limit {
432 return None;
433 }
396434
397 <SponsorBasket<T>>::insert(contract_address, who.as_eth(), block_number);435 <SponsorBasket<T>>::insert(contract_address, who.as_eth(), block_number);
398436
399 Some(sponsor)437 Some(sponsor)
400 }438 }
401}439}
440
441fn get_sponsoring_fee_limit<T: Config>(contract_address: address) -> uint256 {
442 <SponsoringFeeLimit<T>>::get(contract_address)
443 .get(&0xffffffff)
444 .cloned()
445 .unwrap_or(U256::MAX)
446}
402447
403generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true);448generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true);
404generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false);449generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false);
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
22pub use pallet::*;22pub use pallet::*;
23pub use eth::*;23pub use eth::*;
24use scale_info::TypeInfo;24use scale_info::TypeInfo;
25use frame_support::storage::bounded_btree_map::BoundedBTreeMap;
25pub mod eth;26pub mod eth;
27
28/// Maximum number of methods per contract that could have fee limit
29pub const MAX_FEE_LIMITED_METHODS: u32 = 5;
2630
27#[frame_support::pallet]31#[frame_support::pallet]
28pub mod pallet {32pub mod pallet {
29 pub use super::*;33 pub use super::*;
30 use crate::eth::ContractHelpersEvents;34 use crate::eth::ContractHelpersEvents;
31 use frame_support::pallet_prelude::*;35 use frame_support::pallet_prelude::*;
32 use pallet_evm_coder_substrate::DispatchResult;36 use pallet_evm_coder_substrate::DispatchResult;
33 use sp_core::H160;37 use sp_core::{H160, U256};
34 use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};38 use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
35 use up_data_structs::SponsorshipState;39 use up_data_structs::SponsorshipState;
36 use evm_coder::ToLog;40 use evm_coder::ToLog;
58 /// No pending sponsor for contract.62 /// No pending sponsor for contract.
59 NoPendingSponsor,63 NoPendingSponsor,
64
65 /// Number of methods that sponsored limit is defined for exceeds maximum.
66 TooManyMethodsHaveSponsoredLimit,
60 }67 }
6168
62 #[pallet::pallet]69 #[pallet::pallet]
118 /// * **Key2** - sponsored user address.125 /// * **Key2** - sponsored user address.
119 /// * **Value** - last sponsored block number.126 /// * **Value** - last sponsored block number.
120 #[pallet::storage]127 #[pallet::storage]
121 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<128 pub(super) type SponsoringFeeLimit<T: Config> = StorageMap<
129 Hasher = Twox128,
130 Key = H160,
131 Value = BoundedBTreeMap<u32, U256, ConstU32<MAX_FEE_LIMITED_METHODS>>,
132 QueryKind = ValueQuery,
133 >;
134
135 #[pallet::storage]
136 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<
122 Hasher1 = Twox128,137 Hasher1 = Twox128,
123 Key1 = H160,138 Key1 = H160,
124 Hasher2 = Twox128,139 Hasher2 = Twox128,
216 Ok(())231 Ok(())
217 }232 }
218233
219 /// TO-DO234 /// Force set `sponsor` for `contract`.
220 ///235 ///
221 ///236 /// Differs from `set_sponsor` in that confirmation
237 /// from the sponsor is not required.
222 pub fn force_set_sponsor(238 pub fn force_set_sponsor(
223 contract_address: H160,239 contract_address: H160,
224 sponsor: &T::CrossAccountId,240 sponsor: &T::CrossAccountId,
269 Self::force_remove_sponsor(contract_address)285 Self::force_remove_sponsor(contract_address)
270 }286 }
271287
272 /// TO-DO288 /// Force remove `sponsor` for `contract`.
273 ///289 ///
274 ///290 /// Differs from `remove_sponsor` in that
291 /// it doesn't require consent from the `owner` of the contract.
275 pub fn force_remove_sponsor(contract_address: H160) -> DispatchResult {292 pub fn force_remove_sponsor(contract_address: H160) -> DispatchResult {
276 Sponsoring::<T>::remove(contract_address);293 Sponsoring::<T>::remove(contract_address);
277294
353 <SponsoringRateLimit<T>>::insert(contract, rate_limit);370 <SponsoringRateLimit<T>>::insert(contract, rate_limit);
354 }371 }
372
373 /// Set maximum for gas limit of transaction
374 pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) -> DispatchResult {
375 <SponsoringFeeLimit<T>>::try_mutate(contract, |limits_map| {
376 limits_map
377 .try_insert(0xffffffff, fee_limit)
378 .map_err(|_| <Error<T>>::TooManyMethodsHaveSponsoredLimit)
379 })?;
380 Ok(())
381 }
355382
356 /// Is user added to allowlist, or he is owner of specified contract383 /// Is user added to allowlist, or he is owner of specified contract
357 pub fn allowed(contract: H160, user: H160) -> bool {384 pub fn allowed(contract: H160, user: H160) -> bool {
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
32}32}
3333
34/// @title Magic contract, which allows users to reconfigure other contracts34/// @title Magic contract, which allows users to reconfigure other contracts
35/// @dev the ERC-165 identifier for this interface is 0xd77fab7035/// @dev the ERC-165 identifier for this interface is 0x172cb4fb
36contract ContractHelpers is Dummy, ERC165, ContractHelpersEvents {36contract ContractHelpers is Dummy, ERC165, ContractHelpersEvents {
37 /// Get user, which deployed specified contract37 /// Get user, which deployed specified contract
38 /// @dev May return zero address in case if contract is deployed38 /// @dev May return zero address in case if contract is deployed
171 }171 }
172172
173 /// Get current contract sponsoring rate limit173 /// Get current contract sponsoring rate limit
174 /// @param contractAddress Contract to get sponsoring mode of174 /// @param contractAddress Contract to get sponsoring rate limit of
175 /// @return uint32 Amount of blocks between two sponsored transactions175 /// @return uint32 Amount of blocks between two sponsored transactions
176 /// @dev EVM selector for this function is: 0x610cfabd,176 /// @dev EVM selector for this function is: 0x610cfabd,
177 /// or in textual repr: getSponsoringRateLimit(address)177 /// or in textual repr: getSponsoringRateLimit(address)
203 dummy = 0;203 dummy = 0;
204 }204 }
205
206 /// Set contract sponsoring fee limit
207 /// @dev Sponsoring fee limit - is maximum fee that could be spent by
208 /// single transaction
209 /// @param contractAddress Contract to change sponsoring fee limit of
210 /// @param feeLimit Fee limit
211 /// @dev Only contract owner can change this setting
212 /// @dev EVM selector for this function is: 0x03aed665,
213 /// or in textual repr: setSponsoringFeeLimit(address,uint256)
214 function setSponsoringFeeLimit(address contractAddress, uint256 feeLimit)
215 public
216 {
217 require(false, stub_error);
218 contractAddress;
219 feeLimit;
220 dummy = 0;
221 }
222
223 /// Get current contract sponsoring fee limit
224 /// @param contractAddress Contract to get sponsoring fee limit of
225 /// @return uint256 Maximum amount of fee that could be spent by single
226 /// transaction
227 /// @dev EVM selector for this function is: 0xc3fdc9ee,
228 /// or in textual repr: getSponsoringFeeLimit(address)
229 function getSponsoringFeeLimit(address contractAddress)
230 public
231 view
232 returns (uint256)
233 {
234 require(false, stub_error);
235 contractAddress;
236 dummy;
237 return 0;
238 }
205239
206 /// Is specified user present in contract allow list240 /// Is specified user present in contract allow list
207 /// @dev Contract owner always implicitly included241 /// @dev Contract owner always implicitly included
modifiedpallets/evm-migration/Cargo.tomldiffbeforeafterboth
15sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }18pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2020
21[dependencies.codec]21[dependencies.codec]
22default-features = false22default-features = false
modifiedpallets/evm-transaction-payment/Cargo.tomldiffbeforeafterboth
14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
15sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
18fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }18fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
19pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }20up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
21fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }21fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2222
23[dependencies.codec]23[dependencies.codec]
24default-features = false24default-features = false
modifiedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth
22use fp_evm::WithdrawReason;22use fp_evm::WithdrawReason;
23use frame_support::traits::IsSubType;23use frame_support::traits::IsSubType;
24pub use pallet::*;24pub use pallet::*;
25use pallet_evm::{EnsureAddressOrigin, account::CrossAccountId};25use pallet_evm::{account::CrossAccountId, EnsureAddressOrigin};
26use sp_core::H160;26use sp_core::{H160, U256};
27use sp_runtime::{TransactionOutcome, DispatchError};27use sp_runtime::{TransactionOutcome, DispatchError};
28use up_sponsorship::SponsorshipHandler;28use up_sponsorship::SponsorshipHandler;
2929
3333
34 use sp_std::vec::Vec;34 use sp_std::vec::Vec;
35
36 /// Contains call data
37 pub struct CallContext {
38 /// Contract address
39 pub contract_address: H160,
40 /// Transaction data
41 pub input: Vec<u8>,
42 /// Max fee for transaction - gasLimit * gasPrice
43 pub max_fee: U256,
44 }
3545
36 #[pallet::config]46 #[pallet::config]
37 pub trait Config: frame_system::Config + pallet_evm::account::Config {47 pub trait Config: frame_system::Config + pallet_evm::account::Config {
38 /// Loosly-coupled handlers for evm call sponsoring48 /// Loosly-coupled handlers for evm call sponsoring
39 type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, (H160, Vec<u8>)>;49 type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, CallContext>;
40 }50 }
4151
42 #[pallet::pallet]52 #[pallet::pallet]
49impl<T: Config> fp_evm::TransactionValidityHack<T::CrossAccountId> for TransactionValidityHack<T> {59impl<T: Config> fp_evm::TransactionValidityHack<T::CrossAccountId> for TransactionValidityHack<T> {
50 fn who_pays_fee(origin: H160, reason: &WithdrawReason) -> Option<T::CrossAccountId> {60 fn who_pays_fee(
61 origin: H160,
62 max_fee: U256,
63 reason: &WithdrawReason,
64 ) -> Option<T::CrossAccountId> {
51 match reason {65 match reason {
52 WithdrawReason::Call { target, input } => {66 WithdrawReason::Call { target, input } => {
53 let origin_sub = T::CrossAccountId::from_eth(origin);67 let origin_sub = T::CrossAccountId::from_eth(origin);
68 let call_context = CallContext {
69 contract_address: *target,
70 input: input.clone(),
71 max_fee,
72 };
54 T::EvmSponsorshipHandler::get_sponsor(&origin_sub, &(*target, input.clone()))73 T::EvmSponsorshipHandler::get_sponsor(&origin_sub, &call_context)
55 }74 }
56 _ => None,75 _ => None,
57 }76 }
71 source,90 source,
72 target,91 target,
73 input,92 input,
93 gas_limit,
94 max_fee_per_gas,
74 ..95 ..
75 } => {96 } => {
76 let _ = T::CallOrigin::ensure_address_origin(97 let _ = T::CallOrigin::ensure_address_origin(
79 )100 )
80 .ok()?;101 .ok()?;
81 let who = T::CrossAccountId::from_sub(who.clone());102 let who = T::CrossAccountId::from_sub(who.clone());
103 let max_fee = max_fee_per_gas.saturating_mul((*gas_limit).into());
104 let call_context = CallContext {
105 contract_address: *target,
106 input: input.clone(),
107 max_fee,
108 };
82 // Effects from EvmSponsorshipHandler are applied by pallet_evm::runner109 // Effects from EvmSponsorshipHandler are applied by pallet_evm::runner
83 // TODO: Should we implement simulation mode (test, but do not apply effects) in `up-sponsorship`?110 // TODO: Should we implement simulation mode (test, but do not apply effects) in `up-sponsorship`?
84 let sponsor = frame_support::storage::with_transaction(|| {111 let sponsor = frame_support::storage::with_transaction(|| {
85 TransactionOutcome::Rollback(Ok::<_, DispatchError>(112 TransactionOutcome::Rollback(Ok::<_, DispatchError>(
86 T::EvmSponsorshipHandler::get_sponsor(&who, &(*target, input.clone())),113 T::EvmSponsorshipHandler::get_sponsor(&who, &call_context),
87 ))114 ))
88 })115 })
89 // FIXME: it may fail with DispatchError in case of depth limit116 // FIXME: it may fail with DispatchError in case of depth limit
modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
23pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }23pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
24ethereum = { version = "0.12.0", default-features = false }24ethereum = { version = "0.12.0", default-features = false }
25frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }25frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
26pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }26pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
27scale-info = { version = "2.0.1", default-features = false, features = [27scale-info = { version = "2.0.1", default-features = false, features = [
28 "derive",28 "derive",
29] }29] }
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
22}22}
2323
24/// @title A contract that allows you to work with collections.24/// @title A contract that allows you to work with collections.
25/// @dev the ERC-165 identifier for this interface is 0xe54be64025/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
26contract Collection is Dummy, ERC165 {26contract Collection is Dummy, ERC165 {
27 /// Set collection property.27 /// Set collection property.
28 ///28 ///
255 dummy = 0;255 dummy = 0;
256 }256 }
257
258 /// Checks that user allowed to operate with collection.
259 ///
260 /// @param user User address to check.
261 /// @dev EVM selector for this function is: 0xd63a8e11,
262 /// or in textual repr: allowed(address)
263 function allowed(address user) public view returns (bool) {
264 require(false, stub_error);
265 user;
266 dummy;
267 return false;
268 }
257269
258 /// Add the user to the allowed list.270 /// Add the user to the allowed list.
259 ///271 ///
266 dummy = 0;278 dummy = 0;
267 }279 }
280
281 /// Add substrate user to allowed list.
282 ///
283 /// @param user User substrate address.
284 /// @dev EVM selector for this function is: 0xd06ad267,
285 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
286 function addToCollectionAllowListSubstrate(uint256 user) public {
287 require(false, stub_error);
288 user;
289 dummy = 0;
290 }
268291
269 /// Remove the user from the allowed list.292 /// Remove the user from the allowed list.
270 ///293 ///
277 dummy = 0;300 dummy = 0;
278 }301 }
302
303 /// Remove substrate user from allowed list.
304 ///
305 /// @param user User substrate address.
306 /// @dev EVM selector for this function is: 0xa31913ed,
307 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
308 function removeFromCollectionAllowListSubstrate(uint256 user) public {
309 require(false, stub_error);
310 user;
311 dummy = 0;
312 }
279313
280 /// Switch permission for minting.314 /// Switch permission for minting.
281 ///315 ///
325 return "";359 return "";
326 }360 }
361
362 /// Get collection owner.
363 ///
364 /// @return Tuble with sponsor address and his substrate mirror.
365 /// If address is canonical then substrate mirror is zero and vice versa.
366 /// @dev EVM selector for this function is: 0xdf727d3b,
367 /// or in textual repr: collectionOwner()
368 function collectionOwner() public view returns (Tuple6 memory) {
369 require(false, stub_error);
370 dummy;
371 return Tuple6(0x0000000000000000000000000000000000000000, 0);
372 }
327373
328 /// Changes collection owner to another account374 /// Changes collection owner to another account
329 ///375 ///
modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20pallet-common = { default-features = false, path = '../common' }20pallet-common = { default-features = false, path = '../common' }
21pallet-structure = { default-features = false, path = '../structure' }21pallet-structure = { default-features = false, path = '../structure' }
22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
99}99}
100100
101/// @title A contract that allows you to work with collections.101/// @title A contract that allows you to work with collections.
102/// @dev the ERC-165 identifier for this interface is 0xe54be640102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
103contract Collection is Dummy, ERC165 {103contract Collection is Dummy, ERC165 {
104 /// Set collection property.104 /// Set collection property.
105 ///105 ///
332 dummy = 0;332 dummy = 0;
333 }333 }
334
335 /// Checks that user allowed to operate with collection.
336 ///
337 /// @param user User address to check.
338 /// @dev EVM selector for this function is: 0xd63a8e11,
339 /// or in textual repr: allowed(address)
340 function allowed(address user) public view returns (bool) {
341 require(false, stub_error);
342 user;
343 dummy;
344 return false;
345 }
334346
335 /// Add the user to the allowed list.347 /// Add the user to the allowed list.
336 ///348 ///
343 dummy = 0;355 dummy = 0;
344 }356 }
357
358 /// Add substrate user to allowed list.
359 ///
360 /// @param user User substrate address.
361 /// @dev EVM selector for this function is: 0xd06ad267,
362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
363 function addToCollectionAllowListSubstrate(uint256 user) public {
364 require(false, stub_error);
365 user;
366 dummy = 0;
367 }
345368
346 /// Remove the user from the allowed list.369 /// Remove the user from the allowed list.
347 ///370 ///
354 dummy = 0;377 dummy = 0;
355 }378 }
379
380 /// Remove substrate user from allowed list.
381 ///
382 /// @param user User substrate address.
383 /// @dev EVM selector for this function is: 0xa31913ed,
384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
385 function removeFromCollectionAllowListSubstrate(uint256 user) public {
386 require(false, stub_error);
387 user;
388 dummy = 0;
389 }
356390
357 /// Switch permission for minting.391 /// Switch permission for minting.
358 ///392 ///
402 return "";436 return "";
403 }437 }
438
439 /// Get collection owner.
440 ///
441 /// @return Tuble with sponsor address and his substrate mirror.
442 /// If address is canonical then substrate mirror is zero and vice versa.
443 /// @dev EVM selector for this function is: 0xdf727d3b,
444 /// or in textual repr: collectionOwner()
445 function collectionOwner() public view returns (Tuple17 memory) {
446 require(false, stub_error);
447 dummy;
448 return Tuple17(0x0000000000000000000000000000000000000000, 0);
449 }
404450
405 /// Changes collection owner to another account451 /// Changes collection owner to another account
406 ///452 ///
modifiedpallets/proxy-rmrk-core/Cargo.tomldiffbeforeafterboth
20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
21pallet-structure = { default-features = false, path = "../../pallets/structure" }21pallet-structure = { default-features = false, path = "../../pallets/structure" }
22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
23pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }23pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
24frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }24frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
25rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }25rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
26scale-info = { version = "2.0.1", default-features = false, features = [26scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/proxy-rmrk-equip/Cargo.tomldiffbeforeafterboth
19pallet-common = { default-features = false, path = '../common' }19pallet-common = { default-features = false, path = '../common' }
20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
23frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }23frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
24rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }24rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
25scale-info = { version = "2.0.1", default-features = false, features = [25scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/refungible/Cargo.tomldiffbeforeafterboth
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20evm-coder = { default-features = false, path = '../../crates/evm-coder' }20evm-coder = { default-features = false, path = '../../crates/evm-coder' }
21pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }21pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
22pallet-common = { default-features = false, path = '../common' }22pallet-common = { default-features = false, path = '../common' }
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
99}99}
100100
101/// @title A contract that allows you to work with collections.101/// @title A contract that allows you to work with collections.
102/// @dev the ERC-165 identifier for this interface is 0xe54be640102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
103contract Collection is Dummy, ERC165 {103contract Collection is Dummy, ERC165 {
104 /// Set collection property.104 /// Set collection property.
105 ///105 ///
332 dummy = 0;332 dummy = 0;
333 }333 }
334
335 /// Checks that user allowed to operate with collection.
336 ///
337 /// @param user User address to check.
338 /// @dev EVM selector for this function is: 0xd63a8e11,
339 /// or in textual repr: allowed(address)
340 function allowed(address user) public view returns (bool) {
341 require(false, stub_error);
342 user;
343 dummy;
344 return false;
345 }
334346
335 /// Add the user to the allowed list.347 /// Add the user to the allowed list.
336 ///348 ///
343 dummy = 0;355 dummy = 0;
344 }356 }
357
358 /// Add substrate user to allowed list.
359 ///
360 /// @param user User substrate address.
361 /// @dev EVM selector for this function is: 0xd06ad267,
362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
363 function addToCollectionAllowListSubstrate(uint256 user) public {
364 require(false, stub_error);
365 user;
366 dummy = 0;
367 }
345368
346 /// Remove the user from the allowed list.369 /// Remove the user from the allowed list.
347 ///370 ///
354 dummy = 0;377 dummy = 0;
355 }378 }
379
380 /// Remove substrate user from allowed list.
381 ///
382 /// @param user User substrate address.
383 /// @dev EVM selector for this function is: 0xa31913ed,
384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
385 function removeFromCollectionAllowListSubstrate(uint256 user) public {
386 require(false, stub_error);
387 user;
388 dummy = 0;
389 }
356390
357 /// Switch permission for minting.391 /// Switch permission for minting.
358 ///392 ///
402 return "";436 return "";
403 }437 }
438
439 /// Get collection owner.
440 ///
441 /// @return Tuble with sponsor address and his substrate mirror.
442 /// If address is canonical then substrate mirror is zero and vice versa.
443 /// @dev EVM selector for this function is: 0xdf727d3b,
444 /// or in textual repr: collectionOwner()
445 function collectionOwner() public view returns (Tuple17 memory) {
446 require(false, stub_error);
447 dummy;
448 return Tuple17(0x0000000000000000000000000000000000000000, 0);
449 }
404450
405 /// Changes collection owner to another account451 /// Changes collection owner to another account
406 ///452 ///
modifiedpallets/structure/Cargo.tomldiffbeforeafterboth
16 "derive",16 "derive",
17] }17] }
18up-data-structs = { path = "../../primitives/data-structs", default-features = false }18up-data-structs = { path = "../../primitives/data-structs", default-features = false }
19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2020
21[features]21[features]
22default = ["std"]22default = ["std"]
modifiedpallets/unique/CHANGELOG.mddiffbeforeafterboth
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
66
7## [v0.1.4] 2022-09-57## [v0.2.0] 2022-09-13
88
9### Changes
10- Change **collectionHelper** method `createRefungibleCollection` to `createRFTCollection`,
11
12## [v0.1.4] 2022-09-05
13
9### Added14### Added
1015
11- Methods `force_set_sponsor` , `force_remove_collection_sponsor` to be able to administer sponsorships with other pallets. Added to implement `AppPromotion` pallet logic.16- Methods `force_set_sponsor` , `force_remove_collection_sponsor` to be able to administer sponsorships with other pallets. Added to implement `AppPromotion` pallet logic.
modifiedpallets/unique/Cargo.tomldiffbeforeafterboth
9license = 'GPLv3'9license = 'GPLv3'
10name = 'pallet-unique'10name = 'pallet-unique'
11repository = 'https://github.com/UniqueNetwork/unique-chain'11repository = 'https://github.com/UniqueNetwork/unique-chain'
12version = "0.1.4"12version = "0.2.0"
1313
14[package.metadata.docs.rs]14[package.metadata.docs.rs]
15targets = ['x86_64-unknown-linux-gnu']15targets = ['x86_64-unknown-linux-gnu']
98scale-info = { version = "2.0.1", default-features = false, features = [98scale-info = { version = "2.0.1", default-features = false, features = [
99 "derive",99 "derive",
100] }100] }
101pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }101pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
102pallet-common = { default-features = false, path = "../common" }102pallet-common = { default-features = false, path = "../common" }
103evm-coder = { default-features = false, path = '../../crates/evm-coder' }103evm-coder = { default-features = false, path = '../../crates/evm-coder' }
104pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }104pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};
22use frame_support::traits::Get;22use frame_support::traits::Get;
23use pallet_common::{23use pallet_common::{
24 CollectionById, CollectionHandle,24 CollectionById,
25 dispatch::CollectionDispatch,25 dispatch::CollectionDispatch,
26 erc::{26 erc::{
27 CollectionHelpersEvents,27 CollectionHelpersEvents,
28 static_property::{key, value as property_value},28 static_property::{key, value as property_value},
29 },29 },
30 Pallet as PalletCommon,
31};30};
32use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};31use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
33use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};32use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
34use pallet_evm_coder_substrate::dispatch_to_evm;
35use up_data_structs::{33use up_data_structs::{
36 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,34 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,
37 CollectionMode, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,35 CollectionMode, PropertyValue,
38};36};
3937
40use crate::{Config, SelfWeightOf, weights::WeightInfo};38use crate::{Config, SelfWeightOf, weights::WeightInfo};
4139
42use sp_std::{vec, vec::Vec};40use sp_std::vec::Vec;
43use alloc::format;41use alloc::format;
4442
45/// See [`CollectionHelpersCall`]43/// See [`CollectionHelpersCall`]
245 }243 }
246244
247 #[weight(<SelfWeightOf<T>>::create_collection())]245 #[weight(<SelfWeightOf<T>>::create_collection())]
246 #[solidity(rename_selector = "createRFTCollection")]
248 fn create_refungible_collection(247 fn create_refungible_collection(
249 &mut self,248 &mut self,
250 caller: caller,249 caller: caller,
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth
30}23}
3124
32/// @title Contract, which allows users to operate with collections25/// @title Contract, which allows users to operate with collections
33/// @dev the ERC-165 identifier for this interface is 0x675f307426/// @dev the ERC-165 identifier for this interface is 0x88ee8ef1
34contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {27contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
35 /// Create an NFT collection28 /// Create an NFT collection
36 /// @param name Name of the collection29 /// @param name Name of the collection
69 return 0x0000000000000000000000000000000000000000;62 return 0x0000000000000000000000000000000000000000;
70 }63 }
7164
72 /// @dev EVM selector for this function is: 0x44a68ad5,65 /// @dev EVM selector for this function is: 0xab173450,
73 /// or in textual repr: createRefungibleCollection(string,string,string)66 /// or in textual repr: createRFTCollection(string,string,string)
74 function createRefungibleCollection(67 function createRFTCollection(
75 string memory name,68 string memory name,
76 string memory description,69 string memory description,
77 string memory tokenPrefix70 string memory tokenPrefix
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
1105}1105}
11061106
1107impl<T: Config> Pallet<T> {1107impl<T: Config> Pallet<T> {
1108 /// Force set `sponsor` for `collection`.
1109 ///
1110 /// Differs from [`set_collection_sponsor`][`Pallet::set_collection_sponsor`] in that confirmation
1111 /// from the `sponsor` is not required.
1112 ///
1113 /// # Arguments
1114 ///
1115 /// * `sponsor`: ID of the account of the sponsor-to-be.
1116 /// * `collection_id`: ID of the modified collection.
1108 pub fn force_set_sponsor(sponsor: T::AccountId, collection_id: CollectionId) -> DispatchResult {1117 pub fn force_set_sponsor(sponsor: T::AccountId, collection_id: CollectionId) -> DispatchResult {
1109 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1118 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
1110 target_collection.check_is_internal()?;1119 target_collection.check_is_internal()?;
1125 target_collection.save()1134 target_collection.save()
1126 }1135 }
11271136
1137 /// Force remove `sponsor` for `collection`.
1138 ///
1139 /// Differs from `remove_sponsor` in that
1140 /// it doesn't require consent from the `owner` of the collection.
1141 ///
1142 /// # Arguments
1143 ///
1144 /// * `collection_id`: ID of the modified collection.
1128 pub fn force_remove_collection_sponsor(collection_id: CollectionId) -> DispatchResult {1145 pub fn force_remove_collection_sponsor(collection_id: CollectionId) -> DispatchResult {
1129 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1146 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
1130 target_collection.check_is_internal()?;1147 target_collection.check_is_internal()?;
modifiedprimitives/app_promotion_rpc/Cargo.tomldiffbeforeafterboth
14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
1818
19[features]19[features]
20default = ["std"]20default = ["std"]
modifiedprimitives/common/CHANGELOG.mddiffbeforeafterboth
1<!-- bureaucrate goes here -->1<!-- bureaucrate goes here -->
2## [v0.9.27] 2022-09-08
3
4### Added
5- Relay block constants. In particular, it is necessary to add the `AppPromotion` pallet at runtime.
6
2## [v0.9.25] 2022-08-167## [v0.9.25] 2022-08-16
38
4### Other changes9### Other changes
modifiedprimitives/common/Cargo.tomldiffbeforeafterboth
48[dependencies.fp-rpc]48[dependencies.fp-rpc]
49default-features = false49default-features = false
50git = "https://github.com/uniquenetwork/frontier"50git = "https://github.com/uniquenetwork/frontier"
51branch = "unique-polkadot-v0.9.27"51branch = "unique-polkadot-v0.9.27-fee-limit"
5252
53[dependencies.pallet-evm]53[dependencies.pallet-evm]
54default-features = false54default-features = false
55git = "https://github.com/uniquenetwork/frontier"55git = "https://github.com/uniquenetwork/frontier"
56branch = "unique-polkadot-v0.9.27"56branch = "unique-polkadot-v0.9.27-fee-limit"
5757
modifiedprimitives/data-structs/Cargo.tomldiffbeforeafterboth
25sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }25sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
26derivative = { version = "2.2.0", features = ["use_core"] }26derivative = { version = "2.2.0", features = ["use_core"] }
27struct-versioning = { path = "../../crates/struct-versioning" }27struct-versioning = { path = "../../crates/struct-versioning" }
28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
29rmrk-traits = { default-features = false, path = "../rmrk-traits" }29rmrk-traits = { default-features = false, path = "../rmrk-traits" }
3030
31[features]31[features]
modifiedprimitives/rpc/Cargo.tomldiffbeforeafterboth
14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
1818
19[features]19[features]
20default = ["std"]20default = ["std"]
modifiedruntime/common/config/sponsoring.rsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17use frame_support::parameter_types;
18use crate::{17use crate::{
19 runtime_common::{sponsoring::UniqueSponsorshipHandler},18 runtime_common::{sponsoring::UniqueSponsorshipHandler},
20 Runtime,19 Runtime,
21};20};
21use frame_support::parameter_types;
22use sp_core::U256;
22use up_common::{types::BlockNumber, constants::*};23use up_common::{constants::*, types::BlockNumber};
2324
24parameter_types! {25parameter_types! {
25 pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;26 pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;
27 pub const DefaultSponsoringFeeLimit: U256 = U256::MAX;
26}28}
2729
28type SponsorshipHandler = (30type SponsorshipHandler = (
modifiedruntime/common/ethereum/sponsoring.rsdiffbeforeafterboth
1616
17//! Implements EVM sponsoring logic via TransactionValidityHack17//! Implements EVM sponsoring logic via TransactionValidityHack
1818
19use core::{convert::TryInto, marker::PhantomData};
19use evm_coder::{Call, abi::AbiReader};20use evm_coder::{Call, abi::AbiReader};
20use pallet_common::{CollectionHandle, eth::map_eth_to_id};21use pallet_common::{CollectionHandle, eth::map_eth_to_id};
21use sp_core::H160;22use pallet_evm::account::CrossAccountId;
23use pallet_evm_transaction_payment::CallContext;
22use sp_std::prelude::*;24use pallet_nonfungible::{
25 Config as NonfungibleConfig,
26 erc::{
27 UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call,
28 TokenPropertiesCall,
29 },
30};
23use up_sponsorship::SponsorshipHandler;31use pallet_fungible::{
32 Config as FungibleConfig,
33 erc::{UniqueFungibleCall, ERC20Call},
34};
24use core::marker::PhantomData;35use pallet_refungible::Config as RefungibleConfig;
25use core::convert::TryInto;36use pallet_unique::Config as UniqueConfig;
26use pallet_evm::account::CrossAccountId;37use sp_std::prelude::*;
27use up_data_structs::{TokenId, CreateItemData, CreateNftData, CollectionMode};38use up_data_structs::{CollectionMode, CreateItemData, CreateNftData, TokenId};
28use pallet_unique::Config as UniqueConfig;39use up_sponsorship::SponsorshipHandler;
2940
30use crate::{Runtime, runtime_common::sponsoring::*};41use crate::{Runtime, runtime_common::sponsoring::*};
31
32use pallet_nonfungible::erc::{
33 UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call, TokenPropertiesCall,
34};
35use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
36use pallet_fungible::Config as FungibleConfig;
37use pallet_nonfungible::Config as NonfungibleConfig;
38use pallet_refungible::Config as RefungibleConfig;
3942
40pub type EvmSponsorshipHandler = (43pub type EvmSponsorshipHandler = (
41 UniqueEthSponsorshipHandler<Runtime>,44 UniqueEthSponsorshipHandler<Runtime>,
4447
45pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);48pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);
46impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>49impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>
47 SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T>50 SponsorshipHandler<T::CrossAccountId, CallContext> for UniqueEthSponsorshipHandler<T>
48{51{
49 fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {52 fn get_sponsor(
53 who: &T::CrossAccountId,
54 call_context: &CallContext,
55 ) -> Option<T::CrossAccountId> {
50 let collection_id = map_eth_to_id(&call.0)?;56 let collection_id = map_eth_to_id(&call_context.contract_address)?;
51 let collection = <CollectionHandle<T>>::new(collection_id)?;57 let collection = <CollectionHandle<T>>::new(collection_id)?;
52 let sponsor = collection.sponsorship.sponsor()?.clone();58 let sponsor = collection.sponsorship.sponsor()?.clone();
53 let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;59 let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;
54 Some(T::CrossAccountId::from_sub(match &collection.mode {60 Some(T::CrossAccountId::from_sub(match &collection.mode {
55 CollectionMode::NFT => {61 CollectionMode::NFT => {
56 let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;62 let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
modifiedruntime/opal/CHANGELOG.mddiffbeforeafterboth
3All notable changes to this project will be documented in this file.3All notable changes to this project will be documented in this file.
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
6
7## [v0.9.27] 2022-09-08
8
9### Added
10
11- `AppPromotion` pallet to runtime.
12
6## [v0.9.27] 2022-08-1613## [v0.9.27] 2022-08-16
714
8### Bugfixes15### Bugfixes
916
10- Add missing config keys 74f532ac28dce15c15e7d576c074a58eba658c0817- Add missing config keys 74f532ac28dce15c15e7d576c074a58eba658c08
1118
12### Other changes19### Other changes
1320
14- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a21- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
1522
16- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf823- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
1724
18- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b25- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
1926
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
417up-rpc = { path = "../../primitives/rpc", default-features = false }417up-rpc = { path = "../../primitives/rpc", default-features = false }
418app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}418app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
419rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }419rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }
420fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }420fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
421pallet-inflation = { path = '../../pallets/inflation', default-features = false }421pallet-inflation = { path = '../../pallets/inflation', default-features = false }
422pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }422pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
423up-data-structs = { path = '../../primitives/data-structs', default-features = false }423up-data-structs = { path = '../../primitives/data-structs', default-features = false }
436pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }436pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
437pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }437pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
438pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }438pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
439pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }439pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
440pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }440pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
441pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }441pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
442fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }442fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
443fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }443fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
444evm-coder = { default-features = false, path = '../../crates/evm-coder' }444evm-coder = { default-features = false, path = '../../crates/evm-coder' }
445up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }445up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
446446
447################################################################################447################################################################################
448# Build Dependencies448# Build Dependencies
modifiedruntime/quartz/CHANGELOG.mddiffbeforeafterboth
3All notable changes to this project will be documented in this file.3All notable changes to this project will be documented in this file.
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
6
7## [v0.9.27] 2022-09-08
8
9### Added
10
11- `AppPromotion` pallet to runtime.
12
6## [v0.9.27] 2022-08-1613## [v0.9.27] 2022-08-16
714
8### Bugfixes15### Bugfixes
916
10- Add missing config keys 74f532ac28dce15c15e7d576c074a58eba658c0817- Add missing config keys 74f532ac28dce15c15e7d576c074a58eba658c08
1118
12### Other changes19### Other changes
13
14- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
1520
16- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf821- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
1722
18- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b23- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
1924
25- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
2026
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
418pallet-unique = { path = '../../pallets/unique', default-features = false }418pallet-unique = { path = '../../pallets/unique', default-features = false }
419up-rpc = { path = "../../primitives/rpc", default-features = false }419up-rpc = { path = "../../primitives/rpc", default-features = false }
420app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}420app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
421fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }421fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
422pallet-inflation = { path = '../../pallets/inflation', default-features = false }422pallet-inflation = { path = '../../pallets/inflation', default-features = false }
423pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }423pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
424up-data-structs = { path = '../../primitives/data-structs', default-features = false }424up-data-structs = { path = '../../primitives/data-structs', default-features = false }
437pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }437pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
438pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }438pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
439pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }439pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
440pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }440pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
441pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }441pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
442pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }442pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
443fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }443fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
444fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }444fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
445evm-coder = { default-features = false, path = '../../crates/evm-coder' }445evm-coder = { default-features = false, path = '../../crates/evm-coder' }
446up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }446up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
447447
448################################################################################448################################################################################
449# Build Dependencies449# Build Dependencies
modifiedruntime/tests/Cargo.tomldiffbeforeafterboth
16sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
1818
19fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2020
21frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }21frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
22frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }22frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
25pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }25pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
26pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }26pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
2727
28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
29pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }29pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
3030
31pallet-common = { path = '../../pallets/common' }31pallet-common = { path = '../../pallets/common' }
32pallet-structure = { path = '../../pallets/structure' }32pallet-structure = { path = '../../pallets/structure' }
43scale-info = "*"43scale-info = "*"
4444
45evm-coder = { default-features = false, path = '../../crates/evm-coder' }45evm-coder = { default-features = false, path = '../../crates/evm-coder' }
46up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }46up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
4747
modifiedruntime/unique/CHANGELOG.mddiffbeforeafterboth
3All notable changes to this project will be documented in this file.3All notable changes to this project will be documented in this file.
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
6
7## [v0.9.27] 2022-09-08
8
9### Added
10
11- `AppPromotion` pallet to runtime.
12
6## [v0.9.27] 2022-08-1613## [v0.9.27] 2022-08-16
714
8### Bugfixes15### Bugfixes
916
10- Add missing config keys 74f532ac28dce15c15e7d576c074a58eba658c0817- Add missing config keys 74f532ac28dce15c15e7d576c074a58eba658c08
1118
12### Other changes19### Other changes
1320
14- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a21- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
1522
16- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf823- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
1724
18- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b25- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
1926
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
430pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }430pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
431pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }431pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
432pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }432pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
433pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }433pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
434pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }434pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
435pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }435pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
436fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }436fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
437fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }437fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
438fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }438fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
439evm-coder = { default-features = false, path = '../../crates/evm-coder' }439evm-coder = { default-features = false, path = '../../crates/evm-coder' }
440up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }440up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
441441
442################################################################################442################################################################################
443# Build Dependencies443# Build Dependencies
modifiedtests/package.jsondiffbeforeafterboth
73 "testRemoveFromContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromContractAllowList.test.ts",73 "testRemoveFromContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromContractAllowList.test.ts",
74 "testSetContractSponsoringRateLimit": "mocha --timeout 9999999 -r ts-node/register ./**/setContractSponsoringRateLimit.test.ts",74 "testSetContractSponsoringRateLimit": "mocha --timeout 9999999 -r ts-node/register ./**/setContractSponsoringRateLimit.test.ts",
75 "testSetOffchainSchema": "mocha --timeout 9999999 -r ts-node/register ./**/setOffchainSchema.test.ts",75 "testSetOffchainSchema": "mocha --timeout 9999999 -r ts-node/register ./**/setOffchainSchema.test.ts",
76 "testNextSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/nextSponsoring.test.ts",
76 "testOverflow": "mocha --timeout 9999999 -r ts-node/register ./**/overflow.test.ts",77 "testOverflow": "mocha --timeout 9999999 -r ts-node/register ./**/overflow.test.ts",
77 "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",78 "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",
78 "testScheduler": "mocha --timeout 9999999 -r ts-node/register ./**/scheduler.test.ts",79 "testScheduler": "mocha --timeout 9999999 -r ts-node/register ./**/scheduler.test.ts",
99 "dependencies": {100 "dependencies": {
100 "@polkadot/api": "9.2.2",101 "@polkadot/api": "9.2.2",
101 "@polkadot/api-contract": "9.2.2",102 "@polkadot/api-contract": "9.2.2",
102 "@polkadot/util-crypto": "10.1.1",103 "@polkadot/util-crypto": "10.1.7",
103 "bignumber.js": "^9.0.2",104 "bignumber.js": "^9.0.2",
104 "chai-as-promised": "^7.1.1",105 "chai-as-promised": "^7.1.1",
105 "chai-like": "^1.1.1",106 "chai-like": "^1.1.1",
modifiedtests/scripts/readyness.jsdiffbeforeafterboth
6 await api.isReadyOrError;6 await api.isReadyOrError;
77
8 const head = (await api.rpc.chain.getHeader()).number.toNumber();8 const head = (await api.rpc.chain.getHeader()).number.toNumber();
9 await api.disconnect();
9 if(head < 1) throw Error('No block #1');10 if(head < 1) throw Error('No block #1');
1011
11 await api.disconnect();
12}12}
1313
14const sleep = time => {14const sleep = time => {
modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import chai from 'chai';
19import chaiAsPromised from 'chai-as-promised';
20import {usingPlaygrounds} from './util/playgrounds';18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
21
22chai.use(chaiAsPromised);
23const expect = chai.expect;
24
25let donor: IKeyringPair;
26
27before(async () => {
28 await usingPlaygrounds(async (_, privateKeyWrapper) => {
29 donor = privateKeyWrapper('//Alice');
30 });
31});
3219
33describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {20describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
21 let donor: IKeyringPair;
22
23 before(async () => {
24 await usingPlaygrounds(async (_, privateKeyWrapper) => {
25 donor = privateKeyWrapper('//Alice');
26 });
27 });
28
34 it('Add collection admin.', async () => {29 itSub('Add collection admin.', async ({helper}) => {
35 await usingPlaygrounds(async (helper) => {
36 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);30 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
37 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});31 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
3832
39 const collection = await helper.collection.getData(collectionId);33 const collection = await helper.collection.getData(collectionId);
40 expect(collection!.normalizedOwner!).to.be.equal(alice.address);34 expect(collection!.normalizedOwner!).to.be.equal(helper.address.normalizeSubstrate(alice.address));
4135
42 await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});36 await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
4337
44 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);38 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
45 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});39 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
46 });
47 });40 });
48});41});
4942
50describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {43describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
44 let donor: IKeyringPair;
45
46 before(async () => {
47 await usingPlaygrounds(async (_, privateKeyWrapper) => {
48 donor = privateKeyWrapper('//Alice');
49 });
50 });
51
51 it("Not owner can't add collection admin.", async () => {52 itSub("Not owner can't add collection admin.", async ({helper}) => {
52 await usingPlaygrounds(async (helper) => {
53 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);53 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
54 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});54 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
5555
56 const collection = await helper.collection.getData(collectionId);56 const collection = await helper.collection.getData(collectionId);
57 expect(collection?.normalizedOwner).to.be.equal(alice.address);57 expect(collection?.normalizedOwner).to.be.equal(helper.address.normalizeSubstrate(alice.address));
5858
59 const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});59 const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});
60 const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});60 const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});
61 await expect(changeAdminTxCharlie()).to.be.rejected;61 await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
62 await expect(changeAdminTxBob()).to.be.rejected;62 await expect(changeAdminTxBob()).to.be.rejectedWith(/common\.NoPermission/);
6363
64 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);64 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
65 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});65 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});
66 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});66 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});
67 });
68 });67 });
6968
70 it("Admin can't add collection admin.", async () => {69 itSub("Admin can't add collection admin.", async ({helper}) => {
71 await usingPlaygrounds(async (helper) => {
72 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);70 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
73 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});71 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
7472
78 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});76 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
7977
80 const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});78 const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});
81 await expect(changeAdminTxCharlie()).to.be.rejected;79 await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
8280
83 const adminListAfterAddNewAdmin = await collection.getAdmins();81 const adminListAfterAddNewAdmin = await collection.getAdmins();
84 expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});82 expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});
85 expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});83 expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});
86 });
87 });84 });
8885
89 it("Can't add collection admin of not existing collection.", async () => {86 itSub("Can't add collection admin of not existing collection.", async ({helper}) => {
90 await usingPlaygrounds(async (helper) => {
91 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);87 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
92 // tslint:disable-next-line: no-bitwise
93 const collectionId = (1 << 32) - 1;88 const collectionId = (1 << 32) - 1;
9489
95 const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});90 const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
96 await expect(addAdminTx()).to.be.rejected;91 await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
9792
98 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)93 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
99 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});94 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
100 });
101 });95 });
10296
103 it("Can't add an admin to a destroyed collection.", async () => {97 itSub("Can't add an admin to a destroyed collection.", async ({helper}) => {
104 await usingPlaygrounds(async (helper) => {
105 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);98 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
106 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});99 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
107100
108 await collection.burn(alice);101 await collection.burn(alice);
109 const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});102 const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});
110 await expect(addAdminTx()).to.be.rejected;103 await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
111104
112 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)105 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
113 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});106 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
114 });
115 });107 });
116108
117 it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {109 itSub('Add an admin to a collection that has reached the maximum number of admins limit', async ({helper}) => {
118 await usingPlaygrounds(async (helper) => {
119 const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);110 const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
120 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});111 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
121112
129 }120 }
130121
131 const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});122 const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});
132 await expect(addExtraAdminTx()).to.be.rejected;123 await expect(addExtraAdminTx()).to.be.rejectedWith(/common\.CollectionAdminCountExceeded/);
133 });
134 });124 });
135});125});
136126
modifiedtests/src/approve.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import chai from 'chai';18import {expect, itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
19import chaiAsPromised from 'chai-as-promised';
20import {
21 approveExpectFail,
22 approveExpectSuccess,
23 createCollectionExpectSuccess,
24 createItemExpectSuccess,
25} from './util/helpers';
26import {usingPlaygrounds} from './util/playgrounds';
2719
28let donor: IKeyringPair;
2920
30before(async () => {
31 await usingPlaygrounds(async (_, privateKey) => {
32 donor = privateKey('//Alice');
33 });
34});
35
36chai.use(chaiAsPromised);
37const expect = chai.expect;
38
39describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {21describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {
40 let alice: IKeyringPair;22 let alice: IKeyringPair;
41 let bob: IKeyringPair;23 let bob: IKeyringPair;
42 let charlie: IKeyringPair;24 let charlie: IKeyringPair;
4325
44 before(async () => {26 before(async () => {
45 await usingPlaygrounds(async (helper) => {27 await usingPlaygrounds(async (helper, privateKey) => {
28 const donor = privateKey('//Alice');
46 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);29 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
47 });30 });
48 });31 });
4932
50 it('[nft] Execute the extrinsic and check approvedList', async () => {33 itSub('[nft] Execute the extrinsic and check approvedList', async ({helper}) => {
51 await usingPlaygrounds(async (helper) => {
52 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});34 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
53 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});35 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
54 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});36 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
55 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;37 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;
56 });
57 });38 });
5839
59 it('[fungible] Execute the extrinsic and check approvedList', async () => {40 itSub('[fungible] Execute the extrinsic and check approvedList', async ({helper}) => {
60 await usingPlaygrounds(async (helper) => {
61 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);41 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
62 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);42 await helper.ft.mintTokens(alice, collectionId, 10n, {Substrate: alice.address});
63 const tokenId = await helper.ft.getLastTokenId(collectionId);43 const tokenId = await helper.ft.getLastTokenId(collectionId);
64 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});44 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
65 const amount = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});45 const amount = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
66 expect(amount).to.be.equal(BigInt(1));46 expect(amount).to.be.equal(BigInt(1));
67 });
68 });47 });
6948
70 it('[refungible] Execute the extrinsic and check approvedList', async function() {49 itSub.ifWithPallets('[refungible] Execute the extrinsic and check approvedList', [Pallets.ReFungible], async ({helper}) => {
71 await usingPlaygrounds(async (helper) => {
72 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});50 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
73 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});51 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
74 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});52 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
75 const amount = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});53 const amount = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
76 expect(amount).to.be.equal(BigInt(1));54 expect(amount).to.be.equal(BigInt(1));
77 });
78 });55 });
7956
80 it('[nft] Remove approval by using 0 amount', async () => {57 itSub('[nft] Remove approval by using 0 amount', async ({helper}) => {
81 await usingPlaygrounds(async (helper) => {
82 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});58 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
83 const collectionId = collection.collectionId;59 const collectionId = collection.collectionId;
84 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});60 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
85 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});61 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
86 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;62 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;
87 await helper.signTransaction(alice, helper.api?.tx.unique.approve({Substrate: bob.address}, collectionId, tokenId, 0));63 await helper.signTransaction(alice, helper.api?.tx.unique.approve({Substrate: bob.address}, collectionId, tokenId, 0));
88 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;64 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;
89 });
90 });65 });
9166
92 it('[fungible] Remove approval by using 0 amount', async () => {67 itSub('[fungible] Remove approval by using 0 amount', async ({helper}) => {
93 await usingPlaygrounds(async (helper) => {
94 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);68 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
95 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);69 await helper.ft.mintTokens(alice, collectionId, 10n, {Substrate: alice.address});
96 const tokenId = await helper.ft.getLastTokenId(collectionId);70 const tokenId = await helper.ft.getLastTokenId(collectionId);
97 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});71 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
98 const amountBefore = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});72 const amountBefore = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
99 expect(amountBefore).to.be.equal(BigInt(1));73 expect(amountBefore).to.be.equal(BigInt(1));
10074
101 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);75 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
102 const amountAfter = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});76 const amountAfter = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
103 expect(amountAfter).to.be.equal(BigInt(0));77 expect(amountAfter).to.be.equal(BigInt(0));
104 });
105 });78 });
10679
107 it('[refungible] Remove approval by using 0 amount', async function() {80 itSub.ifWithPallets('[refungible] Remove approval by using 0 amount', [Pallets.ReFungible], async ({helper}) => {
108 await usingPlaygrounds(async (helper) => {
109 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});81 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
110 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});82 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
111 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});83 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
112 const amountBefore = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});84 const amountBefore = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
113 expect(amountBefore).to.be.equal(BigInt(1));85 expect(amountBefore).to.be.equal(BigInt(1));
11486
115 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);87 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
116 const amountAfter = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});88 const amountAfter = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
117 expect(amountAfter).to.be.equal(BigInt(0));89 expect(amountAfter).to.be.equal(BigInt(0));
118 });
119 });90 });
12091
121 it('can`t be called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {92 itSub('can`t be called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
122 await usingPlaygrounds(async (helper) => {
123 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});93 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
124 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});94 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
125 const approveTokenTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});95 const approveTokenTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
126 await expect(approveTokenTx()).to.be.rejected;96 await expect(approveTokenTx()).to.be.rejected;
127 });
128 });97 });
129});98});
13099
134 let charlie: IKeyringPair;103 let charlie: IKeyringPair;
135104
136 before(async () => {105 before(async () => {
137 await usingPlaygrounds(async (helper) => {106 await usingPlaygrounds(async (helper, privateKey) => {
107 const donor = privateKey('//Alice');
138 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);108 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
139 });109 });
140 });110 });
141111
142 it('NFT', async () => {112 itSub('NFT', async ({helper}) => {
143 await usingPlaygrounds(async (helper) => {
144 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});113 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
145 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});114 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
146 await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});115 await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
147 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: charlie.address})).to.be.true;116 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: charlie.address})).to.be.true;
148 });
149 });117 });
150118
151 it('Fungible up to an approved amount', async () => {119 itSub('Fungible up to an approved amount', async ({helper}) => {
152 await usingPlaygrounds(async (helper) => {
153 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);120 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
154 await helper.ft.mintTokens(alice, collectionId, bob.address, 10n);121 await helper.ft.mintTokens(alice, collectionId, 10n, bob.address);
155 const tokenId = await helper.ft.getLastTokenId(collectionId);122 const tokenId = await helper.ft.getLastTokenId(collectionId);
156 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});123 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
157 const amount = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: charlie.address}, {Substrate: bob.address});124 const amount = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: charlie.address}, {Substrate: bob.address});
158 expect(amount).to.be.equal(BigInt(1));125 expect(amount).to.be.equal(BigInt(1));
159 });
160 });126 });
161127
162 it('ReFungible up to an approved amount', async function() {128 itSub.ifWithPallets('ReFungible up to an approved amount', [Pallets.ReFungible], async ({helper}) => {
163 await usingPlaygrounds(async (helper) => {
164 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});129 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
165 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});130 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});
166 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address}, 100n);131 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address}, 100n);
167 const amount = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: charlie.address}, {Substrate: bob.address});132 const amount = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: charlie.address}, {Substrate: bob.address});
168 expect(amount).to.be.equal(BigInt(100n));133 expect(amount).to.be.equal(BigInt(100n));
169 });
170 });134 });
171});135});
172136
176 let charlie: IKeyringPair;140 let charlie: IKeyringPair;
177141
178 before(async () => {142 before(async () => {
179 await usingPlaygrounds(async (helper) => {143 await usingPlaygrounds(async (helper, privateKey) => {
144 const donor = privateKey('//Alice');
180 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);145 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
181 });146 });
182 });147 });
183148
184 it('NFT', async () => {149 itSub('NFT', async ({helper}) => {
185 await usingPlaygrounds(async (helper) => {
186 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});150 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
187 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});151 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
188 await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});152 await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
189 await helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});153 await helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
190 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);154 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
191 expect(owner.Substrate).to.be.equal(alice.address);155 expect(owner.Substrate).to.be.equal(alice.address);
192 });
193 });156 });
194157
195 it('Fungible up to an approved amount', async () => {158 itSub('Fungible up to an approved amount', async ({helper}) => {
196 await usingPlaygrounds(async (helper) => {
197 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);159 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
198 await helper.ft.mintTokens(alice, collectionId, bob.address, 10n);160 await helper.ft.mintTokens(alice, collectionId, 10n, bob.address);
199 const tokenId = await helper.ft.getLastTokenId(collectionId);161 const tokenId = await helper.ft.getLastTokenId(collectionId);
200 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});162 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
201 const before = await helper.ft.getBalance(collectionId, {Substrate: alice.address});163 const before = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
202 await helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);164 await helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
203 const after = await helper.ft.getBalance(collectionId, {Substrate: alice.address});165 const after = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
204 expect(after - before).to.be.equal(BigInt(1));166 expect(after - before).to.be.equal(BigInt(1));
205 });
206 });167 });
207168
208 it('ReFungible up to an approved amount', async function() {169 itSub.ifWithPallets('ReFungible up to an approved amount', [Pallets.ReFungible], async ({helper}) => {
209 await usingPlaygrounds(async (helper) => {
210 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});170 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
211 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});171 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});
212 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});172 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
213 const before = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});173 const before = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
214 await helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);174 await helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
215 const after = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});175 const after = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
216 expect(after - before).to.be.equal(BigInt(1));176 expect(after - before).to.be.equal(BigInt(1));
217 });
218 });177 });
219});178});
220179
224 let charlie: IKeyringPair;183 let charlie: IKeyringPair;
225184
226 before(async () => {185 before(async () => {
227 await usingPlaygrounds(async (helper) => {186 await usingPlaygrounds(async (helper, privateKey) => {
187 const donor = privateKey('//Alice');
228 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);188 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
229 });189 });
230 });190 });
231191
232 it('NFT', async () => {192 itSub('NFT', async ({helper}) => {
233 await usingPlaygrounds(async (helper) => {
234 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});193 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
235 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});194 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
236 await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});195 await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
237 await helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});196 await helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
238 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);197 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
239 expect(owner.Substrate).to.be.equal(alice.address);198 expect(owner.Substrate).to.be.equal(alice.address);
240 const transferTokenFromTx = async () => helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});199 const transferTokenFromTx = async () => helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
241 await expect(transferTokenFromTx()).to.be.rejected;200 await expect(transferTokenFromTx()).to.be.rejected;
242 });
243 });201 });
244202
245 it('Fungible up to an approved amount', async () => {203 itSub('Fungible up to an approved amount', async ({helper}) => {
246 await usingPlaygrounds(async (helper) => {
247 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);204 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
248 await helper.ft.mintTokens(alice, collectionId, bob.address, 10n);205 await helper.ft.mintTokens(alice, collectionId, 10n, bob.address);
249 const tokenId = await helper.ft.getLastTokenId(collectionId);206 const tokenId = await helper.ft.getLastTokenId(collectionId);
250 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});207 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
251 const before = await helper.ft.getBalance(collectionId, {Substrate: alice.address});208 const before = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
252 await helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);209 await helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
253 const after = await helper.ft.getBalance(collectionId, {Substrate: alice.address});210 const after = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
254 expect(after - before).to.be.equal(BigInt(1));211 expect(after - before).to.be.equal(BigInt(1));
255212
256 const transferTokenFromTx = async () => helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);213 const transferTokenFromTx = async () => helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
257 await expect(transferTokenFromTx()).to.be.rejected;214 await expect(transferTokenFromTx()).to.be.rejected;
258 });
259 });215 });
260216
261 it('ReFungible up to an approved amount', async function() {217 itSub.ifWithPallets('ReFungible up to an approved amount', [Pallets.ReFungible], async ({helper}) => {
262 await usingPlaygrounds(async (helper) => {
263 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});218 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
264 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});219 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});
265 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address}, 100n);220 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address}, 100n);
266 const before = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});221 const before = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
267 await helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 100n);222 await helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 100n);
268 const after = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});223 const after = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
269 expect(after - before).to.be.equal(BigInt(100));224 expect(after - before).to.be.equal(BigInt(100));
270 const transferTokenFromTx = async () => helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 100n);225 const transferTokenFromTx = async () => helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 100n);
271 await expect(transferTokenFromTx()).to.be.rejected;226 await expect(transferTokenFromTx()).to.be.rejected;
272 });
273 });227 });
274});228});
275229
280 let dave: IKeyringPair;234 let dave: IKeyringPair;
281235
282 before(async () => {236 before(async () => {
283 await usingPlaygrounds(async (helper) => {237 await usingPlaygrounds(async (helper, privateKey) => {
238 const donor = privateKey('//Alice');
284 [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);239 [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);
285 });240 });
286 });241 });
287242
288 it('If a user B is approved to transfer 10 Fungible tokens from user A, they can transfer 2 tokens to user C, which will result in decreasing approval from 10 to 8. Then user B can transfer 8 tokens to user D.', async () => {243 itSub('If a user B is approved to transfer 10 Fungible tokens from user A, they can transfer 2 tokens to user C, which will result in decreasing approval from 10 to 8. Then user B can transfer 8 tokens to user D.', async ({helper}) => {
289 await usingPlaygrounds(async (helper) => {
290 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);244 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
291 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);245 await helper.ft.mintTokens(alice, collectionId, 10n, alice.address);
292 const tokenId = await helper.ft.getLastTokenId(collectionId);246 const tokenId = await helper.ft.getLastTokenId(collectionId);
293 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 10n);247 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 10n);
294248
295 const charlieBefore = await helper.ft.getBalance(collectionId, {Substrate: charlie.address});249 const charlieBefore = await helper.ft.getBalance(collectionId, {Substrate: charlie.address});
296 await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}, 2n);250 await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}, 2n);
297 const charlieAfter = await helper.ft.getBalance(collectionId, {Substrate: charlie.address});251 const charlieAfter = await helper.ft.getBalance(collectionId, {Substrate: charlie.address});
298 expect(charlieAfter - charlieBefore).to.be.equal(BigInt(2));252 expect(charlieAfter - charlieBefore).to.be.equal(BigInt(2));
299253
300 const daveBefore = await helper.ft.getBalance(collectionId, {Substrate: dave.address});254 const daveBefore = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
301 await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: alice.address}, {Substrate: dave.address}, 8n);255 await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: alice.address}, {Substrate: dave.address}, 8n);
302 const daveAfter = await helper.ft.getBalance(collectionId, {Substrate: dave.address});256 const daveAfter = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
303 expect(daveAfter - daveBefore).to.be.equal(BigInt(8));257 expect(daveAfter - daveBefore).to.be.equal(BigInt(8));
304 });
305 });258 });
306});259});
307260
311 let charlie: IKeyringPair;264 let charlie: IKeyringPair;
312265
313 before(async () => {266 before(async () => {
314 await usingPlaygrounds(async (helper) => {267 await usingPlaygrounds(async (helper, privateKey) => {
268 const donor = privateKey('//Alice');
315 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);269 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
316 });270 });
317 });271 });
318272
319 it('NFT', async () => {273 itSub('NFT', async ({helper}) => {
320 await usingPlaygrounds(async (helper) => {
321 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});274 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
322 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});275 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
323 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});276 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
324 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;277 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;
325 await helper.signTransaction(alice, helper.api?.tx.unique.approve({Substrate: bob.address}, collectionId, tokenId, 0));278 await helper.signTransaction(alice, helper.api?.tx.unique.approve({Substrate: bob.address}, collectionId, tokenId, 0));
326 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;279 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;
327 const transferTokenFromTx = async () => helper.nft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: bob.address});280 const transferTokenFromTx = async () => helper.nft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: bob.address});
328 await expect(transferTokenFromTx()).to.be.rejected;281 await expect(transferTokenFromTx()).to.be.rejected;
329 });
330 });282 });
331283
332 it('Fungible', async () => {284 itSub('Fungible', async ({helper}) => {
333 await usingPlaygrounds(async (helper) => {
334 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);285 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
335 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);286 await helper.ft.mintTokens(alice, collectionId, 10n, alice.address);
336 const tokenId = await helper.ft.getLastTokenId(collectionId);287 const tokenId = await helper.ft.getLastTokenId(collectionId);
337 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});288 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
338 const amountBefore = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});289 const amountBefore = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
339 expect(amountBefore).to.be.equal(BigInt(1));290 expect(amountBefore).to.be.equal(BigInt(1));
340291
341 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);292 await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
342 const amountAfter = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});293 const amountAfter = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
343 expect(amountAfter).to.be.equal(BigInt(0));294 expect(amountAfter).to.be.equal(BigInt(0));
344295
345 const transferTokenFromTx = async () => helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address}, 1n);296 const transferTokenFromTx = async () => helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address}, 1n);
346 await expect(transferTokenFromTx()).to.be.rejected;297 await expect(transferTokenFromTx()).to.be.rejected;
347 });
348 });298 });
349299
350 it('ReFungible', async function() {300 itSub.ifWithPallets('ReFungible', [Pallets.ReFungible], async ({helper}) => {
351 await usingPlaygrounds(async (helper) => {
352 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});301 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
353 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});302 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
354 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});303 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
355 const amountBefore = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});304 const amountBefore = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
356 expect(amountBefore).to.be.equal(BigInt(1));305 expect(amountBefore).to.be.equal(BigInt(1));
357306
358 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);307 await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
359 const amountAfter = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});308 const amountAfter = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
360 expect(amountAfter).to.be.equal(BigInt(0));309 expect(amountAfter).to.be.equal(BigInt(0));
361310
362 const transferTokenFromTx = async () => helper.rft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address}, 100n);311 const transferTokenFromTx = async () => helper.rft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address}, 100n);
363 await expect(transferTokenFromTx()).to.be.rejected;312 await expect(transferTokenFromTx()).to.be.rejected;
364 });
365 });313 });
366});314});
367315
371 let charlie: IKeyringPair;319 let charlie: IKeyringPair;
372320
373 before(async () => {321 before(async () => {
374 await usingPlaygrounds(async (helper) => {322 await usingPlaygrounds(async (helper, privateKey) => {
323 const donor = privateKey('//Alice');
375 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);324 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
376 });325 });
377 });326 });
378327
379 it('1 for NFT', async () => {328 itSub('1 for NFT', async ({helper}) => {
380 await usingPlaygrounds(async (helper) => {
381 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});329 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
382 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});330 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
383 const approveTx = async () => helper.signTransaction(bob, helper.api?.tx.unique.approve({Substrate: charlie.address}, collectionId, tokenId, 2));331 const approveTx = async () => helper.signTransaction(bob, helper.api?.tx.unique.approve({Substrate: charlie.address}, collectionId, tokenId, 2));
384 await expect(approveTx()).to.be.rejected;332 await expect(approveTx()).to.be.rejected;
385 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: charlie.address})).to.be.false;333 expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: charlie.address})).to.be.false;
386 });
387 });334 });
388335
389 it('Fungible', async () => {336 itSub('Fungible', async ({helper}) => {
390 await usingPlaygrounds(async (helper) => {
391 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);337 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
392 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);338 await helper.ft.mintTokens(alice, collectionId, 10n, alice.address);
393 const tokenId = await helper.ft.getLastTokenId(collectionId);339 const tokenId = await helper.ft.getLastTokenId(collectionId);
394 const approveTx = async () => helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 11n);340 const approveTx = async () => helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 11n);
395 await expect(approveTx()).to.be.rejected;341 await expect(approveTx()).to.be.rejected;
396 });
397 });342 });
398343
399 it('ReFungible', async function() {344 itSub.ifWithPallets('ReFungible', [Pallets.ReFungible], async ({helper}) => {
400 await usingPlaygrounds(async (helper) => {
401 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});345 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
402 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});346 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
403 const approveTx = async () => helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 101n);347 const approveTx = async () => helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 101n);
404 await expect(approveTx()).to.be.rejected;348 await expect(approveTx()).to.be.rejected;
405 });
406 });349 });
407});350});
408351
413 let dave: IKeyringPair;356 let dave: IKeyringPair;
414357
415 before(async () => {358 before(async () => {
416 await usingPlaygrounds(async (helper) => {359 await usingPlaygrounds(async (helper, privateKey) => {
360 const donor = privateKey('//Alice');
417 [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);361 [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);
418 });362 });
419 });363 });
420364
421 it('NFT', async () => {365 itSub('NFT', async ({helper}) => {
422 await usingPlaygrounds(async (helper) => {
423 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});366 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
424 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});367 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
425 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: charlie.address});368 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: charlie.address});
426369
427 await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address});370 await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address});
428 const owner1 = await helper.nft.getTokenOwner(collectionId, tokenId);371 const owner1 = await helper.nft.getTokenOwner(collectionId, tokenId);
429 expect(owner1.Substrate).to.be.equal(dave.address);372 expect(owner1.Substrate).to.be.equal(dave.address);
430373
431 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});374 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
432 await helper.nft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address});375 await helper.nft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address});
433 const owner2 = await helper.nft.getTokenOwner(collectionId, tokenId);376 const owner2 = await helper.nft.getTokenOwner(collectionId, tokenId);
434 expect(owner2.Substrate).to.be.equal(alice.address);377 expect(owner2.Substrate).to.be.equal(alice.address);
435 });
436 });378 });
437379
438 it('Fungible up to an approved amount', async () => {380 itSub('Fungible up to an approved amount', async ({helper}) => {
439 await usingPlaygrounds(async (helper) => {
440 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);381 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
441 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});382 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
442 await helper.ft.mintTokens(alice, collectionId, charlie.address, 10n);383 await helper.ft.mintTokens(alice, collectionId, 10n, charlie.address);
443 const tokenId = await helper.ft.getLastTokenId(collectionId);384 const tokenId = await helper.ft.getLastTokenId(collectionId);
444385
445 const daveBalanceBefore = await helper.ft.getBalance(collectionId, {Substrate: dave.address});386 const daveBalanceBefore = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
446 await helper.ft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address}, 1n);387 await helper.ft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address}, 1n);
447 const daveBalanceAfter = await helper.ft.getBalance(collectionId, {Substrate: dave.address});388 const daveBalanceAfter = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
448 expect(daveBalanceAfter - daveBalanceBefore).to.be.equal(BigInt(1));389 expect(daveBalanceAfter - daveBalanceBefore).to.be.equal(BigInt(1));
449390
450 await helper.collection.addAdmin(alice ,collectionId, {Substrate: bob.address});391 await helper.collection.addAdmin(alice ,collectionId, {Substrate: bob.address});
451392
452 const aliceBalanceBefore = await helper.ft.getBalance(collectionId, {Substrate: alice.address});393 const aliceBalanceBefore = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
453 await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address}, 1n);394 await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address}, 1n);
454 const aliceBalanceAfter = await helper.ft.getBalance(collectionId, {Substrate: alice.address});395 const aliceBalanceAfter = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
455 expect(aliceBalanceAfter - aliceBalanceBefore).to.be.equal(BigInt(1));396 expect(aliceBalanceAfter - aliceBalanceBefore).to.be.equal(BigInt(1));
456 });
457 });397 });
458398
459 it('ReFungible up to an approved amount', async function() {399 itSub.ifWithPallets('ReFungible up to an approved amount', [Pallets.ReFungible], async ({helper}) => {
460 await usingPlaygrounds(async (helper) => {
461 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});400 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
462 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});401 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
463 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: charlie.address, pieces: 100n});402 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: charlie.address, pieces: 100n});
464403
465 const daveBefore = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: dave.address});404 const daveBefore = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: dave.address});
466 await helper.rft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address}, 1n);405 await helper.rft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address}, 1n);
467 const daveAfter = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: dave.address});406 const daveAfter = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: dave.address});
468 expect(daveAfter - daveBefore).to.be.equal(BigInt(1));407 expect(daveAfter - daveBefore).to.be.equal(BigInt(1));
469408
470 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});409 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
471410
472 const aliceBefore = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});411 const aliceBefore = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
473 await helper.rft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address}, 1n);412 await helper.rft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address}, 1n);
474 const aliceAfter = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});413 const aliceAfter = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
475 expect(aliceAfter - aliceBefore).to.be.equal(BigInt(1));414 expect(aliceAfter - aliceBefore).to.be.equal(BigInt(1));
476 });
477 });415 });
478});416});
479417
484 let dave: IKeyringPair;422 let dave: IKeyringPair;
485423
486 before(async () => {424 before(async () => {
487 await usingPlaygrounds(async (helper) => {425 await usingPlaygrounds(async (helper, privateKey) => {
426 const donor = privateKey('//Alice');
488 [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);427 [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);
489 });428 });
490 });429 });
491430
492 it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. Fungible', async () => {431 itSub.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. Fungible', async ({helper}) => {
493 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});432 const collection = await helper.ft.mintCollection(alice, {});
494 await createItemExpectSuccess(alice, collectionId, 'Fungible', alice.address);433 await collection.mint(alice, 10n);
495 await approveExpectSuccess(collectionId, 0, alice, bob.address, 1);434 await collection.approveTokens(alice, {Substrate: bob.address}, 1n);
496 await approveExpectSuccess(collectionId, 0, alice, charlie.address, 1);435 await collection.approveTokens(alice, {Substrate: charlie.address}, 1n);
497 // const allowances1 = await getAllowance(collectionId, 0, Alice.address, Bob.address);436 // const allowances1 = await getAllowance(collectionId, 0, Alice.address, Bob.address);
498 // const allowances2 = await getAllowance(collectionId, 0, Alice.address, Charlie.address);437 // const allowances2 = await getAllowance(collectionId, 0, Alice.address, Charlie.address);
499 // expect(allowances1 + allowances2).to.be.eq(BigInt(2));438 // expect(allowances1 + allowances2).to.be.eq(BigInt(2));
500 });439 });
501440
502 it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. ReFungible', async () => {441 itSub.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. ReFungible', async ({helper}) => {
503 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});442 const collection = await helper.rft.mintCollection(alice, {});
504 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', alice.address);443 const token = await collection.mintToken(alice, 10n);
505 await approveExpectSuccess(collectionId, itemId, alice, bob.address, 1);444 await token.approve(alice, {Substrate: bob.address}, 1n);
506 await approveExpectSuccess(collectionId, itemId, alice, charlie.address, 1);445 await token.approve(alice, {Substrate: charlie.address}, 1n);
507 // const allowances1 = await getAllowance(collectionId, itemId, Alice.address, Bob.address);446 // const allowances1 = await getAllowance(collectionId, itemId, Alice.address, Bob.address);
508 // const allowances2 = await getAllowance(collectionId, itemId, Alice.address, Charlie.address);447 // const allowances2 = await getAllowance(collectionId, itemId, Alice.address, Charlie.address);
509 // expect(allowances1 + allowances2).to.be.eq(BigInt(2));448 // expect(allowances1 + allowances2).to.be.eq(BigInt(2));
510 });449 });
511450
512 // Canceled by changing approve logic451 // Canceled by changing approve logic
513 it.skip('Cannot approve for more than total user`s amount (owned: 10, approval 1: 5 - should succeed, approval 2: 6 - should fail). Fungible', async () => {452 itSub.skip('Cannot approve for more than total user\'s amount (owned: 10, approval 1: 5 - should succeed, approval 2: 6 - should fail). Fungible', async ({helper}) => {
514 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});453 const collection = await helper.ft.mintCollection(alice, {});
515 await createItemExpectSuccess(alice, collectionId, 'Fungible', dave.address);454 await collection.mint(alice, 10n, {Substrate: dave.address});
516 await approveExpectSuccess(collectionId, 0, dave, bob.address, 5);455 await collection.approveTokens(dave, {Substrate: bob.address}, 5n);
517 await approveExpectFail(collectionId, 0, dave, charlie, 6);456 await expect(collection.approveTokens(dave, {Substrate: charlie.address}, 6n))
457 .to.be.rejectedWith('this test would fail (since it is skipped), replace this expecting message with what would have been received');
518 });458 });
519459
520 // Canceled by changing approve logic460 // Canceled by changing approve logic
521 it.skip('Cannot approve for more than total users amount (owned: 100, approval 1: 50 - should succeed, approval 2: 51 - should fail). ReFungible', async () => {461 itSub.skip('Cannot approve for more than total user\'s amount (owned: 100, approval 1: 50 - should succeed, approval 2: 51 - should fail). ReFungible', async ({helper}) => {
522 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});462 const collection = await helper.rft.mintCollection(alice, {});
523 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', dave.address);463 const token = await collection.mintToken(alice, 100n, {Substrate: dave.address});
524 await approveExpectSuccess(collectionId, itemId, dave, bob.address, 50);464 await token.approve(dave, {Substrate: bob.address}, 50n);
525 await approveExpectFail(collectionId, itemId, dave, charlie, 51);465 await expect(token.approve(dave, {Substrate: charlie.address}, 51n))
466 .to.be.rejectedWith('this test would fail (since it is skipped), replace this expecting message with what would have been received');
526 });467 });
527});468});
528469
532 let charlie: IKeyringPair;473 let charlie: IKeyringPair;
533474
534 before(async () => {475 before(async () => {
535 await usingPlaygrounds(async (helper) => {476 await usingPlaygrounds(async (helper, privateKey) => {
477 const donor = privateKey('//Alice');
536 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);478 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
537 });479 });
538 });480 });
539481
540 it('can be called by collection admin on non-owned item', async () => {482 itSub('can be called by collection admin on non-owned item', async ({helper}) => {
541 await usingPlaygrounds(async (helper) => {
542 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});483 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
543 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});484 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
544 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});485 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
545 const approveTx = async () => helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});486 const approveTx = async () => helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
546 await expect(approveTx()).to.be.rejected;487 await expect(approveTx()).to.be.rejected;
547 });
548 });488 });
549});489});
550490
554 let charlie: IKeyringPair;494 let charlie: IKeyringPair;
555495
556 before(async () => {496 before(async () => {
557 await usingPlaygrounds(async (helper) => {497 await usingPlaygrounds(async (helper, privateKey) => {
498 const donor = privateKey('//Alice');
558 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);499 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
559 });500 });
560 });501 });
561502
562 it('[nft] Approve for a collection that does not exist', async () => {503 itSub('[nft] Approve for a collection that does not exist', async ({helper}) => {
563 await usingPlaygrounds(async (helper) => {
564 const collectionId = 1 << 32 - 1;504 const collectionId = 1 << 32 - 1;
565 const approveTx = async () => helper.nft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});505 const approveTx = async () => helper.nft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});
566 await expect(approveTx()).to.be.rejected;506 await expect(approveTx()).to.be.rejected;
567 });
568 });507 });
569508
570 it('[fungible] Approve for a collection that does not exist', async () => {509 itSub('[fungible] Approve for a collection that does not exist', async ({helper}) => {
571 await usingPlaygrounds(async (helper) => {
572 const collectionId = 1 << 32 - 1;510 const collectionId = 1 << 32 - 1;
573 const approveTx = async () => helper.ft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});511 const approveTx = async () => helper.ft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});
574 await expect(approveTx()).to.be.rejected;512 await expect(approveTx()).to.be.rejected;
575 });
576 });513 });
577514
578 it('[refungible] Approve for a collection that does not exist', async function() {515 itSub.ifWithPallets('[refungible] Approve for a collection that does not exist', [Pallets.ReFungible], async ({helper}) => {
579 await usingPlaygrounds(async (helper) => {
580 const collectionId = 1 << 32 - 1;516 const collectionId = 1 << 32 - 1;
581 const approveTx = async () => helper.rft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});517 const approveTx = async () => helper.rft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});
582 await expect(approveTx()).to.be.rejected;518 await expect(approveTx()).to.be.rejected;
583 });
584 });519 });
585520
586 it('[nft] Approve for a collection that was destroyed', async () => {521 itSub('[nft] Approve for a collection that was destroyed', async ({helper}) => {
587 await usingPlaygrounds(async (helper) => {
588 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});522 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
589 await helper.nft.burn(alice, collectionId);523 await helper.nft.burn(alice, collectionId);
590 const approveTx = async () => helper.nft.approveToken(alice, collectionId, 1, {Substrate: bob.address});524 const approveTx = async () => helper.nft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
591 await expect(approveTx()).to.be.rejected;525 await expect(approveTx()).to.be.rejected;
592 });
593 });526 });
594527
595 it('[fungible] Approve for a collection that was destroyed', async () => {528 itSub('[fungible] Approve for a collection that was destroyed', async ({helper}) => {
596 await usingPlaygrounds(async (helper) => {
597 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});529 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
598 await helper.ft.burn(alice, collectionId);530 await helper.ft.burn(alice, collectionId);
599 const approveTx = async () => helper.ft.approveToken(alice, collectionId, 1, {Substrate: bob.address});531 const approveTx = async () => helper.ft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
600 await expect(approveTx()).to.be.rejected;532 await expect(approveTx()).to.be.rejected;
601 });
602 });533 });
603534
604 it('[refungible] Approve for a collection that was destroyed', async function() {535 itSub.ifWithPallets('[refungible] Approve for a collection that was destroyed', [Pallets.ReFungible], async ({helper}) => {
605 await usingPlaygrounds(async (helper) => {
606 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});536 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
607 await helper.rft.burn(alice, collectionId);537 await helper.rft.burn(alice, collectionId);
608 const approveTx = async () => helper.rft.approveToken(alice, collectionId, 1, {Substrate: bob.address});538 const approveTx = async () => helper.rft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
609 await expect(approveTx()).to.be.rejected;539 await expect(approveTx()).to.be.rejected;
610 });
611 });540 });
612541
613 it('[nft] Approve transfer of a token that does not exist', async () => {542 itSub('[nft] Approve transfer of a token that does not exist', async ({helper}) => {
614 await usingPlaygrounds(async (helper) => {
615 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});543 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
616 const approveTx = async () => helper.nft.approveToken(alice, collectionId, 2, {Substrate: bob.address});544 const approveTx = async () => helper.nft.approveToken(alice, collectionId, 2, {Substrate: bob.address});
617 await expect(approveTx()).to.be.rejected;545 await expect(approveTx()).to.be.rejected;
618 });
619 });546 });
620547
621 it('[refungible] Approve transfer of a token that does not exist', async function() {548 itSub.ifWithPallets('[refungible] Approve transfer of a token that does not exist', [Pallets.ReFungible], async ({helper}) => {
622 await usingPlaygrounds(async (helper) => {
623 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});549 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
624 const approveTx = async () => helper.rft.approveToken(alice, collectionId, 2, {Substrate: bob.address});550 const approveTx = async () => helper.rft.approveToken(alice, collectionId, 2, {Substrate: bob.address});
625 await expect(approveTx()).to.be.rejected;551 await expect(approveTx()).to.be.rejected;
626 });
627 });552 });
628553
629 it('[nft] Approve using the address that does not own the approved token', async () => {554 itSub('[nft] Approve using the address that does not own the approved token', async ({helper}) => {
630 await usingPlaygrounds(async (helper) => {
631 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});555 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
632 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});556 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
633 const approveTx = async () => helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});557 const approveTx = async () => helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});
634 await expect(approveTx()).to.be.rejected;558 await expect(approveTx()).to.be.rejected;
635 });
636 });559 });
637560
638 it('[fungible] Approve using the address that does not own the approved token', async () => {561 itSub('[fungible] Approve using the address that does not own the approved token', async ({helper}) => {
639 await usingPlaygrounds(async (helper) => {
640 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});562 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
641 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);563 await helper.ft.mintTokens(alice, collectionId, 10n, alice.address);
642 const tokenId = await helper.ft.getLastTokenId(collectionId);564 const tokenId = await helper.ft.getLastTokenId(collectionId);
643 const approveTx = async () => helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});565 const approveTx = async () => helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});
644 await expect(approveTx()).to.be.rejected;566 await expect(approveTx()).to.be.rejected;
645 });
646 });567 });
647568
648 it('[refungible] Approve using the address that does not own the approved token', async function() {569 itSub.ifWithPallets('[refungible] Approve using the address that does not own the approved token', [Pallets.ReFungible], async ({helper}) => {
649 await usingPlaygrounds(async (helper) => {
650 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});570 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
651 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});571 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
652 const approveTx = async () => helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});572 const approveTx = async () => helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});
653 await expect(approveTx()).to.be.rejected;573 await expect(approveTx()).to.be.rejected;
654 });
655 });574 });
656575
657 it('should fail if approved more ReFungibles than owned', async function() {576 itSub.ifWithPallets('should fail if approved more ReFungibles than owned', [Pallets.ReFungible], async ({helper}) => {
658 await usingPlaygrounds(async (helper) => {
659 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});577 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
660 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});578 const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
661 await helper.rft.transferToken(alice, collectionId, tokenId, {Substrate: bob.address}, 100n);579 await helper.rft.transferToken(alice, collectionId, tokenId, {Substrate: bob.address}, 100n);
662 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 100n);580 await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 100n);
663581
664 const approveTx = async () => helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 101n);582 const approveTx = async () => helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 101n);
665 await expect(approveTx()).to.be.rejected;583 await expect(approveTx()).to.be.rejected;
666 });
667 });584 });
668585
669 it('should fail if approved more Fungibles than owned', async () => {586 itSub('should fail if approved more Fungibles than owned', async ({helper}) => {
670 await usingPlaygrounds(async (helper) => {
671 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});587 const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
672 await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);588 await helper.ft.mintTokens(alice, collectionId, 10n, alice.address);
673 const tokenId = await helper.ft.getLastTokenId(collectionId);589 const tokenId = await helper.ft.getLastTokenId(collectionId);
674590
675 await helper.ft.transferToken(alice, collectionId, tokenId, {Substrate: bob.address}, 10n);591 await helper.ft.transferToken(alice, collectionId, tokenId, {Substrate: bob.address}, 10n);
676 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 10n);592 await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 10n);
677 const approveTx = async () => helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 11n);593 const approveTx = async () => helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 11n);
678 await expect(approveTx()).to.be.rejected;594 await expect(approveTx()).to.be.rejected;
679 });
680 });595 });
681596
682 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {597 itSub('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
683 await usingPlaygrounds(async (helper) => {
684 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});598 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
685 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});599 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
686 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: false});600 await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: false});
687601
688 const approveTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});602 const approveTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
689 await expect(approveTx()).to.be.rejected;603 await expect(approveTx()).to.be.rejected;
690 });
691 });604 });
692});605});
693606
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';
17import {expect} from 'chai';18import {expect} from 'chai';
19import {isAllowlisted, normalizeAccountId} from '../util/helpers';
18import {contractHelpers, createEthAccountWithBalance, deployFlipper, itWeb3} from './util/helpers';20import {
21 contractHelpers,
22 createEthAccount,
23 createEthAccountWithBalance,
24 deployFlipper,
25 evmCollection,
26 evmCollectionHelpers,
27 getCollectionAddressFromResult,
28 itWeb3,
29} from './util/helpers';
30import {itEth, usingEthPlaygrounds} from './util/playgrounds';
1931
20describe('EVM allowlist', () => {32describe('EVM contract allowlist', () => {
21 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {33 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {
22 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);34 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
23 const flipper = await deployFlipper(web3, owner);35 const flipper = await deployFlipper(web3, owner);
59 });71 });
60});72});
73
74describe('EVM collection allowlist', () => {
75 let donor: IKeyringPair;
76
77 before(async function() {
78 await usingEthPlaygrounds(async (_helper, privateKey) => {
79 donor = privateKey('//Alice');
80 });
81 });
82
83 itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => {
84 const owner = await helper.eth.createAccountWithBalance(donor);
85 const user = helper.eth.createAccount();
86
87 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
88 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
89
90 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
91 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
92 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
93
94 await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner});
95 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
96 });
97
98 itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {
99 const owner = await helper.eth.createAccountWithBalance(donor);
100 const user = donor;
101
102 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
103 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
104
105 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
106 await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
107 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
108
109 await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
110 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
111 });
112
113 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {
114 const owner = await helper.eth.createAccountWithBalance(donor);
115 const notOwner = await helper.eth.createAccountWithBalance(donor);
116 const user = helper.eth.createAccount();
117
118 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
119 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
120
121 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
122 await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
123 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
124 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
125
126 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
127 await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
128 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
129 });
130
131 itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {
132 const owner = await helper.eth.createAccountWithBalance(donor);
133 const notOwner = await helper.eth.createAccountWithBalance(donor);
134 const user = donor;
135
136 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
137 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
138
139 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
140 await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
141 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
142 await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
143
144 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
145 await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
146 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
147 });
148});
61149
modifiedtests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth
21}18}
2219
23/// @title Contract, which allows users to operate with collections20/// @title Contract, which allows users to operate with collections
24/// @dev the ERC-165 identifier for this interface is 0x675f307421/// @dev the ERC-165 identifier for this interface is 0x88ee8ef1
25interface CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {22interface CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
26 /// Create an NFT collection23 /// Create an NFT collection
27 /// @param name Name of the collection24 /// @param name Name of the collection
45 string memory baseUri42 string memory baseUri
46 ) external returns (address);43 ) external returns (address);
4744
48 /// @dev EVM selector for this function is: 0x44a68ad5,45 /// @dev EVM selector for this function is: 0xab173450,
49 /// or in textual repr: createRefungibleCollection(string,string,string)46 /// or in textual repr: createRFTCollection(string,string,string)
50 function createRefungibleCollection(47 function createRFTCollection(
51 string memory name,48 string memory name,
52 string memory description,49 string memory description,
53 string memory tokenPrefix50 string memory tokenPrefix
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
23}23}
2424
25/// @title Magic contract, which allows users to reconfigure other contracts25/// @title Magic contract, which allows users to reconfigure other contracts
26/// @dev the ERC-165 identifier for this interface is 0xd77fab7026/// @dev the ERC-165 identifier for this interface is 0x172cb4fb
27interface ContractHelpers is Dummy, ERC165, ContractHelpersEvents {27interface ContractHelpers is Dummy, ERC165, ContractHelpersEvents {
28 /// Get user, which deployed specified contract28 /// Get user, which deployed specified contract
29 /// @dev May return zero address in case if contract is deployed29 /// @dev May return zero address in case if contract is deployed
111 function setSponsoringMode(address contractAddress, uint8 mode) external;111 function setSponsoringMode(address contractAddress, uint8 mode) external;
112112
113 /// Get current contract sponsoring rate limit113 /// Get current contract sponsoring rate limit
114 /// @param contractAddress Contract to get sponsoring mode of114 /// @param contractAddress Contract to get sponsoring rate limit of
115 /// @return uint32 Amount of blocks between two sponsored transactions115 /// @return uint32 Amount of blocks between two sponsored transactions
116 /// @dev EVM selector for this function is: 0x610cfabd,116 /// @dev EVM selector for this function is: 0x610cfabd,
117 /// or in textual repr: getSponsoringRateLimit(address)117 /// or in textual repr: getSponsoringRateLimit(address)
131 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)131 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
132 external;132 external;
133
134 /// Set contract sponsoring fee limit
135 /// @dev Sponsoring fee limit - is maximum fee that could be spent by
136 /// single transaction
137 /// @param contractAddress Contract to change sponsoring fee limit of
138 /// @param feeLimit Fee limit
139 /// @dev Only contract owner can change this setting
140 /// @dev EVM selector for this function is: 0x03aed665,
141 /// or in textual repr: setSponsoringFeeLimit(address,uint256)
142 function setSponsoringFeeLimit(address contractAddress, uint256 feeLimit)
143 external;
144
145 /// Get current contract sponsoring fee limit
146 /// @param contractAddress Contract to get sponsoring fee limit of
147 /// @return uint256 Maximum amount of fee that could be spent by single
148 /// transaction
149 /// @dev EVM selector for this function is: 0xc3fdc9ee,
150 /// or in textual repr: getSponsoringFeeLimit(address)
151 function getSponsoringFeeLimit(address contractAddress)
152 external
153 view
154 returns (uint256);
133155
134 /// Is specified user present in contract allow list156 /// Is specified user present in contract allow list
135 /// @dev Contract owner always implicitly included157 /// @dev Contract owner always implicitly included
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows you to work with collections.15/// @title A contract that allows you to work with collections.
16/// @dev the ERC-165 identifier for this interface is 0xe54be64016/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
17interface Collection is Dummy, ERC165 {17interface Collection is Dummy, ERC165 {
18 /// Set collection property.18 /// Set collection property.
19 ///19 ///
164 /// or in textual repr: setCollectionAccess(uint8)164 /// or in textual repr: setCollectionAccess(uint8)
165 function setCollectionAccess(uint8 mode) external;165 function setCollectionAccess(uint8 mode) external;
166
167 /// Checks that user allowed to operate with collection.
168 ///
169 /// @param user User address to check.
170 /// @dev EVM selector for this function is: 0xd63a8e11,
171 /// or in textual repr: allowed(address)
172 function allowed(address user) external view returns (bool);
166173
167 /// Add the user to the allowed list.174 /// Add the user to the allowed list.
168 ///175 ///
171 /// or in textual repr: addToCollectionAllowList(address)178 /// or in textual repr: addToCollectionAllowList(address)
172 function addToCollectionAllowList(address user) external;179 function addToCollectionAllowList(address user) external;
180
181 /// Add substrate user to allowed list.
182 ///
183 /// @param user User substrate address.
184 /// @dev EVM selector for this function is: 0xd06ad267,
185 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
186 function addToCollectionAllowListSubstrate(uint256 user) external;
173187
174 /// Remove the user from the allowed list.188 /// Remove the user from the allowed list.
175 ///189 ///
178 /// or in textual repr: removeFromCollectionAllowList(address)192 /// or in textual repr: removeFromCollectionAllowList(address)
179 function removeFromCollectionAllowList(address user) external;193 function removeFromCollectionAllowList(address user) external;
194
195 /// Remove substrate user from allowed list.
196 ///
197 /// @param user User substrate address.
198 /// @dev EVM selector for this function is: 0xa31913ed,
199 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
200 function removeFromCollectionAllowListSubstrate(uint256 user) external;
180201
181 /// Switch permission for minting.202 /// Switch permission for minting.
182 ///203 ///
208 /// or in textual repr: uniqueCollectionType()229 /// or in textual repr: uniqueCollectionType()
209 function uniqueCollectionType() external returns (string memory);230 function uniqueCollectionType() external returns (string memory);
231
232 /// Get collection owner.
233 ///
234 /// @return Tuble with sponsor address and his substrate mirror.
235 /// If address is canonical then substrate mirror is zero and vice versa.
236 /// @dev EVM selector for this function is: 0xdf727d3b,
237 /// or in textual repr: collectionOwner()
238 function collectionOwner() external view returns (Tuple6 memory);
210239
211 /// Changes collection owner to another account240 /// Changes collection owner to another account
212 ///241 ///
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
65}65}
6666
67/// @title A contract that allows you to work with collections.67/// @title A contract that allows you to work with collections.
68/// @dev the ERC-165 identifier for this interface is 0xe54be64068/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
69interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {
70 /// Set collection property.70 /// Set collection property.
71 ///71 ///
216 /// or in textual repr: setCollectionAccess(uint8)216 /// or in textual repr: setCollectionAccess(uint8)
217 function setCollectionAccess(uint8 mode) external;217 function setCollectionAccess(uint8 mode) external;
218
219 /// Checks that user allowed to operate with collection.
220 ///
221 /// @param user User address to check.
222 /// @dev EVM selector for this function is: 0xd63a8e11,
223 /// or in textual repr: allowed(address)
224 function allowed(address user) external view returns (bool);
218225
219 /// Add the user to the allowed list.226 /// Add the user to the allowed list.
220 ///227 ///
223 /// or in textual repr: addToCollectionAllowList(address)230 /// or in textual repr: addToCollectionAllowList(address)
224 function addToCollectionAllowList(address user) external;231 function addToCollectionAllowList(address user) external;
232
233 /// Add substrate user to allowed list.
234 ///
235 /// @param user User substrate address.
236 /// @dev EVM selector for this function is: 0xd06ad267,
237 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
238 function addToCollectionAllowListSubstrate(uint256 user) external;
225239
226 /// Remove the user from the allowed list.240 /// Remove the user from the allowed list.
227 ///241 ///
230 /// or in textual repr: removeFromCollectionAllowList(address)244 /// or in textual repr: removeFromCollectionAllowList(address)
231 function removeFromCollectionAllowList(address user) external;245 function removeFromCollectionAllowList(address user) external;
246
247 /// Remove substrate user from allowed list.
248 ///
249 /// @param user User substrate address.
250 /// @dev EVM selector for this function is: 0xa31913ed,
251 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
252 function removeFromCollectionAllowListSubstrate(uint256 user) external;
232253
233 /// Switch permission for minting.254 /// Switch permission for minting.
234 ///255 ///
260 /// or in textual repr: uniqueCollectionType()281 /// or in textual repr: uniqueCollectionType()
261 function uniqueCollectionType() external returns (string memory);282 function uniqueCollectionType() external returns (string memory);
283
284 /// Get collection owner.
285 ///
286 /// @return Tuble with sponsor address and his substrate mirror.
287 /// If address is canonical then substrate mirror is zero and vice versa.
288 /// @dev EVM selector for this function is: 0xdf727d3b,
289 /// or in textual repr: collectionOwner()
290 function collectionOwner() external view returns (Tuple17 memory);
262291
263 /// Changes collection owner to another account292 /// Changes collection owner to another account
264 ///293 ///
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
65}65}
6666
67/// @title A contract that allows you to work with collections.67/// @title A contract that allows you to work with collections.
68/// @dev the ERC-165 identifier for this interface is 0xe54be64068/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
69interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {
70 /// Set collection property.70 /// Set collection property.
71 ///71 ///
216 /// or in textual repr: setCollectionAccess(uint8)216 /// or in textual repr: setCollectionAccess(uint8)
217 function setCollectionAccess(uint8 mode) external;217 function setCollectionAccess(uint8 mode) external;
218
219 /// Checks that user allowed to operate with collection.
220 ///
221 /// @param user User address to check.
222 /// @dev EVM selector for this function is: 0xd63a8e11,
223 /// or in textual repr: allowed(address)
224 function allowed(address user) external view returns (bool);
218225
219 /// Add the user to the allowed list.226 /// Add the user to the allowed list.
220 ///227 ///
223 /// or in textual repr: addToCollectionAllowList(address)230 /// or in textual repr: addToCollectionAllowList(address)
224 function addToCollectionAllowList(address user) external;231 function addToCollectionAllowList(address user) external;
232
233 /// Add substrate user to allowed list.
234 ///
235 /// @param user User substrate address.
236 /// @dev EVM selector for this function is: 0xd06ad267,
237 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
238 function addToCollectionAllowListSubstrate(uint256 user) external;
225239
226 /// Remove the user from the allowed list.240 /// Remove the user from the allowed list.
227 ///241 ///
230 /// or in textual repr: removeFromCollectionAllowList(address)244 /// or in textual repr: removeFromCollectionAllowList(address)
231 function removeFromCollectionAllowList(address user) external;245 function removeFromCollectionAllowList(address user) external;
246
247 /// Remove substrate user from allowed list.
248 ///
249 /// @param user User substrate address.
250 /// @dev EVM selector for this function is: 0xa31913ed,
251 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
252 function removeFromCollectionAllowListSubstrate(uint256 user) external;
232253
233 /// Switch permission for minting.254 /// Switch permission for minting.
234 ///255 ///
260 /// or in textual repr: uniqueCollectionType()281 /// or in textual repr: uniqueCollectionType()
261 function uniqueCollectionType() external returns (string memory);282 function uniqueCollectionType() external returns (string memory);
283
284 /// Get collection owner.
285 ///
286 /// @return Tuble with sponsor address and his substrate mirror.
287 /// If address is canonical then substrate mirror is zero and vice versa.
288 /// @dev EVM selector for this function is: 0xdf727d3b,
289 /// or in textual repr: collectionOwner()
290 function collectionOwner() external view returns (Tuple17 memory);
262291
263 /// Changes collection owner to another account292 /// Changes collection owner to another account
264 ///293 ///
modifiedtests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth
59 { "internalType": "string", "name": "description", "type": "string" },59 { "internalType": "string", "name": "description", "type": "string" },
60 { "internalType": "string", "name": "tokenPrefix", "type": "string" }60 { "internalType": "string", "name": "tokenPrefix", "type": "string" }
61 ],61 ],
62 "name": "createRefungibleCollection",62 "name": "createRFTCollection",
63 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],63 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
64 "stateMutability": "nonpayable",64 "stateMutability": "nonpayable",
65 "type": "function"65 "type": "function"
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import * as solc from 'solc';
17import {expect} from 'chai';18import {expect} from 'chai';
18import { expectSubstrateEventsAtBlock } from '../util/helpers';19import {expectSubstrateEventsAtBlock} from '../util/helpers';
20import Web3 from 'web3';
21
19import {22import {
20 contractHelpers,23 contractHelpers,
26 createEthAccount,29 createEthAccount,
27 ethBalanceViaSub,30 ethBalanceViaSub,
28 normalizeEvents,31 normalizeEvents,
32 CompiledContract,
33 GAS_ARGS,
34 subToEth,
29} from './util/helpers';35} from './util/helpers';
36import {submitTransactionAsync} from '../substrate/substrate-api';
3037
31describe('Sponsoring EVM contracts', () => {38describe('Sponsoring EVM contracts', () => {
32 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {39 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {
479 });486 });
480});487});
488
489describe('Sponsoring Fee Limit', () => {
490
491 let testContract: CompiledContract;
492
493 function compileTestContract() {
494 if (!testContract) {
495 const input = {
496 language: 'Solidity',
497 sources: {
498 ['TestContract.sol']: {
499 content:
500 `
501 // SPDX-License-Identifier: MIT
502 pragma solidity ^0.8.0;
503
504 contract TestContract {
505 event Result(bool);
506
507 function test(uint32 cycles) public {
508 uint256 counter = 0;
509 while(true) {
510 counter ++;
511 if (counter > cycles){
512 break;
513 }
514 }
515 emit Result(true);
516 }
517 }
518 `,
519 },
520 },
521 settings: {
522 outputSelection: {
523 '*': {
524 '*': ['*'],
525 },
526 },
527 },
528 };
529 const json = JSON.parse(solc.compile(JSON.stringify(input)));
530 const out = json.contracts['TestContract.sol']['TestContract'];
531
532 testContract = {
533 abi: out.abi,
534 object: '0x' + out.evm.bytecode.object,
535 };
536 }
537 return testContract;
538 }
539
540 async function deployTestContract(web3: Web3, owner: string) {
541 const compiled = compileTestContract();
542 const testContract = new web3.eth.Contract(compiled.abi, undefined, {
543 data: compiled.object,
544 from: owner,
545 ...GAS_ARGS,
546 });
547 return await testContract.deploy({data: compiled.object}).send({from: owner});
548 }
549
550 itWeb3('Default fee limit', async ({api, web3, privateKeyWrapper}) => {
551 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
552 const flipper = await deployFlipper(web3, owner);
553 const helpers = contractHelpers(web3, owner);
554 expect(await helpers.methods.getSponsoringFeeLimit(flipper.options.address).call()).to.be.equals('115792089237316195423570985008687907853269984665640564039457584007913129639935');
555 });
556
557 itWeb3('Set fee limit', async ({api, web3, privateKeyWrapper}) => {
558 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
559 const flipper = await deployFlipper(web3, owner);
560 const helpers = contractHelpers(web3, owner);
561 await helpers.methods.setSponsoringFeeLimit(flipper.options.address, 100).send();
562 expect(await helpers.methods.getSponsoringFeeLimit(flipper.options.address).call()).to.be.equals('100');
563 });
564
565 itWeb3('Negative test - set fee limit by non-owner', async ({api, web3, privateKeyWrapper}) => {
566 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
567 const stranger = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
568 const flipper = await deployFlipper(web3, owner);
569 const helpers = contractHelpers(web3, owner);
570 await expect(helpers.methods.setSponsoringFeeLimit(flipper.options.address, 100).send({from: stranger})).to.be.rejected;
571 });
572
573 itWeb3('Negative test - check that eth transactions exceeding fee limit are not executed', async ({api, web3, privateKeyWrapper}) => {
574 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
575 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
576 const user = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
577
578 const testContract = await deployTestContract(web3, owner);
579 const helpers = contractHelpers(web3, owner);
580
581 await helpers.methods.setSponsoringMode(testContract.options.address, SponsoringMode.Generous).send({from: owner});
582 await helpers.methods.setSponsoringRateLimit(testContract.options.address, 0).send({from: owner});
583
584 await helpers.methods.setSponsor(testContract.options.address, sponsor).send();
585 await helpers.methods.confirmSponsorship(testContract.options.address).send({from: sponsor});
586
587 const gasPrice = BigInt(await web3.eth.getGasPrice());
588
589 await helpers.methods.setSponsoringFeeLimit(testContract.options.address, 2_000_000n * gasPrice).send();
590
591 const originalUserBalance = await web3.eth.getBalance(user);
592 await testContract.methods.test(100).send({from: user, gas: 2_000_000});
593 expect(await web3.eth.getBalance(user)).to.be.equal(originalUserBalance);
594
595 await testContract.methods.test(100).send({from: user, gas: 2_100_000});
596 expect(await web3.eth.getBalance(user)).to.not.be.equal(originalUserBalance);
597 });
598
599 itWeb3('Negative test - check that evm.call transactions exceeding fee limit are not executed', async ({api, web3, privateKeyWrapper}) => {
600 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
601 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
602
603 const testContract = await deployTestContract(web3, owner);
604 const helpers = contractHelpers(web3, owner);
605
606 await helpers.methods.setSponsoringMode(testContract.options.address, SponsoringMode.Generous).send({from: owner});
607 await helpers.methods.setSponsoringRateLimit(testContract.options.address, 0).send({from: owner});
608
609 await helpers.methods.setSponsor(testContract.options.address, sponsor).send();
610 await helpers.methods.confirmSponsorship(testContract.options.address).send({from: sponsor});
611
612 const gasPrice = BigInt(await web3.eth.getGasPrice());
613
614 await helpers.methods.setSponsoringFeeLimit(testContract.options.address, 2_000_000n * gasPrice).send();
615
616 const alice = privateKeyWrapper('//Alice');
617 const originalAliceBalance = (await api.query.system.account(alice.address)).data.free.toBigInt();
618
619 await submitTransactionAsync(
620 alice,
621 api.tx.evm.call(
622 subToEth(alice.address),
623 testContract.options.address,
624 testContract.methods.test(100).encodeABI(),
625 Uint8Array.from([]),
626 2_000_000n,
627 gasPrice,
628 null,
629 null,
630 [],
631 ),
632 );
633 expect((await api.query.system.account(alice.address)).data.free.toBigInt()).to.be.equal(originalAliceBalance);
634
635 await submitTransactionAsync(
636 alice,
637 api.tx.evm.call(
638 subToEth(alice.address),
639 testContract.options.address,
640 testContract.methods.test(100).encodeABI(),
641 Uint8Array.from([]),
642 2_100_000n,
643 gasPrice,
644 null,
645 null,
646 [],
647 ),
648 );
649 expect((await api.query.system.account(alice.address)).data.free.toBigInt()).to.not.be.equal(originalAliceBalance);
650 });
651});
481652
modifiedtests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth
41 41
42 const collectionCountBefore = await getCreatedCollectionCount(api);42 const collectionCountBefore = await getCreatedCollectionCount(api);
43 const result = await collectionHelper.methods43 const result = await collectionHelper.methods
44 .createRefungibleCollection(collectionName, description, tokenPrefix)44 .createRFTCollection(collectionName, description, tokenPrefix)
45 .send();45 .send();
46 const collectionCountAfter = await getCreatedCollectionCount(api);46 const collectionCountAfter = await getCreatedCollectionCount(api);
47 47
65 .call()).to.be.false;65 .call()).to.be.false;
6666
67 await collectionHelpers.methods67 await collectionHelpers.methods
68 .createRefungibleCollection('A', 'A', 'A')68 .createRFTCollection('A', 'A', 'A')
69 .send();69 .send();
70 70
71 expect(await collectionHelpers.methods71 expect(await collectionHelpers.methods
76 itWeb3('Set sponsorship', async ({api, web3, privateKeyWrapper}) => {76 itWeb3('Set sponsorship', async ({api, web3, privateKeyWrapper}) => {
77 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);77 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
78 const collectionHelpers = evmCollectionHelpers(web3, owner);78 const collectionHelpers = evmCollectionHelpers(web3, owner);
79 let result = await collectionHelpers.methods.createRefungibleCollection('Sponsor collection', '1', '1').send();79 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send();
80 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);80 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
81 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);81 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
82 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});82 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
96 itWeb3('Set limits', async ({api, web3, privateKeyWrapper}) => {96 itWeb3('Set limits', async ({api, web3, privateKeyWrapper}) => {
97 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);97 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
98 const collectionHelpers = evmCollectionHelpers(web3, owner);98 const collectionHelpers = evmCollectionHelpers(web3, owner);
99 const result = await collectionHelpers.methods.createRefungibleCollection('Const collection', '5', '5').send();99 const result = await collectionHelpers.methods.createRFTCollection('Const collection', '5', '5').send();
100 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);100 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
101 const limits = {101 const limits = {
102 accountTokenOwnershipLimit: 1000,102 accountTokenOwnershipLimit: 1000,
141 .isCollectionExist(collectionAddressForNonexistentCollection).call())141 .isCollectionExist(collectionAddressForNonexistentCollection).call())
142 .to.be.false;142 .to.be.false;
143 143
144 const result = await collectionHelpers.methods.createRefungibleCollection('Collection address exist', '7', '7').send();144 const result = await collectionHelpers.methods.createRFTCollection('Collection address exist', '7', '7').send();
145 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);145 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
146 expect(await collectionHelpers.methods146 expect(await collectionHelpers.methods
147 .isCollectionExist(collectionIdAddress).call())147 .isCollectionExist(collectionIdAddress).call())
164 const tokenPrefix = 'A';164 const tokenPrefix = 'A';
165 165
166 await expect(helper.methods166 await expect(helper.methods
167 .createRefungibleCollection(collectionName, description, tokenPrefix)167 .createRFTCollection(collectionName, description, tokenPrefix)
168 .call()).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGHT);168 .call()).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGHT);
169 169
170 }170 }
174 const description = 'A'.repeat(MAX_DESCRIPTION_LENGHT + 1);174 const description = 'A'.repeat(MAX_DESCRIPTION_LENGHT + 1);
175 const tokenPrefix = 'A';175 const tokenPrefix = 'A';
176 await expect(helper.methods176 await expect(helper.methods
177 .createRefungibleCollection(collectionName, description, tokenPrefix)177 .createRFTCollection(collectionName, description, tokenPrefix)
178 .call()).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGHT);178 .call()).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGHT);
179 }179 }
180 { 180 {
183 const description = 'A';183 const description = 'A';
184 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGHT + 1);184 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGHT + 1);
185 await expect(helper.methods185 await expect(helper.methods
186 .createRefungibleCollection(collectionName, description, tokenPrefix)186 .createRFTCollection(collectionName, description, tokenPrefix)
187 .call()).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGHT);187 .call()).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGHT);
188 }188 }
189 });189 });
196 const tokenPrefix = 'A';196 const tokenPrefix = 'A';
197 197
198 await expect(helper.methods198 await expect(helper.methods
199 .createRefungibleCollection(collectionName, description, tokenPrefix)199 .createRFTCollection(collectionName, description, tokenPrefix)
200 .call()).to.be.rejectedWith('NotSufficientFounds');200 .call()).to.be.rejectedWith('NotSufficientFounds');
201 });201 });
202202
203 itWeb3('(!negative test!) Check owner', async ({api, web3, privateKeyWrapper}) => {203 itWeb3('(!negative test!) Check owner', async ({api, web3, privateKeyWrapper}) => {
204 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);204 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
205 const notOwner = createEthAccount(web3);205 const notOwner = createEthAccount(web3);
206 const collectionHelpers = evmCollectionHelpers(web3, owner);206 const collectionHelpers = evmCollectionHelpers(web3, owner);
207 const result = await collectionHelpers.methods.createRefungibleCollection('A', 'A', 'A').send();207 const result = await collectionHelpers.methods.createRFTCollection('A', 'A', 'A').send();
208 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);208 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
209 const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress, {type: 'ReFungible'});209 const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress, {type: 'ReFungible'});
210 const EXPECTED_ERROR = 'NoPermission';210 const EXPECTED_ERROR = 'NoPermission';
229 itWeb3('(!negative test!) Set limits', async ({api, web3, privateKeyWrapper}) => {229 itWeb3('(!negative test!) Set limits', async ({api, web3, privateKeyWrapper}) => {
230 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);230 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
231 const collectionHelpers = evmCollectionHelpers(web3, owner);231 const collectionHelpers = evmCollectionHelpers(web3, owner);
232 const result = await collectionHelpers.methods.createRefungibleCollection('Schema collection', 'A', 'A').send();232 const result = await collectionHelpers.methods.createRFTCollection('Schema collection', 'A', 'A').send();
233 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);233 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
234 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});234 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
235 await expect(collectionEvm.methods235 await expect(collectionEvm.methods
modifiedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth
84 "RFT collection is already set"
85 );
86 address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;84 address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;
87 rftCollection = CollectionHelpers(collectionHelpers).createRefungibleCollection(_name, _description, _tokenPrefix);85 rftCollection = CollectionHelpers(collectionHelpers).createRFTCollection(_name, _description, _tokenPrefix);
88 emit RFTCollectionSet(rftCollection);86 emit RFTCollectionSet(rftCollection);
89 }87 }
9088
modifiedtests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth
21import {readFile} from 'fs/promises';21import {readFile} from 'fs/promises';
22import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api';22import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api';
23import {getCreateCollectionResult, getCreateItemResult, UNIQUE, requirePallets, Pallets} from '../../util/helpers';23import {getCreateCollectionResult, getCreateItemResult, UNIQUE, requirePallets, Pallets} from '../../util/helpers';
24import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers';24import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRFTCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers';
25import {Contract} from 'web3-eth-contract';25import {Contract} from 'web3-eth-contract';
26import * as solc from 'solc';26import * as solc from 'solc';
2727
123 itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => {123 itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => {
124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
125 const fractionalizer = await deployFractionalizer(web3, owner);125 const fractionalizer = await deployFractionalizer(web3, owner);
126 const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);126 const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
127 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);127 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
128 await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();128 await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
129 const result = await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();129 const result = await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();
256256
257 itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => {257 itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => {
258 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);258 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
259 const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);259 const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
260 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);260 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
261261
262 const fractionalizer = await deployFractionalizer(web3, owner);262 const fractionalizer = await deployFractionalizer(web3, owner);
282 itWeb3('call setRFTCollection while not collection admin', async ({api, web3, privateKeyWrapper}) => {282 itWeb3('call setRFTCollection while not collection admin', async ({api, web3, privateKeyWrapper}) => {
283 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);283 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
284 const fractionalizer = await deployFractionalizer(web3, owner);284 const fractionalizer = await deployFractionalizer(web3, owner);
285 const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);285 const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
286286
287 await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())287 await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
288 .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);288 .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);
368 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);368 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
369369
370 const fractionalizer = await deployFractionalizer(web3, owner);370 const fractionalizer = await deployFractionalizer(web3, owner);
371 const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);371 const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
372 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);372 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
373 const rftTokenId = await refungibleContract.methods.nextTokenId().call();373 const rftTokenId = await refungibleContract.methods.nextTokenId().call();
374 await refungibleContract.methods.mint(owner, rftTokenId).send();374 await refungibleContract.methods.mint(owner, rftTokenId).send();
381 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);381 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
382382
383 const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);383 const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
384 const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);384 const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
385 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);385 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
386 const rftTokenId = await refungibleContract.methods.nextTokenId().call();386 const rftTokenId = await refungibleContract.methods.nextTokenId().call();
387 await refungibleContract.methods.mint(owner, rftTokenId).send();387 await refungibleContract.methods.mint(owner, rftTokenId).send();
392392
393 itWeb3('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({api, web3, privateKeyWrapper}) => {393 itWeb3('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({api, web3, privateKeyWrapper}) => {
394 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);394 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
395 const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);395 const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
396396
397 const fractionalizer = await deployFractionalizer(web3, owner);397 const fractionalizer = await deployFractionalizer(web3, owner);
398 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);398 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
modifiedtests/src/eth/fungibleAbi.jsondiffbeforeafterboth
76 "stateMutability": "nonpayable",76 "stateMutability": "nonpayable",
77 "type": "function"77 "type": "function"
78 },78 },
79 {
80 "inputs": [
81 { "internalType": "uint256", "name": "user", "type": "uint256" }
82 ],
83 "name": "addToCollectionAllowListSubstrate",
84 "outputs": [],
85 "stateMutability": "nonpayable",
86 "type": "function"
87 },
79 {88 {
80 "inputs": [89 "inputs": [
81 { "internalType": "address", "name": "owner", "type": "address" },90 { "internalType": "address", "name": "owner", "type": "address" },
86 "stateMutability": "view",95 "stateMutability": "view",
87 "type": "function"96 "type": "function"
88 },97 },
98 {
99 "inputs": [
100 { "internalType": "address", "name": "user", "type": "address" }
101 ],
102 "name": "allowed",
103 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
104 "stateMutability": "view",
105 "type": "function"
106 },
89 {107 {
90 "inputs": [108 "inputs": [
91 { "internalType": "address", "name": "spender", "type": "address" },109 { "internalType": "address", "name": "spender", "type": "address" },
115 "stateMutability": "nonpayable",133 "stateMutability": "nonpayable",
116 "type": "function"134 "type": "function"
117 },135 },
136 {
137 "inputs": [],
138 "name": "collectionOwner",
139 "outputs": [
140 {
141 "components": [
142 { "internalType": "address", "name": "field_0", "type": "address" },
143 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
144 ],
145 "internalType": "struct Tuple6",
146 "name": "",
147 "type": "tuple"
148 }
149 ],
150 "stateMutability": "view",
151 "type": "function"
152 },
118 {153 {
119 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],154 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
120 "name": "collectionProperty",155 "name": "collectionProperty",
260 "stateMutability": "nonpayable",295 "stateMutability": "nonpayable",
261 "type": "function"296 "type": "function"
262 },297 },
298 {
299 "inputs": [
300 { "internalType": "uint256", "name": "user", "type": "uint256" }
301 ],
302 "name": "removeFromCollectionAllowListSubstrate",
303 "outputs": [],
304 "stateMutability": "nonpayable",
305 "type": "function"
306 },
263 {307 {
264 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],308 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
265 "name": "setCollectionAccess",309 "name": "setCollectionAccess",
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
20 let donor: IKeyringPair;20 let donor: IKeyringPair;
2121
22 before(async function() {22 before(async function() {
23 await usingEthPlaygrounds(async (helper, privateKey) => {23 await usingEthPlaygrounds(async (_, privateKey) => {
24 donor = privateKey('//Alice');24 donor = privateKey('//Alice');
25 });25 });
26 });26 });
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
107 "stateMutability": "nonpayable",107 "stateMutability": "nonpayable",
108 "type": "function"108 "type": "function"
109 },109 },
110 {
111 "inputs": [
112 { "internalType": "uint256", "name": "user", "type": "uint256" }
113 ],
114 "name": "addToCollectionAllowListSubstrate",
115 "outputs": [],
116 "stateMutability": "nonpayable",
117 "type": "function"
118 },
119 {
120 "inputs": [
121 { "internalType": "address", "name": "user", "type": "address" }
122 ],
123 "name": "allowed",
124 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
125 "stateMutability": "view",
126 "type": "function"
127 },
110 {128 {
111 "inputs": [129 "inputs": [
112 { "internalType": "address", "name": "approved", "type": "address" },130 { "internalType": "address", "name": "approved", "type": "address" },
145 "stateMutability": "nonpayable",163 "stateMutability": "nonpayable",
146 "type": "function"164 "type": "function"
147 },165 },
166 {
167 "inputs": [],
168 "name": "collectionOwner",
169 "outputs": [
170 {
171 "components": [
172 { "internalType": "address", "name": "field_0", "type": "address" },
173 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
174 ],
175 "internalType": "struct Tuple17",
176 "name": "",
177 "type": "tuple"
178 }
179 ],
180 "stateMutability": "view",
181 "type": "function"
182 },
148 {183 {
149 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],184 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
150 "name": "collectionProperty",185 "name": "collectionProperty",
374 "stateMutability": "nonpayable",409 "stateMutability": "nonpayable",
375 "type": "function"410 "type": "function"
376 },411 },
412 {
413 "inputs": [
414 { "internalType": "uint256", "name": "user", "type": "uint256" }
415 ],
416 "name": "removeFromCollectionAllowListSubstrate",
417 "outputs": [],
418 "stateMutability": "nonpayable",
419 "type": "function"
420 },
377 {421 {
378 "inputs": [422 "inputs": [
379 { "internalType": "address", "name": "from", "type": "address" },423 { "internalType": "address", "name": "from", "type": "address" },
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
22 let donor: IKeyringPair;22 let donor: IKeyringPair;
2323
24 before(async function() {24 before(async function() {
25 await usingEthPlaygrounds(async (helper, privateKey) => {25 await usingEthPlaygrounds(async (_, privateKey) => {
26 donor = privateKey('//Alice');26 donor = privateKey('//Alice');
27 });27 });
28 });28 });
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
26 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {26 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
27 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);27 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
28 const helper = evmCollectionHelpers(web3, caller);28 const helper = evmCollectionHelpers(web3, caller);
29 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();29 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
30 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);30 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
31 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});31 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
32 const nextTokenId = await contract.methods.nextTokenId().call();32 const nextTokenId = await contract.methods.nextTokenId().call();
38 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {38 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {
39 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);39 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
40 const helper = evmCollectionHelpers(web3, caller);40 const helper = evmCollectionHelpers(web3, caller);
41 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();41 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
42 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);42 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
43 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});43 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
4444
63 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {63 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {
64 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);64 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
65 const helper = evmCollectionHelpers(web3, caller);65 const helper = evmCollectionHelpers(web3, caller);
66 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();66 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
67 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);67 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
68 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});68 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
6969
79 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);79 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
80 const receiver = createEthAccount(web3);80 const receiver = createEthAccount(web3);
81 const helper = evmCollectionHelpers(web3, caller);81 const helper = evmCollectionHelpers(web3, caller);
82 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();82 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
83 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);83 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
84 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});84 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
8585
103 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);103 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
104 const receiver = createEthAccount(web3);104 const receiver = createEthAccount(web3);
105 const helper = evmCollectionHelpers(web3, caller);105 const helper = evmCollectionHelpers(web3, caller);
106 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();106 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
107 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);107 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
108 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});108 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
109109
130 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {130 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
131 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);131 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
132 const helper = evmCollectionHelpers(web3, owner);132 const helper = evmCollectionHelpers(web3, owner);
133 let result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();133 let result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
134 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);134 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
135 const receiver = createEthAccount(web3);135 const receiver = createEthAccount(web3);
136 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});136 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
163 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {163 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {
164 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);164 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
165 const helper = evmCollectionHelpers(web3, caller);165 const helper = evmCollectionHelpers(web3, caller);
166 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();166 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
167 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);167 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
168 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});168 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
169169
221 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {221 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {
222 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);222 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
223 const helper = evmCollectionHelpers(web3, caller);223 const helper = evmCollectionHelpers(web3, caller);
224 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();224 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
225 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);225 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
226 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});226 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
227227
247 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {247 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {
248 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);248 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
249 const helper = evmCollectionHelpers(web3, caller);249 const helper = evmCollectionHelpers(web3, caller);
250 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();250 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
251 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);251 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
252 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});252 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
253253
304 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {304 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {
305 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);305 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
306 const helper = evmCollectionHelpers(web3, caller);306 const helper = evmCollectionHelpers(web3, caller);
307 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();307 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
308 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);308 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
309 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});309 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
310310
344 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);344 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
345 const receiver = createEthAccount(web3);345 const receiver = createEthAccount(web3);
346 const helper = evmCollectionHelpers(web3, caller);346 const helper = evmCollectionHelpers(web3, caller);
347 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();347 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
348 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);348 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
349 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});349 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
350350
376 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);376 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
377 const receiver = createEthAccount(web3);377 const receiver = createEthAccount(web3);
378 const helper = evmCollectionHelpers(web3, caller);378 const helper = evmCollectionHelpers(web3, caller);
379 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();379 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
380 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);380 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
381 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});381 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
382382
413 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {413 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
415 const helper = evmCollectionHelpers(web3, caller);415 const helper = evmCollectionHelpers(web3, caller);
416 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();416 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
417 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);417 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
418 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});418 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
419419
430 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {430 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
431 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);431 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
432 const helper = evmCollectionHelpers(web3, caller);432 const helper = evmCollectionHelpers(web3, caller);
433 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();433 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
434 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);434 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
435 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});435 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
436436
modifiedtests/src/eth/reFungibleAbi.jsondiffbeforeafterboth
107 "stateMutability": "nonpayable",107 "stateMutability": "nonpayable",
108 "type": "function"108 "type": "function"
109 },109 },
110 {
111 "inputs": [
112 { "internalType": "uint256", "name": "user", "type": "uint256" }
113 ],
114 "name": "addToCollectionAllowListSubstrate",
115 "outputs": [],
116 "stateMutability": "nonpayable",
117 "type": "function"
118 },
119 {
120 "inputs": [
121 { "internalType": "address", "name": "user", "type": "address" }
122 ],
123 "name": "allowed",
124 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
125 "stateMutability": "view",
126 "type": "function"
127 },
110 {128 {
111 "inputs": [129 "inputs": [
112 { "internalType": "address", "name": "approved", "type": "address" },130 { "internalType": "address", "name": "approved", "type": "address" },
145 "stateMutability": "nonpayable",163 "stateMutability": "nonpayable",
146 "type": "function"164 "type": "function"
147 },165 },
166 {
167 "inputs": [],
168 "name": "collectionOwner",
169 "outputs": [
170 {
171 "components": [
172 { "internalType": "address", "name": "field_0", "type": "address" },
173 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
174 ],
175 "internalType": "struct Tuple17",
176 "name": "",
177 "type": "tuple"
178 }
179 ],
180 "stateMutability": "view",
181 "type": "function"
182 },
148 {183 {
149 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],184 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
150 "name": "collectionProperty",185 "name": "collectionProperty",
374 "stateMutability": "nonpayable",409 "stateMutability": "nonpayable",
375 "type": "function"410 "type": "function"
376 },411 },
412 {
413 "inputs": [
414 { "internalType": "uint256", "name": "user", "type": "uint256" }
415 ],
416 "name": "removeFromCollectionAllowListSubstrate",
417 "outputs": [],
418 "stateMutability": "nonpayable",
419 "type": "function"
420 },
377 {421 {
378 "inputs": [422 "inputs": [
379 { "internalType": "address", "name": "from", "type": "address" },423 { "internalType": "address", "name": "from", "type": "address" },
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';
18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createRefungibleCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createRFTCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';
1919
20import chai from 'chai';20import chai from 'chai';
21import chaiAsPromised from 'chai-as-promised';21import chaiAsPromised from 'chai-as-promised';
458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
459 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);459 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
460 const helper = evmCollectionHelpers(web3, caller);460 const helper = evmCollectionHelpers(web3, caller);
461 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();461 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
462 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);462 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
463 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});463 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
464464
658 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {658 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {
659 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);659 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
660660
661 const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);661 const {collectionIdAddress, collectionId} = await createRFTCollection(api, web3, owner);
662 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);662 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
663 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();663 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();
664 await refungibleContract.methods.mint(owner, refungibleTokenId).send();664 await refungibleContract.methods.mint(owner, refungibleTokenId).send();
modifiedtests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth
126 "stateMutability": "view",126 "stateMutability": "view",
127 "type": "function"127 "type": "function"
128 },128 },
129 {
130 "inputs": [
131 {
132 "internalType": "address",
133 "name": "contractAddress",
134 "type": "address"
135 }
136 ],
137 "name": "getSponsoringFeeLimit",
138 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
139 "stateMutability": "view",
140 "type": "function"
141 },
129 {142 {
130 "inputs": [143 "inputs": [
131 {144 {
205 "stateMutability": "nonpayable",218 "stateMutability": "nonpayable",
206 "type": "function"219 "type": "function"
207 },220 },
221 {
222 "inputs": [
223 {
224 "internalType": "address",
225 "name": "contractAddress",
226 "type": "address"
227 },
228 { "internalType": "uint256", "name": "feeLimit", "type": "uint256" }
229 ],
230 "name": "setSponsoringFeeLimit",
231 "outputs": [],
232 "stateMutability": "nonpayable",
233 "type": "function"
234 },
208 {235 {
209 "inputs": [236 "inputs": [
210 {237 {
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
141 expect(result.success).to.be.true;141 expect(result.success).to.be.true;
142}142}
143143
144export async function createRefungibleCollection(api: ApiPromise, web3: Web3, owner: string) {144export async function createRFTCollection(api: ApiPromise, web3: Web3, owner: string) {
145 const collectionHelper = evmCollectionHelpers(web3, owner);145 const collectionHelper = evmCollectionHelpers(web3, owner);
146 const result = await collectionHelper.methods146 const result = await collectionHelper.methods
147 .createRefungibleCollection('A', 'B', 'C')147 .createRFTCollection('A', 'B', 'C')
148 .send();148 .send();
149 return await getCollectionAddressFromResult(api, result);149 return await getCollectionAddressFromResult(api, result);
150}150}
addedtests/src/eth/util/playgrounds/unique.dev.d.tsdiffbeforeafterboth

no changes

modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
2// SPDX-License-Identifier: Apache-2.02// SPDX-License-Identifier: Apache-2.0
33
4/* eslint-disable function-call-argument-newline */4/* eslint-disable function-call-argument-newline */
5// eslint-disable-next-line @typescript-eslint/triple-slash-reference
6/// <reference path="unique.dev.d.ts" />
57
6import {readFile} from 'fs/promises';8import {readFile} from 'fs/promises';
79
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import {U128_MAX} from './util/helpers';18import {U128_MAX} from './util/helpers';
19
20import {usingPlaygrounds} from './util/playgrounds';19import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
2120
22import chai from 'chai';21// todo:playgrounds get rid of globals
23import chaiAsPromised from 'chai-as-promised';
24chai.use(chaiAsPromised);
25const expect = chai.expect;
26
27let alice: IKeyringPair;22let alice: IKeyringPair;
28let bob: IKeyringPair;23let bob: IKeyringPair;
35 });30 });
36 });31 });
3732
38 it('Create fungible collection and token', async () => {33 itSub('Create fungible collection and token', async ({helper}) => {
39 await usingPlaygrounds(async helper => {
40 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});34 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
41 const defaultTokenId = await collection.getLastTokenId();35 const defaultTokenId = await collection.getLastTokenId();
42 expect(defaultTokenId).to.be.equal(0);36 expect(defaultTokenId).to.be.equal(0);
4337
44 await collection.mint(alice, {Substrate: alice.address}, U128_MAX);38 await collection.mint(alice, U128_MAX);
45 const aliceBalance = await collection.getBalance({Substrate: alice.address});39 const aliceBalance = await collection.getBalance({Substrate: alice.address});
46 const itemCountAfter = await collection.getLastTokenId();40 const itemCountAfter = await collection.getLastTokenId();
4741
48 expect(itemCountAfter).to.be.equal(defaultTokenId);42 expect(itemCountAfter).to.be.equal(defaultTokenId);
49 expect(aliceBalance).to.be.equal(U128_MAX);43 expect(aliceBalance).to.be.equal(U128_MAX);
50 });
51 });44 });
52 45
53 it('RPC method tokenOnewrs for fungible collection and token', async () => {46 itSub('RPC method tokenOnewrs for fungible collection and token', async ({helper, privateKey}) => {
54 await usingPlaygrounds(async (helper, privateKey) => {
55 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};47 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
56 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));48 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
5749
58 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});50 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
5951
60 await collection.mint(alice, {Substrate: alice.address}, U128_MAX);52 await collection.mint(alice, U128_MAX);
6153
62 await collection.transfer(alice, {Substrate: bob.address}, 1000n);54 await collection.transfer(alice, {Substrate: bob.address}, 1000n);
63 await collection.transfer(alice, ethAcc, 900n);55 await collection.transfer(alice, ethAcc, 900n);
75 const eleven = privateKey('//ALice+11');67 const eleven = privateKey('//ALice+11');
76 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;68 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
77 expect((await collection.getTop10Owners()).length).to.be.equal(10);69 expect((await collection.getTop10Owners()).length).to.be.equal(10);
78 });
79 });70 });
80 71
81 it('Transfer token', async () => {72 itSub('Transfer token', async ({helper}) => {
82 await usingPlaygrounds(async helper => {
83 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};73 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
84 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});74 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
85 await collection.mint(alice, {Substrate: alice.address}, 500n);75 await collection.mint(alice, 500n);
8676
87 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);77 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
88 expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;78 expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
93 expect(await collection.getBalance(ethAcc)).to.be.equal(140n);83 expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
9484
95 await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;85 await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
96 });
97 });86 });
9887
99 it('Tokens multiple creation', async () => {88 itSub('Tokens multiple creation', async ({helper}) => {
100 await usingPlaygrounds(async helper => {
101 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});89 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
10290
103 await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [91 await collection.mintWithOneOwner(alice, [
104 {value: 500n},92 {value: 500n},
105 {value: 400n},93 {value: 400n},
106 {value: 300n},94 {value: 300n},
107 ]);95 ]);
10896
109 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);97 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
110 });
111 });98 });
11299
113 it('Burn some tokens ', async () => {100 itSub('Burn some tokens ', async ({helper}) => {
114 await usingPlaygrounds(async helper => {
115 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});101 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
116 await collection.mint(alice, {Substrate: alice.address}, 500n);102 await collection.mint(alice, 500n);
117103
118 expect(await collection.isTokenExists(0)).to.be.true;104 expect(await collection.isTokenExists(0)).to.be.true;
119 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);105 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
120 expect(await collection.burnTokens(alice, 499n)).to.be.true;106 expect(await collection.burnTokens(alice, 499n)).to.be.true;
121 expect(await collection.isTokenExists(0)).to.be.true;107 expect(await collection.isTokenExists(0)).to.be.true;
122 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);108 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
123 });
124 });109 });
125 110
126 it('Burn all tokens ', async () => {111 itSub('Burn all tokens ', async ({helper}) => {
127 await usingPlaygrounds(async helper => {
128 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});112 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
129 await collection.mint(alice, {Substrate: alice.address}, 500n);113 await collection.mint(alice, 500n);
130114
131 expect(await collection.isTokenExists(0)).to.be.true;115 expect(await collection.isTokenExists(0)).to.be.true;
132 expect(await collection.burnTokens(alice, 500n)).to.be.true;116 expect(await collection.burnTokens(alice, 500n)).to.be.true;
133 expect(await collection.isTokenExists(0)).to.be.true;117 expect(await collection.isTokenExists(0)).to.be.true;
134118
135 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);119 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
136 expect(await collection.getTotalPieces()).to.be.equal(0n);120 expect(await collection.getTotalPieces()).to.be.equal(0n);
137 });
138 });121 });
139122
140 it('Set allowance for token', async () => {123 itSub('Set allowance for token', async ({helper}) => {
141 await usingPlaygrounds(async helper => {
142 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});124 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
143 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};125 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
144 await collection.mint(alice, {Substrate: alice.address}, 100n);126 await collection.mint(alice, 100n);
145127
146 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);128 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
147 129
160 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);142 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
161 expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;143 expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
162 expect(await collection.getBalance(ethAcc)).to.be.equal(10n);144 expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
163 });
164 });145 });
165});146});
166147
modifiedtests/src/limits.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import usingApi from './substrate/substrate-api';18import {expect, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util/playgrounds';
19import {
20 createCollectionExpectSuccess,
21 destroyCollectionExpectSuccess,
22 setCollectionLimitsExpectSuccess,
23 setCollectionSponsorExpectSuccess,
24 confirmSponsorshipExpectSuccess,
25 createItemExpectSuccess,
26 createItemExpectFailure,
27 transferExpectSuccess,
28 getFreeBalance,
29 waitNewBlocks, burnItemExpectSuccess,
30 requirePallets,
31 Pallets,
32} from './util/helpers';
33import {expect} from 'chai';
3419
35describe('Number of tokens per address (NFT)', () => {20describe('Number of tokens per address (NFT)', () => {
36 let alice: IKeyringPair;21 let alice: IKeyringPair;
3722
38 before(async () => {23 before(async () => {
39 await usingApi(async (api, privateKeyWrapper) => {24 await usingPlaygrounds(async (helper, privateKey) => {
40 alice = privateKeyWrapper('//Alice');25 const donor = privateKey('//Alice');
26 [alice] = await helper.arrange.createAccounts([10n], donor);
41 });27 });
42 });28 });
4329
44 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {30 itSub.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async ({helper}) => {
45
46 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});31 const collection = await helper.nft.mintCollection(alice, {});
47 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});32 await collection.setLimits(alice, {accountTokenOwnershipLimit: 20});
33
48 for(let i = 0; i < 10; i++){34 for(let i = 0; i < 10; i++){
49 await createItemExpectSuccess(alice, collectionId, 'NFT');35 await expect(collection.mintToken(alice)).to.be.not.rejected;
50 }36 }
51 await createItemExpectFailure(alice, collectionId, 'NFT');37 await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
52 for(let i = 1; i < 11; i++) {38 for(let i = 1; i < 11; i++) {
53 await burnItemExpectSuccess(alice, collectionId, i);39 await expect(collection.burnToken(alice, i)).to.be.not.rejected;
54 }40 }
55 await destroyCollectionExpectSuccess(collectionId);41 await collection.burn(alice);
56 });42 });
43
44 itSub('Collection limits allow lower number than chain limits, collection limits are enforced', async ({helper}) => {
45 const collection = await helper.nft.mintCollection(alice, {});
46 await collection.setLimits(alice, {accountTokenOwnershipLimit: 1});
5747
58 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {48 await collection.mintToken(alice);
59
60 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
61 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});49 await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
62 await createItemExpectSuccess(alice, collectionId, 'NFT');
63 await createItemExpectFailure(alice, collectionId, 'NFT');50
64 await burnItemExpectSuccess(alice, collectionId, 1);51 await collection.burnToken(alice, 1);
65 await destroyCollectionExpectSuccess(collectionId);52 await expect(collection.burn(alice)).to.be.not.rejected;
66 });53 });
67});54});
6855
69describe('Number of tokens per address (ReFungible)', () => {56describe('Number of tokens per address (ReFungible)', () => {
70 let alice: IKeyringPair;57 let alice: IKeyringPair;
7158
72 before(async function() {59 before(async function() {
73 await requirePallets(this, [Pallets.ReFungible]);60 await usingPlaygrounds(async (helper, privateKey) => {
61 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
7462
75 await usingApi(async (api, privateKeyWrapper) => {63 const donor = privateKey('//Alice');
76 alice = privateKeyWrapper('//Alice');64 [alice] = await helper.arrange.createAccounts([10n], donor);
77 });65 });
78 });66 });
7967
80 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {68 itSub.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async ({helper}) => {
81 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});69 const collection = await helper.rft.mintCollection(alice, {});
82 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});70 await collection.setLimits(alice, {accountTokenOwnershipLimit: 20});
71
83 for(let i = 0; i < 10; i++){72 for(let i = 0; i < 10; i++){
84 await createItemExpectSuccess(alice, collectionId, 'ReFungible');73 await expect(collection.mintToken(alice, 10n)).to.be.not.rejected;
85 }74 }
86 await createItemExpectFailure(alice, collectionId, 'ReFungible');75 await expect(collection.mintToken(alice, 10n)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
87 for(let i = 1; i < 11; i++) {76 for(let i = 1; i < 11; i++) {
88 await burnItemExpectSuccess(alice, collectionId, i, 100);77 await expect(collection.burnToken(alice, i, 10n)).to.be.not.rejected;
89 }78 }
90 await destroyCollectionExpectSuccess(collectionId);79 await collection.burn(alice);
91 });80 });
9281
93 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {82 itSub('Collection limits allow lower number than chain limits, collection limits are enforced', async ({helper}) => {
94 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});83 const collection = await helper.rft.mintCollection(alice, {});
95 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});84 await collection.setLimits(alice, {accountTokenOwnershipLimit: 1});
85
96 await createItemExpectSuccess(alice, collectionId, 'ReFungible');86 await collection.mintToken(alice);
97 await createItemExpectFailure(alice, collectionId, 'ReFungible');87 await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
98 await burnItemExpectSuccess(alice, collectionId, 1, 100);88
89 await collection.burnToken(alice, 1);
99 await destroyCollectionExpectSuccess(collectionId);90 await expect(collection.burn(alice)).to.be.not.rejected;
100 });91 });
101});92});
10293
94// todo:playgrounds skipped ~ postponed
103describe.skip('Sponsor timeout (NFT) (only for special chain limits test)', () => {95describe.skip('Sponsor timeout (NFT) (only for special chain limits test)', () => {
104 let alice: IKeyringPair;96 /*let alice: IKeyringPair;
105 let bob: IKeyringPair;97 let bob: IKeyringPair;
106 let charlie: IKeyringPair;98 let charlie: IKeyringPair;
10799
113 });105 });
114 });106 });
115107
116 it.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {108 itSub.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async ({helper}) => {
117 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});109 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
118 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});110 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
119 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');111 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
137 await destroyCollectionExpectSuccess(collectionId);129 await destroyCollectionExpectSuccess(collectionId);
138 });130 });
139131
140 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {132 itSub('Collection limits have lower timeout value than chain limits, chain limits are enforced', async ({helper}) => {
141133
142 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});134 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
143 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});135 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
176 });168 });
177 });169 });
178170
179 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {171 itSub('Collection limits have greater timeout value than chain limits, collection limits are enforced', async ({helper}) => {
180 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});172 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
181 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});173 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
182 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');174 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');
202 await destroyCollectionExpectSuccess(collectionId);194 await destroyCollectionExpectSuccess(collectionId);
203 });195 });
204196
205 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {197 itSub('Collection limits have lower timeout value than chain limits, chain limits are enforced', async ({helper}) => {
206198
207 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});199 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
208 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});200 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
243 });235 });
244 });236 });
245237
246 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {238 itSub('Collection limits have greater timeout value than chain limits, collection limits are enforced', async ({helper}) => {
247 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});239 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
248 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});240 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
249 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');241 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');
267 await destroyCollectionExpectSuccess(collectionId);259 await destroyCollectionExpectSuccess(collectionId);
268 });260 });
269261
270 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {262 itSub('Collection limits have lower timeout value than chain limits, chain limits are enforced', async ({helper}) => {
271263
272 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});264 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
273 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});265 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
290 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;282 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
291 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);283 //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
292 await destroyCollectionExpectSuccess(collectionId);284 await destroyCollectionExpectSuccess(collectionId);
293 });285 });*/
294});286});
295287
296describe('Collection zero limits (NFT)', () => {288describe('Collection zero limits (NFT)', () => {
299 let charlie: IKeyringPair;291 let charlie: IKeyringPair;
300292
301 before(async () => {293 before(async () => {
302 await usingApi(async (api, privateKeyWrapper) => {294 await usingPlaygrounds(async (helper, privateKey) => {
303 alice = privateKeyWrapper('//Alice');295 const donor = privateKey('//Alice');
304 bob = privateKeyWrapper('//Bob');296 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
305 charlie = privateKeyWrapper('//Charlie');
306 });297 });
307 });298 });
308299
309 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {300 itSub.skip('Limits have 0 in tokens per address field, the chain limits are applied', async ({helper}) => {
310 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});301 const collection = await helper.nft.mintCollection(alice, {});
311 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});302 await collection.setLimits(alice, {accountTokenOwnershipLimit: 0});
303
312 for(let i = 0; i < 10; i++){304 for(let i = 0; i < 10; i++){
313 await createItemExpectSuccess(alice, collectionId, 'NFT');305 await collection.mintToken(alice);
314 }306 }
315 await createItemExpectFailure(alice, collectionId, 'NFT');307 await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
316 });308 });
317309
318 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {310 itSub('Limits have 0 in sponsor timeout, no limits are applied', async ({helper}) => {
311 const collection = await helper.nft.mintCollection(alice, {});
312 await collection.setLimits(alice, {sponsorTransferTimeout: 0});
313 const token = await collection.mintToken(alice);
319314
320 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});315 await collection.setSponsor(alice, alice.address);
321 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
322 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
323 await setCollectionSponsorExpectSuccess(collectionId, alice.address);316 await collection.confirmSponsorship(alice);
324 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');317
325 await transferExpectSuccess(collectionId, tokenId, alice, bob);318 await token.transfer(alice, {Substrate: bob.address});
326 const aliceBalanceBefore = await getFreeBalance(alice);319 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
327320
328 // check setting SponsorTimeout = 0, success with next block321 // check setting SponsorTimeout = 0, success with next block
329 await waitNewBlocks(1);322 await helper.wait.newBlocks(1);
330 await transferExpectSuccess(collectionId, tokenId, bob, charlie);323 await token.transfer(bob, {Substrate: charlie.address});
331 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);324 const aliceBalanceAfterSponsoredTransaction1 = await helper.balance.getSubstrate(alice.address);
332 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;325 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
333 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
334 });326 });
335});327});
336328
340 let charlie: IKeyringPair;332 let charlie: IKeyringPair;
341333
342 before(async () => {334 before(async () => {
343 await usingApi(async (api, privateKeyWrapper) => {335 await usingPlaygrounds(async (helper, privateKey) => {
344 alice = privateKeyWrapper('//Alice');336 const donor = privateKey('//Alice');
345 bob = privateKeyWrapper('//Bob');337 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
346 charlie = privateKeyWrapper('//Charlie');
347 });338 });
348 });339 });
349340
350 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {341 itSub('Limits have 0 in sponsor timeout, no limits are applied', async ({helper}) => {
351 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});342 const collection = await helper.ft.mintCollection(alice, {});
352 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});343 await collection.setLimits(alice, {sponsorTransferTimeout: 0});
353 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');344 await collection.mint(alice, 3n);
354 await setCollectionSponsorExpectSuccess(collectionId, alice.address);
355 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
356 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');
357 const aliceBalanceBefore = await getFreeBalance(alice);
358 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
359345
346 await collection.setSponsor(alice, alice.address);
347 await collection.confirmSponsorship(alice);
348
349 await collection.transfer(alice, {Substrate: bob.address}, 2n);
350 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
351
360 // check setting SponsorTimeout = 0, success with next block352 // check setting SponsorTimeout = 0, success with next block
361 await waitNewBlocks(1);353 await helper.wait.newBlocks(1);
362 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');354 await collection.transfer(bob, {Substrate: charlie.address});
363 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);355 const aliceBalanceAfterSponsoredTransaction1 = await helper.balance.getSubstrate(alice.address);
364 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;356 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
365 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
366 });357 });
367});358});
368359
372 let charlie: IKeyringPair;363 let charlie: IKeyringPair;
373364
374 before(async function() {365 before(async function() {
375 await requirePallets(this, [Pallets.ReFungible]);366 await usingPlaygrounds(async (helper, privateKey) => {
367 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
376368
377 await usingApi(async (api, privateKeyWrapper) => {369 const donor = privateKey('//Alice');
378 alice = privateKeyWrapper('//Alice');
379 bob = privateKeyWrapper('//Bob');370 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
380 charlie = privateKeyWrapper('//Charlie');
381 });371 });
382 });372 });
383373
384 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {374 itSub.skip('Limits have 0 in tokens per address field, the chain limits are applied', async ({helper}) => {
385 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});375 const collection = await helper.rft.mintCollection(alice, {});
386 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});376 await collection.setLimits(alice, {accountTokenOwnershipLimit: 0});
387 for(let i = 0; i < 10; i++){377 for(let i = 0; i < 10; i++){
388 await createItemExpectSuccess(alice, collectionId, 'ReFungible');378 await collection.mintToken(alice);
389 }379 }
390 await createItemExpectFailure(alice, collectionId, 'ReFungible');380 await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
391 });381 });
392382
393 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {383 itSub('Limits have 0 in sponsor timeout, no limits are applied', async ({helper}) => {
384 const collection = await helper.rft.mintCollection(alice, {});
385 await collection.setLimits(alice, {sponsorTransferTimeout: 0});
386 const token = await collection.mintToken(alice, 3n);
394387
395 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});388 await collection.setSponsor(alice, alice.address);
396 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
397 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');
398 await setCollectionSponsorExpectSuccess(collectionId, alice.address);389 await collection.confirmSponsorship(alice);
399 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');390
400 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');391 await token.transfer(alice, {Substrate: bob.address}, 2n);
401 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
402 const aliceBalanceBefore = await getFreeBalance(alice);392 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
403393
404 // check setting SponsorTimeout = 0, success with next block394 // check setting SponsorTimeout = 0, success with next block
405 await waitNewBlocks(1);395 await helper.wait.newBlocks(1);
406 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');396 await token.transfer(bob, {Substrate: charlie.address});
407 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);397 const aliceBalanceAfterSponsoredTransaction1 = await helper.balance.getSubstrate(alice.address);
408 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;398 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
409 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
410 });399 });
411
412 it('Effective collection limits', async () => {
413 await usingApi(async (api) => {
414 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});400});
415 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
416
417 { // Check that limits is undefined
418 const collection = await api.rpc.unique.collectionById(collectionId);
419 expect(collection.isSome).to.be.true;
420 const limits = collection.unwrap().limits;
421 expect(limits).to.be.any;
422
423 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.null;
424 expect(limits.sponsoredDataSize.toHuman()).to.be.null;
425 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.null;
426 expect(limits.tokenLimit.toHuman()).to.be.null;
427 expect(limits.sponsorTransferTimeout.toHuman()).to.be.null;
428 expect(limits.sponsorApproveTimeout.toHuman()).to.be.null;
429 expect(limits.ownerCanTransfer.toHuman()).to.be.true;
430 expect(limits.ownerCanDestroy.toHuman()).to.be.null;
431 expect(limits.transfersEnabled.toHuman()).to.be.null;
432 }
433
434 { // Check that limits is undefined for non-existent collection
435 const limits = await api.rpc.unique.effectiveCollectionLimits(11111);
436 expect(limits.toHuman()).to.be.null;
437 }
438
439 { // Check that default values defined for collection limits
440 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);
441 expect(limitsOpt.isNone).to.be.false;
442 const limits = limitsOpt.unwrap();
443
444 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('100,000');
445 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('2,048');
446 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');
447 expect(limits.tokenLimit.toHuman()).to.be.eq('4,294,967,295');
448 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');
449 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');
450 expect(limits.ownerCanTransfer.toHuman()).to.be.true;
451 expect(limits.ownerCanDestroy.toHuman()).to.be.true;
452 expect(limits.transfersEnabled.toHuman()).to.be.true;
453 }
454401
455 { //Check the values for collection limits402describe('Effective collection limits (NFT)', () => {
456 await setCollectionLimitsExpectSuccess(alice, collectionId, {
457 accountTokenOwnershipLimit: 99_999,403 let alice: IKeyringPair;
458 sponsoredDataSize: 1024,
459 tokenLimit: 123,
460 transfersEnabled: false,
461 });
462404
463 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);405 before(async () => {
464 expect(limitsOpt.isNone).to.be.false;
465 const limits = limitsOpt.unwrap();
466 406 await usingPlaygrounds(async (helper, privateKey) => {
467 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('99,999');
468 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('1,024');
469 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');
470 expect(limits.tokenLimit.toHuman()).to.be.eq('123');
471 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');407 const donor = privateKey('//Alice');
472 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');
473 expect(limits.ownerCanTransfer.toHuman()).to.be.true;408 [alice] = await helper.arrange.createAccounts([10n], donor);
474 expect(limits.ownerCanDestroy.toHuman()).to.be.true;
475 expect(limits.transfersEnabled.toHuman()).to.be.false;
476 }
477 });409 });
478 });410 });
411
479});412 itSub('Effective collection limits', async ({helper}) => {
413 const collection = await helper.nft.mintCollection(alice, {});
414 await collection.setLimits(alice, {ownerCanTransfer: true});
415
416 {
417 // Check that limits are undefined
418 const collectionInfo = await collection.getData();
419 const limits = collectionInfo?.raw.limits;
420 expect(limits).to.be.any;
421
422 expect(limits.accountTokenOwnershipLimit).to.be.null;
423 expect(limits.sponsoredDataSize).to.be.null;
424 expect(limits.sponsoredDataRateLimit).to.be.null;
425 expect(limits.tokenLimit).to.be.null;
426 expect(limits.sponsorTransferTimeout).to.be.null;
427 expect(limits.sponsorApproveTimeout).to.be.null;
428 expect(limits.ownerCanTransfer).to.be.true;
429 expect(limits.ownerCanDestroy).to.be.null;
430 expect(limits.transfersEnabled).to.be.null;
431 }
480432
433 { // Check that limits is undefined for non-existent collection
434 const limits = await helper.collection.getEffectiveLimits(999999);
435 expect(limits).to.be.null;
436 }
481437
438 { // Check that default values defined for collection limits
439 const limits = await collection.getEffectiveLimits();
440
441 expect(limits.accountTokenOwnershipLimit).to.be.eq(100000);
442 expect(limits.sponsoredDataSize).to.be.eq(2048);
443 expect(limits.sponsoredDataRateLimit).to.be.deep.eq({sponsoringDisabled: null});
444 expect(limits.tokenLimit).to.be.eq(4294967295);
445 expect(limits.sponsorTransferTimeout).to.be.eq(5);
446 expect(limits.sponsorApproveTimeout).to.be.eq(5);
447 expect(limits.ownerCanTransfer).to.be.true;
448 expect(limits.ownerCanDestroy).to.be.true;
449 expect(limits.transfersEnabled).to.be.true;
450 }
451
452 {
453 // Check the values for collection limits
454 await collection.setLimits(alice, {
455 accountTokenOwnershipLimit: 99_999,
456 sponsoredDataSize: 1024,
457 tokenLimit: 123,
458 transfersEnabled: false,
459 });
460
461 const limits = await collection.getEffectiveLimits();
462
463 expect(limits.accountTokenOwnershipLimit).to.be.eq(99999);
464 expect(limits.sponsoredDataSize).to.be.eq(1024);
465 expect(limits.sponsoredDataRateLimit).to.be.deep.eq({sponsoringDisabled: null});
466 expect(limits.tokenLimit).to.be.eq(123);
467 expect(limits.sponsorTransferTimeout).to.be.eq(5);
468 expect(limits.sponsorApproveTimeout).to.be.eq(5);
469 expect(limits.ownerCanTransfer).to.be.true;
470 expect(limits.ownerCanDestroy).to.be.true;
471 expect(limits.transfersEnabled).to.be.false;
472 }
473 });
474});
482475
modifiedtests/src/nextSponsoring.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import chai from 'chai';
20import chaiAsPromised from 'chai-as-promised';
21import {default as usingApi} from './substrate/substrate-api';
22import {18import {expect, itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
23 createCollectionExpectSuccess,19
24 setCollectionSponsorExpectSuccess,
25 confirmSponsorshipExpectSuccess,
26 createItemExpectSuccess,
27 transferExpectSuccess,
28 normalizeAccountId,
29 getNextSponsored,
30 requirePallets,
31 Pallets,
32} from './util/helpers';
33
34chai.use(chaiAsPromised);
35const expect = chai.expect;20const SPONSORING_TIMEOUT = 5;
36
37
3821
41 let bob: IKeyringPair;24 let bob: IKeyringPair;
4225
43 before(async () => {26 before(async () => {
44 await usingApi(async (api, privateKeyWrapper) => {27 await usingPlaygrounds(async (helper, privateKey) => {
45 alice = privateKeyWrapper('//Alice');28 const donor = privateKey('//Alice');
46 bob = privateKeyWrapper('//Bob');29 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
47 });30 });
48 });31 });
4932
50 it('NFT', async () => {33 itSub('NFT', async ({helper}) => {
51 await usingApi(async (api: ApiPromise) => {
52
53 // Not existing collection 34 // Non-existing collection
54 expect(await getNextSponsored(api, 0, normalizeAccountId(alice), 0)).to.be.equal(-1);35 expect(await helper.collection.getTokenNextSponsored(0, 0, {Substrate: alice.address})).to.be.null;
5536
56 const collectionId = await createCollectionExpectSuccess();37 const collection = await helper.nft.mintCollection(alice, {});
57 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);38 const token = await collection.mintToken(alice);
5839
59 // Check with Disabled sponsoring state40 // Check with Disabled sponsoring state
60 expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.equal(-1);41 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
42
43 // Check with Unconfirmed sponsoring state
61 await setCollectionSponsorExpectSuccess(collectionId, bob.address);44 await collection.setSponsor(alice, bob.address);
62
63 // Check with Unconfirmed sponsoring state
64 expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.equal(-1);45 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
46
47 // Check with Confirmed sponsoring state
65 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');48 await collection.confirmSponsorship(bob);
66
67 // Check with Confirmed sponsoring state
68 expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.equal(0);49 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.equal(0);
6950
70 // After transfer51 // Check after transfer
71 await transferExpectSuccess(collectionId, itemId, alice, bob, 1);52 await token.transfer(alice, {Substrate: bob.address});
72 expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.lessThanOrEqual(5);53 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
7354
74 // Not existing token 55 // Non-existing token
75 expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId+1)).to.be.equal(-1);56 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
76 });
77 });57 });
7858
79 it('Fungible', async () => {59 itSub('Fungible', async ({helper}) => {
80 await usingApi(async (api: ApiPromise) => {
81
82 const createMode = 'Fungible';60 const collection = await helper.ft.mintCollection(alice, {});
83 const funCollectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});61 await collection.mint(alice, 10n);
62
63 // Check with Disabled sponsoring state
84 await createItemExpectSuccess(alice, funCollectionId, createMode);64 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
65
85 await setCollectionSponsorExpectSuccess(funCollectionId, bob.address);66 await collection.setSponsor(alice, bob.address);
86 await confirmSponsorshipExpectSuccess(funCollectionId, '//Bob');67 await collection.confirmSponsorship(bob);
68
69 // Check with Confirmed sponsoring state
87 expect(await getNextSponsored(api, funCollectionId, normalizeAccountId(alice), 0)).to.be.equal(0);70 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.equal(0);
8871
72 // Check after transfer
89 await transferExpectSuccess(funCollectionId, 0, alice, bob, 10, 'Fungible');73 await collection.transfer(alice, {Substrate: bob.address});
90 expect(await getNextSponsored(api, funCollectionId, normalizeAccountId(alice), 0)).to.be.lessThanOrEqual(5);74 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
91 });
92 });75 });
9376
94 it('ReFungible', async function() {77 itSub.ifWithPallets('ReFungible', [Pallets.ReFungible], async ({helper}) => {
95 await requirePallets(this, [Pallets.ReFungible]);
96
97 await usingApi(async (api: ApiPromise) => {
98
99 const createMode = 'ReFungible';78 const collection = await helper.rft.mintCollection(alice, {});
100 const refunCollectionId = await createCollectionExpectSuccess({mode: {type: createMode}});79 const token = await collection.mintToken(alice, 10n);
80
81 // Check with Disabled sponsoring state
101 const refunItemId = await createItemExpectSuccess(alice, refunCollectionId, createMode);82 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
83
102 await setCollectionSponsorExpectSuccess(refunCollectionId, bob.address);84 await collection.setSponsor(alice, bob.address);
103 await confirmSponsorshipExpectSuccess(refunCollectionId, '//Bob');85 await collection.confirmSponsorship(bob);
86
87 // Check with Confirmed sponsoring state
104 expect(await getNextSponsored(api, refunCollectionId, normalizeAccountId(alice), refunItemId)).to.be.equal(0);88 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.equal(0);
10589
90 // Check after transfer
106 await transferExpectSuccess(refunCollectionId, refunItemId, alice, bob, 10, 'ReFungible');91 await token.transfer(alice, {Substrate: bob.address});
107 expect(await getNextSponsored(api, refunCollectionId, normalizeAccountId(alice), refunItemId)).to.be.lessThanOrEqual(5);92 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
10893
109 // Not existing token 94 // Non-existing token
110 expect(await getNextSponsored(api, refunCollectionId, normalizeAccountId(alice), refunItemId+1)).to.be.equal(-1);95 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
111 });96 });
112 });
113});97});
11498
modifiedtests/src/overflow.test.tsdiffbeforeafterboth
23chai.use(chaiAsPromised);23chai.use(chaiAsPromised);
24const expect = chai.expect;24const expect = chai.expect;
2525
26// todo:playgrounds skipped ~ postponed
26describe.skip('Integration Test fungible overflows', () => {27describe.skip('Integration Test fungible overflows', () => {
27 let alice: IKeyringPair;28 let alice: IKeyringPair;
28 let bob: IKeyringPair;29 let bob: IKeyringPair;
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {expect} from 'chai';17import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
19import usingApi from './substrate/substrate-api';
20
21function getModuleNames(api: ApiPromise): string[] {
22 return api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());
23}
2418
25// Pallets that must always be present19// Pallets that must always be present
26const requiredPallets = [20const requiredPallets = [
6256
63describe('Pallet presence', () => {57describe('Pallet presence', () => {
64 before(async () => {58 before(async () => {
65 await usingApi(async api => {59 await usingPlaygrounds(async helper => {
66 const chain = await api.rpc.system.chain();60 const chain = await helper.api!.rpc.system.chain();
6761
68 const refungible = 'refungible';62 const refungible = 'refungible';
69 const scheduler = 'scheduler';63 const scheduler = 'scheduler';
80 });74 });
81 });75 });
8276
83 it('Required pallets are present', async () => {77 itSub('Required pallets are present', async ({helper}) => {
84 await usingApi(async api => {
85 for (let i=0; i<requiredPallets.length; i++) {
86 expect(getModuleNames(api)).to.include(requiredPallets[i]);78 expect(helper.fetchAllPalletNames()).to.contain.members([...requiredPallets]);
87 }
88 });
89 });79 });
80
90 it('Governance and consensus pallets are present', async () => {81 itSub('Governance and consensus pallets are present', async ({helper}) => {
91 await usingApi(async api => {
92 for (let i=0; i<consensusPallets.length; i++) {
93 expect(getModuleNames(api)).to.include(consensusPallets[i]);82 expect(helper.fetchAllPalletNames()).to.contain.members([...consensusPallets]);
94 }
95 });
96 });83 });
84
97 it('No extra pallets are included', async () => {85 itSub('No extra pallets are included', async ({helper}) => {
98 await usingApi(async api => {
99 expect(getModuleNames(api).sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());86 expect(helper.fetchAllPalletNames().sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
100 });
101 });87 });
102});88});
10389
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18
19import {usingPlaygrounds} from './util/playgrounds';
20import {18import {itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds, expect} from './util/playgrounds';
21 getModuleNames,
22 Pallets,
23 requirePallets,
24} from './util/helpers';
25
26import chai from 'chai';
27import chaiAsPromised from 'chai-as-promised';
28chai.use(chaiAsPromised);
29const expect = chai.expect;
3019
31let alice: IKeyringPair;20let alice: IKeyringPair;
32let bob: IKeyringPair;21let bob: IKeyringPair;
33const MAX_REFUNGIBLE_PIECES = 1_000_000_000_000_000_000_000n;22const MAX_REFUNGIBLE_PIECES = 1_000_000_000_000_000_000_000n;
3423
35describe('integration test: Refungible functionality:', async () => {24describe('integration test: Refungible functionality:', async () => {
36 before(async function() {25 before(async function() {
37 await requirePallets(this, [Pallets.ReFungible]);
38
39 await usingPlaygrounds(async (helper, privateKey) => {26 await usingPlaygrounds(async (helper, privateKey) => {
27 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
28
40 alice = privateKey('//Alice');29 alice = privateKey('//Alice');
41 bob = privateKey('//Bob');30 bob = privateKey('//Bob');
42 if (!getModuleNames(helper.api!).includes(Pallets.ReFungible)) this.skip();
43 });31 });
44 });32 });
45 33
46 it('Create refungible collection and token', async () => {34 itSub('Create refungible collection and token', async ({helper}) => {
47 await usingPlaygrounds(async helper => {
48 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});35 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
4936
50 const itemCountBefore = await collection.getLastTokenId();37 const itemCountBefore = await collection.getLastTokenId();
51 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);38 const token = await collection.mintToken(alice, 100n);
52 39
53 const itemCountAfter = await collection.getLastTokenId();40 const itemCountAfter = await collection.getLastTokenId();
54 41
55 // What to expect42 // What to expect
56 expect(token?.tokenId).to.be.gte(itemCountBefore);43 expect(token?.tokenId).to.be.gte(itemCountBefore);
57 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);44 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
58 expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());45 expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
59 });
60 });46 });
61 47
62 it('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async () => {48 itSub('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async ({helper}) => {
63 await usingPlaygrounds(async helper => {
64 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});49 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
65 50
66 const token = await collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES);51 const token = await collection.mintToken(alice, MAX_REFUNGIBLE_PIECES);
67 52
68 expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);53 expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
69 54
70 await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);55 await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);
71 expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);56 expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
72 expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);57 expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
73 58
74 await expect(collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES + 1n)).to.eventually.be.rejected;59 await expect(collection.mintToken(alice, MAX_REFUNGIBLE_PIECES + 1n))
75 });60 .to.eventually.be.rejectedWith(/refungible\.WrongRefungiblePieces/);
76 });61 });
77 62
78 it('RPC method tokenOnewrs for refungible collection and token', async () => {63 itSub('RPC method tokenOnewrs for refungible collection and token', async ({helper, privateKey}) => {
79 await usingPlaygrounds(async (helper, privateKey) => {
80 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};64 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
81 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));65 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
8266
83 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});67 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
8468
85 const token = await collection.mintToken(alice, {Substrate: alice.address}, 10_000n);69 const token = await collection.mintToken(alice, 10_000n);
8670
87 await token.transfer(alice, {Substrate: bob.address}, 1000n);71 await token.transfer(alice, {Substrate: bob.address}, 1000n);
88 await token.transfer(alice, ethAcc, 900n);72 await token.transfer(alice, ethAcc, 900n);
100 const eleven = privateKey('//ALice+11');84 const eleven = privateKey('//ALice+11');
101 expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;85 expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
102 expect((await token.getTop10Owners()).length).to.be.equal(10);86 expect((await token.getTop10Owners()).length).to.be.equal(10);
103 });
104 });87 });
105 88
106 it('Transfer token pieces', async () => {89 itSub('Transfer token pieces', async ({helper}) => {
107 await usingPlaygrounds(async helper => {
108 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});90 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
109 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);91 const token = await collection.mintToken(alice, 100n);
11092
111 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);93 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
112 expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;94 expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
113 95
114 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);96 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
115 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);97 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
116 98
117 await expect(token.transfer(alice, {Substrate: bob.address}, 41n)).to.eventually.be.rejected;99 await expect(token.transfer(alice, {Substrate: bob.address}, 41n))
118 });100 .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
119 });101 });
120102
121 it('Create multiple tokens', async () => {103 itSub('Create multiple tokens', async ({helper}) => {
122 await usingPlaygrounds(async helper => {
123 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});104 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
124 // TODO: fix mintMultipleTokens105 // TODO: fix mintMultipleTokens
125 // await collection.mintMultipleTokens(alice, [106 // await collection.mintMultipleTokens(alice, [
135 const lastTokenId = await collection.getLastTokenId();116 const lastTokenId = await collection.getLastTokenId();
136 expect(lastTokenId).to.be.equal(3);117 expect(lastTokenId).to.be.equal(3);
137 expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);118 expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
138 });
139 });119 });
140120
141 it('Burn some pieces', async () => {121 itSub('Burn some pieces', async ({helper}) => {
142 await usingPlaygrounds(async helper => {
143 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});122 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
144 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);123 const token = await collection.mintToken(alice, 100n);
145 expect(await collection.isTokenExists(token.tokenId)).to.be.true;124 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
146 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);125 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
147 expect((await token.burn(alice, 99n)).success).to.be.true;126 expect((await token.burn(alice, 99n)).success).to.be.true;
148 expect(await collection.isTokenExists(token.tokenId)).to.be.true;127 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
149 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);128 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
150 });
151 });129 });
152130
153 it('Burn all pieces', async () => {131 itSub('Burn all pieces', async ({helper}) => {
154 await usingPlaygrounds(async helper => {
155 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});132 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
156 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);133 const token = await collection.mintToken(alice, 100n);
157 134
158 expect(await collection.isTokenExists(token.tokenId)).to.be.true;135 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
159 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);136 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
160137
161 expect((await token.burn(alice, 100n)).success).to.be.true;138 expect((await token.burn(alice, 100n)).success).to.be.true;
162 expect(await collection.isTokenExists(token.tokenId)).to.be.false;139 expect(await collection.isTokenExists(token.tokenId)).to.be.false;
163 });
164 });140 });
165141
166 it('Burn some pieces for multiple users', async () => {142 itSub('Burn some pieces for multiple users', async ({helper}) => {
167 await usingPlaygrounds(async helper => {
168 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});143 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
169 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);144 const token = await collection.mintToken(alice, 100n);
170145
171 expect(await collection.isTokenExists(token.tokenId)).to.be.true;146 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
172 147
189 expect((await token.burn(bob, 1n)).success).to.be.true;164 expect((await token.burn(bob, 1n)).success).to.be.true;
190165
191 expect(await collection.isTokenExists(token.tokenId)).to.be.false;166 expect(await collection.isTokenExists(token.tokenId)).to.be.false;
192 });
193 });167 });
194168
195 it('Set allowance for token', async () => {169 itSub('Set allowance for token', async ({helper}) => {
196 await usingPlaygrounds(async helper => {
197 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});170 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
198 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);171 const token = await collection.mintToken(alice, 100n);
199 172
200 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);173 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
201174
206 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);179 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
207 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);180 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
208 expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);181 expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
209 });
210 });182 });
211183
212 it('Repartition', async () => {184 itSub('Repartition', async ({helper}) => {
213 await usingPlaygrounds(async helper => {
214 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});185 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
215 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);186 const token = await collection.mintToken(alice, 100n);
216187
217 expect(await token.repartition(alice, 200n)).to.be.true;188 expect(await token.repartition(alice, 200n)).to.be.true;
218 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);189 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
222 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);193 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
223 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);194 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
224 195
225 await expect(token.repartition(alice, 80n)).to.eventually.be.rejected;196 await expect(token.repartition(alice, 80n))
226 197 .to.eventually.be.rejectedWith(/refungible\.RepartitionWhileNotOwningAllPieces/);
198
227 expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;199 expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
228 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);200 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
229 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);201 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
230202
231 expect(await token.repartition(bob, 150n)).to.be.true;203 expect(await token.repartition(bob, 150n)).to.be.true;
232 await expect(token.transfer(bob, {Substrate: alice.address}, 160n)).to.eventually.be.rejected;204 await expect(token.transfer(bob, {Substrate: alice.address}, 160n))
233205 .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
234 });
235 });206 });
236207
237 it('Repartition with increased amount', async () => {208 itSub('Repartition with increased amount', async ({helper}) => {
238 await usingPlaygrounds(async helper => {
239 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});209 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
240 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);210 const token = await collection.mintToken(alice, 100n);
241 await token.repartition(alice, 200n);211 await token.repartition(alice, 200n);
242 const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);212 const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
243 expect(chainEvents).to.include.deep.members([{213 expect(chainEvents).to.include.deep.members([{
251 '100',221 '100',
252 ],222 ],
253 }]);223 }]);
254 });
255 });224 });
256225
257 it('Repartition with decreased amount', async () => {226 itSub('Repartition with decreased amount', async ({helper}) => {
258 await usingPlaygrounds(async helper => {
259 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});227 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
260 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);228 const token = await collection.mintToken(alice, 100n);
261 await token.repartition(alice, 50n);229 await token.repartition(alice, 50n);
262 const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);230 const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
263 expect(chainEvents).to.include.deep.members([{231 expect(chainEvents).to.include.deep.members([{
271 '50',239 '50',
272 ],240 ],
273 }]);241 }]);
274 });
275 });242 });
276 243
277 it('Create new collection with properties', async () => {244 itSub('Create new collection with properties', async ({helper}) => {
278 await usingPlaygrounds(async helper => {
279 const properties = [{key: 'key1', value: 'val1'}];245 const properties = [{key: 'key1', value: 'val1'}];
280 const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];246 const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
281 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});247 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
282 const info = await collection.getData();248 const info = await collection.getData();
283 expect(info?.raw.properties).to.be.deep.equal(properties);249 expect(info?.raw.properties).to.be.deep.equal(properties);
284 expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);250 expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
285 });
286 });251 });
287});252});
288253
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';17import {IKeyringPair} from '@polkadot/types/types';
19import {usingPlaygrounds} from './util/playgrounds';18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
20
21chai.use(chaiAsPromised);
22const expect = chai.expect;
2319
24describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {20describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
21 let alice: IKeyringPair;
22 let bob: IKeyringPair;
23
24 before(async () => {
25 await usingPlaygrounds(async (helper, privateKey) => {
26 const donor = privateKey('//Alice');
27 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
28 });
29 });
30
25 it('Remove collection admin.', async () => {31 itSub('Remove collection admin', async ({helper}) => {
26 await usingPlaygrounds(async (helper, privateKey) => {32 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-1', tokenPrefix: 'RCA'});
27 const alice = privateKey('//Alice');
28 const bob = privateKey('//Bob');
29 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
30
31 const collectionInfo = await collection.getData();33 const collectionInfo = await collection.getData();
32 expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);34 expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
33 // first - add collection admin Bob35 // first - add collection admin Bob
34 await collection.addAdmin(alice, {Substrate: bob.address});36 await collection.addAdmin(alice, {Substrate: bob.address});
3537
36 const adminListAfterAddAdmin = await collection.getAdmins();38 const adminListAfterAddAdmin = await collection.getAdmins();
37 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});39 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
3840
39 // then remove bob from admins of collection41 // then remove bob from admins of collection
40 await collection.removeAdmin(alice, {Substrate: bob.address});42 await collection.removeAdmin(alice, {Substrate: bob.address});
4143
42 const adminListAfterRemoveAdmin = await collection.getAdmins();44 const adminListAfterRemoveAdmin = await collection.getAdmins();
43 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});45 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: bob.address});
44 });
45 });46 });
4647
47 it('Remove admin from collection that has no admins', async () => {48 itSub('Remove admin from collection that has no admins', async ({helper}) => {
48 await usingPlaygrounds(async (helper, privateKey) => {49 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-2', tokenPrefix: 'RCA'});
49 const alice = privateKey('//Alice');
50 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
5150
52 const adminListBeforeAddAdmin = await collection.getAdmins();51 const adminListBeforeAddAdmin = await collection.getAdmins();
53 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);52 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
5453
55 // await expect(collection.removeAdmin(alice, {Substrate: alice.address})).to.be.rejectedWith('Unable to remove collection admin');
56 await collection.removeAdmin(alice, {Substrate: alice.address});54 await collection.removeAdmin(alice, {Substrate: alice.address});
57 });
58 });55 });
59});56});
6057
61describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {58describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
59 let alice: IKeyringPair;
60 let bob: IKeyringPair;
61 let charlie: IKeyringPair;
62
63 before(async () => {
64 await usingPlaygrounds(async (helper, privateKey) => {
65 const donor = privateKey('//Alice');
66 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
67 });
68 });
69
62 it('Can\'t remove collection admin from not existing collection', async () => {70 itSub('Can\'t remove collection admin from not existing collection', async ({helper}) => {
63 await usingPlaygrounds(async (helper, privateKey) => {
64 // tslint:disable-next-line: no-bitwise
65 const collectionId = (1 << 32) - 1;71 const collectionId = (1 << 32) - 1;
66 const alice = privateKey('//Alice');
67 const bob = privateKey('//Bob');
6872
69 await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address})).to.be.rejected;73 await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address}))
7074 .to.be.rejectedWith(/common\.CollectionNotFound/);
71 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
72 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
73 });
74 });75 });
7576
76 it('Can\'t remove collection admin from deleted collection', async () => {77 itSub('Can\'t remove collection admin from deleted collection', async ({helper}) => {
77 await usingPlaygrounds(async (helper, privateKey) => {78 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-2', tokenPrefix: 'RCA'});
78 const alice = privateKey('//Alice');
79 const bob = privateKey('//Bob');
80 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
8179
82 expect(await collection.burn(alice)).to.be.true;80 expect(await collection.burn(alice)).to.be.true;
8381
84 await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address})).to.be.rejected;82 await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address}))
8583 .to.be.rejectedWith(/common\.CollectionNotFound/);
86 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
87 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
88 });
89 });84 });
9085
91 it('Regular user can\'t remove collection admin', async () => {86 itSub('Regular user can\'t remove collection admin', async ({helper}) => {
92 await usingPlaygrounds(async (helper, privateKey) => {87 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-3', tokenPrefix: 'RCA'});
93 const alice = privateKey('//Alice');
94 const bob = privateKey('//Bob');
95 const charlie = privateKey('//Charlie');
96 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
9788
98 await collection.addAdmin(alice, {Substrate: bob.address});89 await collection.addAdmin(alice, {Substrate: bob.address});
9990
100 await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;91 await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
10192 .to.be.rejectedWith(/common\.NoPermission/);
102 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
103 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
104 });
105 });93 });
10694
107 it('Admin can\'t remove collection admin.', async () => {95 itSub('Admin can\'t remove collection admin.', async ({helper}) => {
108 await usingPlaygrounds(async (helper, privateKey) => {96 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-4', tokenPrefix: 'RCA'});
109 const alice = privateKey('//Alice');97
110 const bob = privateKey('//Bob');
111 const charlie = privateKey('//Charlie');
112 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
113
114 await collection.addAdmin(alice, {Substrate: bob.address});98 await collection.addAdmin(alice, {Substrate: bob.address});
115 await collection.addAdmin(alice, {Substrate: charlie.address});99 await collection.addAdmin(alice, {Substrate: charlie.address});
116100
117 const adminListAfterAddAdmin = await collection.getAdmins();101 const adminListAfterAddAdmin = await collection.getAdmins();
118 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});102 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
119 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});103 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: charlie.address});
120104
121 await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;105 await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
106 .to.be.rejectedWith(/common\.NoPermission/);
122107
123 const adminListAfterRemoveAdmin = await collection.getAdmins();108 const adminListAfterRemoveAdmin = await collection.getAdmins();
124 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});109 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: bob.address});
125 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});110 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: charlie.address});
126 });
127 });111 });
128});112});
129113
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi, submitTransactionExpectFailAsync} from './substrate/substrate-api';17import {IKeyringPair} from '@polkadot/types/types';
20import {18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
21 createCollectionExpectSuccess,
22 setCollectionSponsorExpectSuccess,
23 destroyCollectionExpectSuccess,
24 confirmSponsorshipExpectSuccess,
25 confirmSponsorshipExpectFailure,
26 createItemExpectSuccess,
27 findUnusedAddress,
28 removeCollectionSponsorExpectSuccess,
29 removeCollectionSponsorExpectFailure,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32 getCreatedCollectionCount,
33} from './util/helpers';
34import {IKeyringPair} from '@polkadot/types/types';
35
36chai.use(chaiAsPromised);
37const expect = chai.expect;
38
39let alice: IKeyringPair;
40let bob: IKeyringPair;
4119
42describe('integration test: ext. removeCollectionSponsor():', () => {20describe('integration test: ext. removeCollectionSponsor():', () => {
21 let donor: IKeyringPair;
22 let alice: IKeyringPair;
23 let bob: IKeyringPair;
4324
44 before(async () => {25 before(async () => {
45 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
46 alice = privateKeyWrapper('//Alice');27 donor = privateKey('//Alice');
47 bob = privateKeyWrapper('//Bob');28 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
48 });29 });
49 });30 });
5031
51 it('Removing NFT collection sponsor stops sponsorship', async () => {32 itSub('Removing NFT collection sponsor stops sponsorship', async ({helper}) => {
52 const collectionId = await createCollectionExpectSuccess();33 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-1', tokenPrefix: 'RCS'});
53 await setCollectionSponsorExpectSuccess(collectionId, bob.address);34 await collection.setSponsor(alice, bob.address);
54 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');35 await collection.confirmSponsorship(bob);
55 await removeCollectionSponsorExpectSuccess(collectionId);36 await collection.removeSponsor(alice);
5637
57 await usingApi(async (api, privateKeyWrapper) => {
58 // Find unused address38 // Find unused address
59 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);39 const [zeroBalance] = await helper.arrange.createAccounts([0n], donor);
6040
61 // Mint token for unused address41 // Mint token for unused address
62 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);42 const token = await collection.mintToken(alice, {Substrate: zeroBalance.address});
6343
64 // Transfer this tokens from unused address to Alice - should fail44 // Transfer this tokens from unused address to Alice - should fail
65 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();45 const sponsorBalanceBefore = await helper.balance.getSubstrate(bob.address);
66 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
67 const badTransaction = async function () {
68 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
69 };
70 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');46 await expect(token.transfer(zeroBalance, {Substrate: alice.address}))
47 .to.be.rejectedWith('Inability to pay some fees');
71 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();48 const sponsorBalanceAfter = await helper.balance.getSubstrate(bob.address);
7249
73 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);50 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
74 });
75 });51 });
7652
77 it('Remove a sponsor after it was already removed', async () => {53 itSub('Remove a sponsor after it was already removed', async ({helper}) => {
78 const collectionId = await createCollectionExpectSuccess();54 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-2', tokenPrefix: 'RCS'});
79 await setCollectionSponsorExpectSuccess(collectionId, bob.address);55 await collection.setSponsor(alice, bob.address);
80 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');56 await collection.confirmSponsorship(bob);
81 await removeCollectionSponsorExpectSuccess(collectionId);57 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
82 await removeCollectionSponsorExpectSuccess(collectionId);58 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
83 });59 });
8460
85 it('Remove sponsor in a collection that never had the sponsor set', async () => {61 itSub('Remove sponsor in a collection that never had the sponsor set', async ({helper}) => {
86 const collectionId = await createCollectionExpectSuccess();62 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-3', tokenPrefix: 'RCS'});
87 await removeCollectionSponsorExpectSuccess(collectionId);63 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
88 });64 });
8965
90 it('Remove sponsor for a collection that had the sponsor set, but not confirmed', async () => {66 itSub('Remove sponsor for a collection that had the sponsor set, but not confirmed', async ({helper}) => {
91 const collectionId = await createCollectionExpectSuccess();67 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-4', tokenPrefix: 'RCS'});
92 await setCollectionSponsorExpectSuccess(collectionId, bob.address);68 await collection.setSponsor(alice, bob.address);
93 await removeCollectionSponsorExpectSuccess(collectionId);69 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
94 });70 });
9571
96});72});
9773
98describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {74describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
75 let alice: IKeyringPair;
76 let bob: IKeyringPair;
77 let charlie: IKeyringPair;
78
99 before(async () => {79 before(async () => {
100 await usingApi(async (api, privateKeyWrapper) => {80 await usingPlaygrounds(async (helper, privateKey) => {
101 alice = privateKeyWrapper('//Alice');81 const donor = privateKey('//Alice');
102 bob = privateKeyWrapper('//Bob');82 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
103 });83 });
104 });84 });
10585
106 it('(!negative test!) Remove sponsor for a collection that never existed', async () => {86 itSub('(!negative test!) Remove sponsor for a collection that never existed', async ({helper}) => {
107 // Find the collection that never existed
108 let collectionId = 0;87 const collectionId = (1 << 32) - 1;
109 await usingApi(async (api) => {88 await expect(helper.collection.removeSponsor(alice, collectionId)).to.be.rejectedWith(/common\.CollectionNotFound/);
110 collectionId = await getCreatedCollectionCount(api) + 1;
111 });
112
113 await removeCollectionSponsorExpectFailure(collectionId);
114 });89 });
11590
116 it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {91 itSub('(!negative test!) Remove sponsor for a collection with collection admin permissions', async ({helper}) => {
117 const collectionId = await createCollectionExpectSuccess();92 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-1', tokenPrefix: 'RCS'});
118 await setCollectionSponsorExpectSuccess(collectionId, bob.address);93 await collection.setSponsor(alice, bob.address);
119 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);94 await collection.addAdmin(alice, {Substrate: charlie.address});
120 await removeCollectionSponsorExpectFailure(collectionId, '//Bob');95 await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
121 });96 });
12297
123 it('(!negative test!) Remove sponsor for a collection by regular user', async () => {98 itSub('(!negative test!) Remove sponsor for a collection by regular user', async ({helper}) => {
124 const collectionId = await createCollectionExpectSuccess();99 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-2', tokenPrefix: 'RCS'});
125 await setCollectionSponsorExpectSuccess(collectionId, bob.address);100 await collection.setSponsor(alice, bob.address);
126 await removeCollectionSponsorExpectFailure(collectionId, '//Bob');101 await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
127 });102 });
128103
129 it('(!negative test!) Remove sponsor in a destroyed collection', async () => {104 itSub('(!negative test!) Remove sponsor in a destroyed collection', async ({helper}) => {
130 const collectionId = await createCollectionExpectSuccess();105 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-3', tokenPrefix: 'RCS'});
131 await setCollectionSponsorExpectSuccess(collectionId, bob.address);106 await collection.setSponsor(alice, bob.address);
132 await destroyCollectionExpectSuccess(collectionId);107 await collection.burn(alice);
133 await removeCollectionSponsorExpectFailure(collectionId);108 await expect(collection.removeSponsor(alice)).to.be.rejectedWith(/common\.CollectionNotFound/);
134 });109 });
135110
136 it('Set - remove - confirm: fails', async () => {111 itSub('Set - remove - confirm: fails', async ({helper}) => {
137 const collectionId = await createCollectionExpectSuccess();112 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-4', tokenPrefix: 'RCS'});
138 await setCollectionSponsorExpectSuccess(collectionId, bob.address);113 await collection.setSponsor(alice, bob.address);
139 await removeCollectionSponsorExpectSuccess(collectionId);114 await collection.removeSponsor(alice);
140 await confirmSponsorshipExpectFailure(collectionId, '//Bob');115 await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
141 });116 });
142117
143 it('Set - confirm - remove - confirm: Sponsor cannot come back', async () => {118 itSub('Set - confirm - remove - confirm: Sponsor cannot come back', async ({helper}) => {
144 const collectionId = await createCollectionExpectSuccess();119 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-5', tokenPrefix: 'RCS'});
145 await setCollectionSponsorExpectSuccess(collectionId, bob.address);120 await collection.setSponsor(alice, bob.address);
146 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');121 await collection.confirmSponsorship(bob);
147 await removeCollectionSponsorExpectSuccess(collectionId);122 await collection.removeSponsor(alice);
148 await confirmSponsorshipExpectFailure(collectionId, '//Bob');123 await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
149 });124 });
150
151});125});
modifiedtests/src/removeFromAllowList.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi} from './substrate/substrate-api';17import {IKeyringPair} from '@polkadot/types/types';
20import {18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
21 createCollectionExpectSuccess,
22 destroyCollectionExpectSuccess,
23 enableAllowListExpectSuccess,
24 addToAllowListExpectSuccess,
25 removeFromAllowListExpectSuccess,
26 isAllowlisted,
27 findNotExistingCollection,
28 removeFromAllowListExpectFailure,
29 disableAllowListExpectSuccess,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32} from './util/helpers';
33import {IKeyringPair} from '@polkadot/types/types';
34
35chai.use(chaiAsPromised);
36const expect = chai.expect;
3719
38describe('Integration Test removeFromAllowList', () => {20describe('Integration Test removeFromAllowList', () => {
39 let alice: IKeyringPair;21 let alice: IKeyringPair;
40 let bob: IKeyringPair;22 let bob: IKeyringPair;
4123
42 before(async () => {24 before(async () => {
43 await usingApi(async (api, privateKeyWrapper) => {25 await usingPlaygrounds(async (helper, privateKey) => {
44 alice = privateKeyWrapper('//Alice');26 const donor = privateKey('//Alice');
45 bob = privateKeyWrapper('//Bob');27 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
46 });28 });
47 });29 });
4830
49 it('ensure bob is not in allowlist after removal', async () => {31 itSub('ensure bob is not in allowlist after removal', async ({helper}) => {
50 await usingApi(async api => {32 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-1', tokenPrefix: 'RFAL'});
33
34 const collectionInfo = await collection.getData();
51 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});35 expect(collectionInfo!.raw.permissions.access).to.not.equal('AllowList');
36
52 await enableAllowListExpectSuccess(alice, collectionId);37 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
53 await addToAllowListExpectSuccess(alice, collectionId, bob.address);38 await collection.addToAllowList(alice, {Substrate: bob.address});
5439 expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
40
55 await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(bob.address));41 await collection.removeFromAllowList(alice, {Substrate: bob.address});
56 expect(await isAllowlisted(api, collectionId, bob.address)).to.be.false;42 expect(await collection.getAllowList()).to.be.empty;
57 });
58 });43 });
5944
60 it('allows removal from collection with unset allowlist status', async () => {45 itSub('allows removal from collection with unset allowlist status', async ({helper}) => {
61 await usingApi(async () => {46 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-2', tokenPrefix: 'RFAL'});
47
62 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();48 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
63 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);49 await collection.addToAllowList(alice, {Substrate: bob.address});
64 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);50 expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
51
65 await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);52 await collection.setPermissions(alice, {access: 'Normal'});
6653
67 await removeFromAllowListExpectSuccess(alice, collectionWithoutAllowlistId, normalizeAccountId(bob.address));54 await collection.removeFromAllowList(alice, {Substrate: bob.address});
68 });55 expect(await collection.getAllowList()).to.be.empty;
69 });56 });
70});57});
7158
74 let bob: IKeyringPair;61 let bob: IKeyringPair;
7562
76 before(async () => {63 before(async () => {
77 await usingApi(async (api, privateKeyWrapper) => {64 await usingPlaygrounds(async (helper, privateKey) => {
78 alice = privateKeyWrapper('//Alice');65 const donor = privateKey('//Alice');
79 bob = privateKeyWrapper('//Bob');66 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
80 });67 });
81 });68 });
8269
83 it('fails on removal from not existing collection', async () => {70 itSub('fails on removal from not existing collection', async ({helper}) => {
71 const nonExistentCollectionId = (1 << 32) - 1;
84 await usingApi(async (api) => {72 await expect(helper.collection.removeFromAllowList(alice, nonExistentCollectionId, {Substrate: alice.address}))
85 const collectionId = await findNotExistingCollection(api);
86
87 await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));
88 });73 .to.be.rejectedWith(/common\.CollectionNotFound/);
89 });74 });
9075
91 it('fails on removal from removed collection', async () => {76 itSub('fails on removal from removed collection', async ({helper}) => {
92 await usingApi(async () => {77 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-3', tokenPrefix: 'RFAL'});
93 const collectionId = await createCollectionExpectSuccess();78 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
94 await enableAllowListExpectSuccess(alice, collectionId);
95 await addToAllowListExpectSuccess(alice, collectionId, bob.address);79 await collection.addToAllowList(alice, {Substrate: bob.address});
80
96 await destroyCollectionExpectSuccess(collectionId);81 await collection.burn(alice);
97
98 await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));82 await expect(collection.removeFromAllowList(alice, {Substrate: bob.address}))
99 });83 .to.be.rejectedWith(/common\.CollectionNotFound/);
100 });84 });
101});85});
10286
106 let charlie: IKeyringPair;90 let charlie: IKeyringPair;
10791
108 before(async () => {92 before(async () => {
109 await usingApi(async (api, privateKeyWrapper) => {93 await usingPlaygrounds(async (helper, privateKey) => {
110 alice = privateKeyWrapper('//Alice');94 const donor = privateKey('//Alice');
111 bob = privateKeyWrapper('//Bob');95 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
112 charlie = privateKeyWrapper('//Charlie');
113 });96 });
114 });97 });
11598
116 it('ensure address is not in allowlist after removal', async () => {99 itSub('ensure address is not in allowlist after removal', async ({helper}) => {
117 await usingApi(async api => {100 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-4', tokenPrefix: 'RFAL'});
101
118 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});102 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
119 await enableAllowListExpectSuccess(alice, collectionId);
120 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);103 await collection.addAdmin(alice, {Substrate: bob.address});
104
121 await addToAllowListExpectSuccess(alice, collectionId, charlie.address);105 await collection.addToAllowList(bob, {Substrate: charlie.address});
122 await removeFromAllowListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));106 await collection.removeFromAllowList(bob, {Substrate: charlie.address});
107
123 expect(await isAllowlisted(api, collectionId, charlie.address)).to.be.false;108 expect(await collection.getAllowList()).to.be.empty;
124 });
125 });109 });
126110
127 it('Collection admin allowed to remove from allowlist with unset allowlist status', async () => {111 itSub('Collection admin allowed to remove from allowlist with unset allowlist status', async ({helper}) => {
128 await usingApi(async () => {112 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-5', tokenPrefix: 'RFAL'});
113
129 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();114 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
130 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
131 await addCollectionAdminExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);115 await collection.addAdmin(alice, {Substrate: bob.address});
132 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);116 await collection.addToAllowList(alice, {Substrate: charlie.address});
117
133 await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);118 await collection.setPermissions(bob, {access: 'Normal'});
134 await removeFromAllowListExpectSuccess(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));119 await collection.removeFromAllowList(bob, {Substrate: charlie.address});
120
135 });121 expect(await collection.getAllowList()).to.be.empty;
136 });122 });
137123
138 it('Regular user can`t remove from allowlist', async () => {124 itSub('Regular user can`t remove from allowlist', async ({helper}) => {
139 await usingApi(async () => {125 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-6', tokenPrefix: 'RFAL'});
126
140 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();127 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
141 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);128 await collection.addToAllowList(alice, {Substrate: charlie.address});
129
142 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);130 await expect(collection.removeFromAllowList(bob, {Substrate: charlie.address}))
131 .to.be.rejectedWith(/common\.NoPermission/);
143 await removeFromAllowListExpectFailure(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));132 expect(await collection.getAllowList()).to.deep.contain({Substrate: charlie.address});
144 });
145 });133 });
146});134});
147135
modifiedtests/src/removeFromContractAllowList.test.tsdiffbeforeafterboth
20import {IKeyringPair} from '@polkadot/types/types';20import {IKeyringPair} from '@polkadot/types/types';
21import {expect} from 'chai';21import {expect} from 'chai';
2222
23// todo:playgrounds skipped again
23describe.skip('Integration Test removeFromContractAllowList', () => {24describe.skip('Integration Test removeFromContractAllowList', () => {
24 let bob: IKeyringPair;25 let bob: IKeyringPair;
2526
modifiedtests/src/rpc.test.tsdiffbeforeafterboth
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
2// This file is part of Unique Network.
3
4// Unique Network is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Unique Network is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
16
1import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
2import {expect} from 'chai';18import {usingPlaygrounds, itSub, expect} from './util/playgrounds';
3import usingApi from './substrate/substrate-api';
4import {createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, CrossAccountId, getTokenOwner, normalizeAccountId, transfer, U128_MAX} from './util/helpers';19import {crossAccountIdFromLower} from './util/playgrounds/unique';
5
6let alice: IKeyringPair;
7let bob: IKeyringPair;
8
920
10describe('integration test: RPC methods', () => {21describe('integration test: RPC methods', () => {
22 let donor: IKeyringPair;
23 let alice: IKeyringPair;
24 let bob: IKeyringPair;
25
11 before(async () => {26 before(async () => {
12 await usingApi(async (api, privateKeyWrapper) => {27 await usingPlaygrounds(async (helper, privateKey) => {
13 alice = privateKeyWrapper('//Alice');28 donor = privateKey('//Alice');
14 bob = privateKeyWrapper('//Bob');29 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
15 });30 });
16 });31 });
1732
18
19 it('returns None for fungible collection', async () => {33 itSub('returns None for fungible collection', async ({helper}) => {
20 await usingApi(async api => {
21 const collection = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});34 const collection = await helper.ft.mintCollection(alice, {name: 'RPC-1', tokenPrefix: 'RPC'});
22 await expect(getTokenOwner(api, collection, 0)).to.be.rejectedWith(/^owner == null$/);
23 });35 const owner = (await helper.callRpc('api.rpc.unique.tokenOwner', [collection.collectionId, 0])).toJSON() as any;
36 expect(owner).to.be.null;
24 });37 });
25 38
26 it('RPC method tokenOwners for fungible collection and token', async () => {39 itSub('RPC method tokenOwners for fungible collection and token', async ({helper}) => {
27 await usingApi(async (api, privateKeyWrapper) => {40 // Set-up a few token owners of all stripes
28 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};41 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
29 const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));42 const facelessCrowd = (await helper.arrange.createAccounts([0n, 0n, 0n, 0n, 0n, 0n, 0n], donor))
30 43 .map(i => {return {Substrate: i.address};});
44
31 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});45 const collection = await helper.ft.mintCollection(alice, {name: 'RPC-2', tokenPrefix: 'RPC'});
32 const collectionId = createCollectionResult.collectionId;46 // mint some maximum (u128) amounts of tokens possible
33 const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);47 await collection.mint(alice, (1n << 128n) - 1n);
34 48
35 await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);49 await collection.transfer(alice, {Substrate: bob.address}, 1000n);
36 await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);50 await collection.transfer(alice, ethAcc, 900n);
37 51
38 for (let i = 0; i < 7; i++) {52 for (let i = 0; i < facelessCrowd.length; i++) {
39 await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);53 await collection.transfer(alice, facelessCrowd[i], 1n);
40 } 54 }
41 55 // Set-up over
56
42 const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);57 const owners = await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0]);
43 const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));58 const ids = (owners.toJSON() as any[]).map(crossAccountIdFromLower);
44 const aliceID = normalizeAccountId(alice);59
45 const bobId = normalizeAccountId(bob);
46
47 // What to expect
48 // tslint:disable-next-line:no-unused-expression
49 expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);60 expect(ids).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
50 expect(owners.length == 10).to.be.true;61 expect(owners.length == 10).to.be.true;
51 62
63 // Make sure only 10 results are returned with this RPC
52 const eleven = privateKeyWrapper('11');64 const [eleven] = await helper.arrange.createAccounts([0n], donor);
53 expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;65 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
54 expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);66 expect((await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0])).length).to.be.equal(10);
55 });
56 });67 });
57});68});
modifiedtests/src/scheduler.test.tsdiffbeforeafterboth
4444
45chai.use(chaiAsPromised);45chai.use(chaiAsPromised);
4646
47// todo:playgrounds skipped ~ postponed
47describe.skip('Scheduling token and balance transfers', () => {48describe.skip('Scheduling token and balance transfers', () => {
48 let alice: IKeyringPair;49 let alice: IKeyringPair;
49 let bob: IKeyringPair;50 let bob: IKeyringPair;
modifiedtests/src/setChainLimits.test.tsdiffbeforeafterboth
23 IChainLimits,23 IChainLimits,
24} from './util/helpers';24} from './util/helpers';
2525
26// todo:playgrounds skipped ~ postponed
26describe.skip('Negative Integration Test setChainLimits', () => {27describe.skip('Negative Integration Test setChainLimits', () => {
27 let alice: IKeyringPair;28 let alice: IKeyringPair;
28 let bob: IKeyringPair;29 let bob: IKeyringPair;
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits
18import {ApiPromise} from '@polkadot/api';
19import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
20import chai from 'chai';
21import chaiAsPromised from 'chai-as-promised';
22import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
23import {19import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
24 createCollectionExpectSuccess, getCreatedCollectionCount,
25 getCreateItemResult,
26 setCollectionLimitsExpectFailure,
27 setCollectionLimitsExpectSuccess,
28 addCollectionAdminExpectSuccess,
29 queryCollectionExpectSuccess,
30} from './util/helpers';
31
32chai.use(chaiAsPromised);
33const expect = chai.expect;
34
35let alice: IKeyringPair;
36let bob: IKeyringPair;
37let collectionIdForTesting: number;
3820
39const accountTokenOwnershipLimit = 0;21const accountTokenOwnershipLimit = 0;
40const sponsoredDataSize = 0;22const sponsoredDataSize = 0;
41const sponsorTransferTimeout = 1;23const sponsorTransferTimeout = 1;
42const tokenLimit = 10;24const tokenLimit = 10;
4325
44describe('setCollectionLimits positive', () => {26describe('setCollectionLimits positive', () => {
45 let tx;27 let alice: IKeyringPair;
28 let bob: IKeyringPair;
29
46 before(async () => {30 before(async () => {
47 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
48 alice = privateKeyWrapper('//Alice');32 const donor = privateKey('//Alice');
49 bob = privateKeyWrapper('//Bob');
50 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});33 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
51 });34 });
52 });35 });
36
53 it('execute setCollectionLimits with predefined params ', async () => {37 itSub('execute setCollectionLimits with predefined params', async ({helper}) => {
54 await usingApi(async (api: ApiPromise) => {
55 tx = api.tx.unique.setCollectionLimits(
56 collectionIdForTesting,
57 {
58 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
59 sponsoredDataSize: sponsoredDataSize,
60 tokenLimit: tokenLimit,
61 sponsorTransferTimeout,
62 ownerCanTransfer: true,
63 ownerCanDestroy: true,
64 },
65 );38 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-1', tokenPrefix: 'SCL'});
39
66 const events = await submitTransactionAsync(alice, tx);40 await collection.setLimits(
67 const result = getCreateItemResult(events);41 alice,
42 {
43 accountTokenOwnershipLimit,
44 sponsoredDataSize,
45 tokenLimit,
46 sponsorTransferTimeout,
47 ownerCanTransfer: true,
48 ownerCanDestroy: true,
49 },
50 );
6851
69 // get collection limits defined previously52 // get collection limits defined previously
70 const collectionInfo = await queryCollectionExpectSuccess(api, collectionIdForTesting);53 const collectionInfo = await collection.getEffectiveLimits();
7154
72 // tslint:disable-next-line:no-unused-expression
73 expect(result.success).to.be.true;
74 expect(collectionInfo.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.equal(accountTokenOwnershipLimit);55 expect(collectionInfo.accountTokenOwnershipLimit).to.be.equal(accountTokenOwnershipLimit);
75 expect(collectionInfo.limits.sponsoredDataSize.unwrap().toNumber()).to.be.equal(sponsoredDataSize);56 expect(collectionInfo.sponsoredDataSize).to.be.equal(sponsoredDataSize);
76 expect(collectionInfo.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);57 expect(collectionInfo.tokenLimit).to.be.equal(tokenLimit);
77 expect(collectionInfo.limits.sponsorTransferTimeout.unwrap().toNumber()).to.be.equal(sponsorTransferTimeout);58 expect(collectionInfo.sponsorTransferTimeout).to.be.equal(sponsorTransferTimeout);
78 expect(collectionInfo.limits.ownerCanTransfer.unwrap().toJSON()).to.be.true;59 expect(collectionInfo.ownerCanTransfer).to.be.true;
79 expect(collectionInfo.limits.ownerCanDestroy.unwrap().toJSON()).to.be.true;60 expect(collectionInfo.ownerCanDestroy).to.be.true;
80 });
81 });61 });
8262
83 it('Set the same token limit twice', async () => {63 itSub('Set the same token limit twice', async ({helper}) => {
84 await usingApi(async (api: ApiPromise) => {64 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-2', tokenPrefix: 'SCL'});
8565
86 const collectionLimits = {66 const collectionLimits = {
87 accountTokenOwnershipLimit: accountTokenOwnershipLimit,67 accountTokenOwnershipLimit,
88 sponsoredMintSize: sponsoredDataSize,68 sponsoredDataSize,
89 tokenLimit: tokenLimit,69 tokenLimit,
90 sponsorTransferTimeout,70 sponsorTransferTimeout,
91 ownerCanTransfer: true,71 ownerCanTransfer: true,
92 ownerCanDestroy: true,72 ownerCanDestroy: true,
73 };
74
93 };75 await collection.setLimits(alice, collectionLimits);
9476
95 // The first time
96 const tx1 = api.tx.unique.setCollectionLimits(
97 collectionIdForTesting,
98 collectionLimits,
99 );
100 const events1 = await submitTransactionAsync(alice, tx1);
101 const result1 = getCreateItemResult(events1);
102 expect(result1.success).to.be.true;
103 const collectionInfo1 = await queryCollectionExpectSuccess(api, collectionIdForTesting);77 const collectionInfo1 = await collection.getEffectiveLimits();
78
104 expect(collectionInfo1.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);79 expect(collectionInfo1.tokenLimit).to.be.equal(tokenLimit);
10580
106 // The second time
107 const tx2 = api.tx.unique.setCollectionLimits(81 await collection.setLimits(alice, collectionLimits);
108 collectionIdForTesting,
109 collectionLimits,
110 );
111 const events2 = await submitTransactionAsync(alice, tx2);
112 const result2 = getCreateItemResult(events2);
113 expect(result2.success).to.be.true;
114 const collectionInfo2 = await queryCollectionExpectSuccess(api, collectionIdForTesting);82 const collectionInfo2 = await collection.getEffectiveLimits();
115 expect(collectionInfo2.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);83 expect(collectionInfo2.tokenLimit).to.be.equal(tokenLimit);
116 });
117 });84 });
11885
119 it('execute setCollectionLimits from admin collection', async () => {86 itSub('execute setCollectionLimits from admin collection', async ({helper}) => {
87 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-3', tokenPrefix: 'SCL'});
120 await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);88 await collection.addAdmin(alice, {Substrate: bob.address});
89
90 const collectionLimits = {
91 accountTokenOwnershipLimit,
92 sponsoredDataSize,
93 // sponsoredMintSize,
94 tokenLimit,
95 };
96
121 await usingApi(async (api: ApiPromise) => {97 await expect(collection.setLimits(alice, collectionLimits)).to.not.be.rejected;
122 tx = api.tx.unique.setCollectionLimits(
123 collectionIdForTesting,
124 {
125 accountTokenOwnershipLimit,
126 sponsoredDataSize,
127 // sponsoredMintSize,
128 tokenLimit,
129 },
130 );
131 await expect(submitTransactionAsync(bob, tx)).to.be.not.rejected;
132 });
133 });98 });
134});99});
135100
136describe('setCollectionLimits negative', () => {101describe('setCollectionLimits negative', () => {
137 let tx;102 let alice: IKeyringPair;
103 let bob: IKeyringPair;
104
138 before(async () => {105 before(async () => {
139 await usingApi(async (api, privateKeyWrapper) => {106 await usingPlaygrounds(async (helper, privateKey) => {
140 alice = privateKeyWrapper('//Alice');107 const donor = privateKey('//Alice');
141 bob = privateKeyWrapper('//Bob');
142 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});108 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
143 });109 });
144 });110 });
111
145 it('execute setCollectionLimits for not exists collection', async () => {112 itSub('execute setCollectionLimits for not exists collection', async ({helper}) => {
113 const nonExistentCollectionId = (1 << 32) - 1;
146 await usingApi(async (api: ApiPromise) => {114 await expect(helper.collection.setLimits(
147 const collectionCount = await getCreatedCollectionCount(api);115 alice,
148 const nonExistedCollectionId = collectionCount + 1;
149 tx = api.tx.unique.setCollectionLimits(
150 nonExistedCollectionId,116 nonExistentCollectionId,
151 {117 {
152 accountTokenOwnershipLimit,118 accountTokenOwnershipLimit,
153 sponsoredDataSize,119 sponsoredDataSize,
154 // sponsoredMintSize,120 // sponsoredMintSize,
155 tokenLimit,121 tokenLimit,
156 },122 },
157 );123 )).to.be.rejectedWith(/common\.CollectionNotFound/);
158 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
159 });
160 });124 });
125
161 it('execute setCollectionLimits from user who is not owner of this collection', async () => {126 itSub('execute setCollectionLimits from user who is not owner of this collection', async ({helper}) => {
127 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-1', tokenPrefix: 'SCL'});
128
162 await usingApi(async (api: ApiPromise) => {129 await expect(collection.setLimits(bob, {
163 tx = api.tx.unique.setCollectionLimits(
164 collectionIdForTesting,
165 {
166 accountTokenOwnershipLimit,130 accountTokenOwnershipLimit,
167 sponsoredDataSize,131 sponsoredDataSize,
168 // sponsoredMintSize,132 // sponsoredMintSize,
169 tokenLimit,133 tokenLimit,
170 },134 })).to.be.rejectedWith(/common\.NoPermission/);
171 );
172 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
173 });
174 });135 });
175136
176 it('fails when trying to enable OwnerCanTransfer after it was disabled', async () => {137 itSub('fails when trying to enable OwnerCanTransfer after it was disabled', async ({helper}) => {
177 const collectionId = await createCollectionExpectSuccess();138 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-2', tokenPrefix: 'SCL'});
139
178 await setCollectionLimitsExpectSuccess(alice, collectionId, {140 await collection.setLimits(alice, {
179 accountTokenOwnershipLimit: accountTokenOwnershipLimit,141 accountTokenOwnershipLimit,
180 sponsoredMintSize: sponsoredDataSize,142 sponsoredDataSize,
181 tokenLimit: tokenLimit,143 tokenLimit,
182 sponsorTransferTimeout,144 sponsorTransferTimeout,
183 ownerCanTransfer: false,145 ownerCanTransfer: false,
184 ownerCanDestroy: true,146 ownerCanDestroy: true,
185 });147 });
148
186 await setCollectionLimitsExpectFailure(alice, collectionId, {149 await expect(collection.setLimits(alice, {
187 accountTokenOwnershipLimit: accountTokenOwnershipLimit,150 accountTokenOwnershipLimit,
188 sponsoredMintSize: sponsoredDataSize,151 sponsoredDataSize,
189 tokenLimit: tokenLimit,152 tokenLimit,
190 sponsorTransferTimeout,153 sponsorTransferTimeout,
191 ownerCanTransfer: true,154 ownerCanTransfer: true,
192 ownerCanDestroy: true,155 ownerCanDestroy: true,
193 });156 })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
194 });157 });
195158
196 it('fails when trying to enable OwnerCanDestroy after it was disabled', async () => {159 itSub('fails when trying to enable OwnerCanDestroy after it was disabled', async ({helper}) => {
197 const collectionId = await createCollectionExpectSuccess();160 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-3', tokenPrefix: 'SCL'});
161
198 await setCollectionLimitsExpectSuccess(alice, collectionId, {162 await collection.setLimits(alice, {
199 accountTokenOwnershipLimit: accountTokenOwnershipLimit,163 accountTokenOwnershipLimit,
200 sponsoredMintSize: sponsoredDataSize,164 sponsoredDataSize,
201 tokenLimit: tokenLimit,165 tokenLimit,
202 sponsorTransferTimeout,166 sponsorTransferTimeout,
203 ownerCanTransfer: true,167 ownerCanTransfer: true,
204 ownerCanDestroy: false,168 ownerCanDestroy: false,
205 });169 });
170
206 await setCollectionLimitsExpectFailure(alice, collectionId, {171 await expect(collection.setLimits(alice, {
207 accountTokenOwnershipLimit: accountTokenOwnershipLimit,172 accountTokenOwnershipLimit,
208 sponsoredMintSize: sponsoredDataSize,173 sponsoredDataSize,
209 tokenLimit: tokenLimit,174 tokenLimit,
210 sponsorTransferTimeout,175 sponsorTransferTimeout,
211 ownerCanTransfer: true,176 ownerCanTransfer: true,
212 ownerCanDestroy: true,177 ownerCanDestroy: true,
213 });178 })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
214 });179 });
215180
216 it('Setting the higher token limit fails', async () => {181 itSub('Setting the higher token limit fails', async ({helper}) => {
217 await usingApi(async () => {182 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-4', tokenPrefix: 'SCL'});
218183
219 const collectionId = await createCollectionExpectSuccess();
220 const collectionLimits = {184 const collectionLimits = {
221 accountTokenOwnershipLimit: accountTokenOwnershipLimit,185 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
222 sponsoredMintSize: sponsoredDataSize,186 sponsoredMintSize: sponsoredDataSize,
227 };191 };
228192
229 // The first time193 // The first time
230 await setCollectionLimitsExpectSuccess(alice, collectionId, collectionLimits);194 await collection.setLimits(alice, collectionLimits);
231195
232 // The second time - higher token limit196 // The second time - higher token limit
233 collectionLimits.tokenLimit += 1;197 collectionLimits.tokenLimit += 1;
234 await setCollectionLimitsExpectFailure(alice, collectionId, collectionLimits);198 await expect(collection.setLimits(alice, collectionLimits)).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);
235 });
236 });199 });
237
238});200});
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi} from './substrate/substrate-api';17import {IKeyringPair} from '@polkadot/types/types';
20import {createCollectionExpectSuccess,18import {itSub, usingPlaygrounds, expect, Pallets} from './util/playgrounds';
21 setCollectionSponsorExpectSuccess,
22 destroyCollectionExpectSuccess,
23 setCollectionSponsorExpectFailure,
24 addCollectionAdminExpectSuccess,
25 getCreatedCollectionCount,
26 requirePallets,
27 Pallets,
28} from './util/helpers';
29import {IKeyringPair} from '@polkadot/types/types';
30
31chai.use(chaiAsPromised);
32
33let alice: IKeyringPair;
34let bob: IKeyringPair;
35let charlie: IKeyringPair;
3619
37describe('integration test: ext. setCollectionSponsor():', () => {20describe('integration test: ext. setCollectionSponsor():', () => {
21 let alice: IKeyringPair;
22 let bob: IKeyringPair;
23 let charlie: IKeyringPair;
3824
39 before(async () => {25 before(async () => {
40 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
41 alice = privateKeyWrapper('//Alice');27 const donor = privateKey('//Alice');
42 bob = privateKeyWrapper('//Bob');28 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
43 charlie = privateKeyWrapper('//Charlie');
44 });29 });
45 });30 });
4631
47 it('Set NFT collection sponsor', async () => {32 itSub('Set NFT collection sponsor', async ({helper}) => {
48 const collectionId = await createCollectionExpectSuccess();33 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-1-NFT', tokenPrefix: 'SCS'});
49 await setCollectionSponsorExpectSuccess(collectionId, bob.address);34 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
35
36 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
37 Unconfirmed: bob.address,
38 });
50 });39 });
40
51 it('Set Fungible collection sponsor', async () => {41 itSub('Set Fungible collection sponsor', async ({helper}) => {
52 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});42 const collection = await helper.ft.mintCollection(alice, {name: 'SetCollectionSponsor-1-FT', tokenPrefix: 'SCS'});
53 await setCollectionSponsorExpectSuccess(collectionId, bob.address);43 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
44
45 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
46 Unconfirmed: bob.address,
47 });
54 });48 });
49
55 it('Set ReFungible collection sponsor', async function() {50 itSub.ifWithPallets('Set ReFungible collection sponsor', [Pallets.ReFungible], async ({helper}) => {
56 await requirePallets(this, [Pallets.ReFungible]);
57
58 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});51 const collection = await helper.rft.mintCollection(alice, {name: 'SetCollectionSponsor-1-RFT', tokenPrefix: 'SCS'});
59 await setCollectionSponsorExpectSuccess(collectionId, bob.address);52 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
53
54 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
55 Unconfirmed: bob.address,
56 });
60 });57 });
6158
62 it('Set the same sponsor repeatedly', async () => {59 itSub('Set the same sponsor repeatedly', async ({helper}) => {
63 const collectionId = await createCollectionExpectSuccess();60 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-2', tokenPrefix: 'SCS'});
64 await setCollectionSponsorExpectSuccess(collectionId, bob.address);61 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
65 await setCollectionSponsorExpectSuccess(collectionId, bob.address);62 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
63
64 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
65 Unconfirmed: bob.address,
66 });
66 });67 });
68
67 it('Replace collection sponsor', async () => {69 itSub('Replace collection sponsor', async ({helper}) => {
68 const collectionId = await createCollectionExpectSuccess();70 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-3', tokenPrefix: 'SCS'});
69 await setCollectionSponsorExpectSuccess(collectionId, bob.address);71 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
70 await setCollectionSponsorExpectSuccess(collectionId, charlie.address);72 await expect(collection.setSponsor(alice, charlie.address)).to.be.not.rejected;
73
74 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
75 Unconfirmed: charlie.address,
76 });
71 });77 });
78
72 it('Collection admin add sponsor', async () => {79 itSub('Collection admin add sponsor', async ({helper}) => {
73 const collectionId = await createCollectionExpectSuccess();80 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-4', tokenPrefix: 'SCS'});
74 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);81 await collection.addAdmin(alice, {Substrate: bob.address});
75 await setCollectionSponsorExpectSuccess(collectionId, charlie.address, '//Bob');82 await expect(collection.setSponsor(bob, charlie.address)).to.be.not.rejected;
83
84 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
85 Unconfirmed: charlie.address,
86 });
76 });87 });
77});88});
7889
79describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {90describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {
91 let alice: IKeyringPair;
92 let bob: IKeyringPair;
93
80 before(async () => {94 before(async () => {
81 await usingApi(async (api, privateKeyWrapper) => {95 await usingPlaygrounds(async (helper, privateKey) => {
82 alice = privateKeyWrapper('//Alice');96 const donor = privateKey('//Alice');
83 bob = privateKeyWrapper('//Bob');97 [alice, bob] = await helper.arrange.createAccounts([10n, 5n], donor);
84 charlie = privateKeyWrapper('//Charlie');
85 });98 });
86 });99 });
87100
88 it('(!negative test!) Add sponsor with a non-owner', async () => {101 itSub('(!negative test!) Add sponsor with a non-owner', async ({helper}) => {
89 const collectionId = await createCollectionExpectSuccess();102 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-1', tokenPrefix: 'SCS'});
90 await setCollectionSponsorExpectFailure(collectionId, bob.address, '//Bob');103 await expect(collection.setSponsor(bob, bob.address))
104 .to.be.rejectedWith(/common\.NoPermission/);
91 });105 });
106
92 it('(!negative test!) Add sponsor to a collection that never existed', async () => {107 itSub('(!negative test!) Add sponsor to a collection that never existed', async ({helper}) => {
93 // Find the collection that never existed
94 let collectionId = 0;
95 await usingApi(async (api) => {
96 collectionId = await getCreatedCollectionCount(api) + 1;108 const collectionId = (1 << 32) - 1;
97 });
98
99 await setCollectionSponsorExpectFailure(collectionId, bob.address);109 await expect(helper.collection.setSponsor(alice, collectionId, bob.address))
110 .to.be.rejectedWith(/common\.CollectionNotFound/);
100 });111 });
112
101 it('(!negative test!) Add sponsor to a collection that was destroyed', async () => {113 itSub('(!negative test!) Add sponsor to a collection that was destroyed', async ({helper}) => {
102 const collectionId = await createCollectionExpectSuccess();114 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-2', tokenPrefix: 'SCS'});
103 await destroyCollectionExpectSuccess(collectionId);115 await collection.burn(alice);
104 await setCollectionSponsorExpectFailure(collectionId, bob.address);116 await expect(collection.setSponsor(alice, bob.address))
117 .to.be.rejectedWith(/common\.CollectionNotFound/);
105 });118 });
106});119});
107120
modifiedtests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth
25 setContractSponsoringRateLimitExpectSuccess,25 setContractSponsoringRateLimitExpectSuccess,
26} from './util/helpers';26} from './util/helpers';
2727
28// todo:playgrounds postponed skipped test
28describe.skip('Integration Test setContractSponsoringRateLimit', () => {29describe.skip('Integration Test setContractSponsoringRateLimit', () => {
29 it('ensure sponsored contract can\'t be called twice without pause for free', async () => {30 it('ensure sponsored contract can\'t be called twice without pause for free', async () => {
30 await usingApi(async (api, privateKeyWrapper) => {31 await usingApi(async (api, privateKeyWrapper) => {
modifiedtests/src/setMintPermission.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import usingApi from './substrate/substrate-api';
19import {18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
20 addToAllowListExpectSuccess,
21 createCollectionExpectSuccess,
22 createItemExpectFailure,
23 createItemExpectSuccess,
24 destroyCollectionExpectSuccess,
25 enableAllowListExpectSuccess,
26 findNotExistingCollection,
27 setMintPermissionExpectFailure,
28 setMintPermissionExpectSuccess,
29 addCollectionAdminExpectSuccess,
30} from './util/helpers';
3119
32describe('Integration Test setMintPermission', () => {20describe('Integration Test setMintPermission', () => {
33 let alice: IKeyringPair;21 let alice: IKeyringPair;
34 let bob: IKeyringPair;22 let bob: IKeyringPair;
3523
36 before(async () => {24 before(async () => {
37 await usingApi(async (api, privateKeyWrapper) => {25 await usingPlaygrounds(async (helper, privateKey) => {
38 alice = privateKeyWrapper('//Alice');26 const donor = privateKey('//Alice');
39 bob = privateKeyWrapper('//Bob');27 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
40 });28 });
41 });29 });
4230
43 it('ensure allow-listed non-privileged address can mint tokens', async () => {31 itSub('ensure allow-listed non-privileged address can mint tokens', async ({helper}) => {
44 await usingApi(async () => {32 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-1', description: '', tokenPrefix: 'SMP'});
45 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});33 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
46 await enableAllowListExpectSuccess(alice, collectionId);34 await collection.addToAllowList(alice, {Substrate: bob.address});
47 await setMintPermissionExpectSuccess(alice, collectionId, true);35
48 await addToAllowListExpectSuccess(alice, collectionId, bob.address);36 await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected;
49
50 await createItemExpectSuccess(bob, collectionId, 'NFT');
51 });
52 });37 });
5338
54 it('can be enabled twice', async () => {39 itSub('can be enabled twice', async ({helper}) => {
55 await usingApi(async () => {40 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-2', description: '', tokenPrefix: 'SMP'});
56 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});41 expect((await collection.getData())?.raw.permissions.access).to.not.equal('AllowList');
42
57 await setMintPermissionExpectSuccess(alice, collectionId, true);43 await collection.setPermissions(alice, {mintMode: true});
58 await setMintPermissionExpectSuccess(alice, collectionId, true);44 await collection.setPermissions(alice, {mintMode: true});
59 });45 expect((await collection.getData())?.raw.permissions.mintMode).to.be.true;
60 });46 });
6147
62 it('can be disabled twice', async () => {48 itSub('can be disabled twice', async ({helper}) => {
63 await usingApi(async () => {49 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-3', description: '', tokenPrefix: 'SMP'});
50 expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
51
52 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
53 expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
64 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});54 expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
55
65 await setMintPermissionExpectSuccess(alice, collectionId, true);56 await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
66 await setMintPermissionExpectSuccess(alice, collectionId, false);57 await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
67 await setMintPermissionExpectSuccess(alice, collectionId, false);58 expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
68 });59 expect((await collection.getData())?.raw.permissions.mintMode).to.equal(false);
69 });60 });
7061
71 it('Collection admin success on set', async () => {62 itSub('Collection admin success on set', async ({helper}) => {
63 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-4', description: '', tokenPrefix: 'SMP'});
72 await usingApi(async () => {64 await collection.addAdmin(alice, {Substrate: bob.address});
73 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});65 await collection.setPermissions(bob, {access: 'AllowList', mintMode: true});
74 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);66
75 await setMintPermissionExpectSuccess(bob, collectionId, true);67 expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
76 });68 expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
77 });69 });
78});70});
7971
82 let bob: IKeyringPair;74 let bob: IKeyringPair;
8375
84 before(async () => {76 before(async () => {
85 await usingApi(async (api, privateKeyWrapper) => {77 await usingPlaygrounds(async (helper, privateKey) => {
86 alice = privateKeyWrapper('//Alice');78 const donor = privateKey('//Alice');
87 bob = privateKeyWrapper('//Bob');79 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
88 });80 });
89 });81 });
9082
91 it('fails on not existing collection', async () => {83 itSub('fails on not existing collection', async ({helper}) => {
84 const collectionId = (1 << 32) - 1;
92 await usingApi(async (api) => {85 await expect(helper.collection.setPermissions(alice, collectionId, {mintMode: true}))
93 const nonExistingCollection = await findNotExistingCollection(api);
94 await setMintPermissionExpectFailure(alice, nonExistingCollection, true);
95 });86 .to.be.rejectedWith(/common\.CollectionNotFound/);
96 });87 });
9788
98 it('fails on removed collection', async () => {89 itSub('fails on removed collection', async ({helper}) => {
90 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-1', tokenPrefix: 'SMP'});
91 await collection.burn(alice);
92
99 await usingApi(async () => {93 await expect(collection.setPermissions(alice, {mintMode: true}))
100 const removedCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
101 await destroyCollectionExpectSuccess(removedCollectionId);
102
103 await setMintPermissionExpectFailure(alice, removedCollectionId, true);
104 });94 .to.be.rejectedWith(/common\.CollectionNotFound/);
105 });95 });
10696
107 it('fails when not collection owner tries to set mint status', async () => {97 itSub('fails when non-owner tries to set mint status', async ({helper}) => {
108 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});98 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-2', tokenPrefix: 'SMP'});
109 await enableAllowListExpectSuccess(alice, collectionId);99
110 await setMintPermissionExpectFailure(bob, collectionId, true);100 await expect(collection.setPermissions(bob, {mintMode: true}))
101 .to.be.rejectedWith(/common\.NoPermission/);
111 });102 });
112103
113 it('ensure non-allow-listed non-privileged address can\'t mint tokens', async () => {104 itSub('ensure non-allow-listed non-privileged address can\'t mint tokens', async ({helper}) => {
105 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-3', tokenPrefix: 'SMP'});
106 await collection.setPermissions(alice, {mintMode: true});
107
114 await usingApi(async () => {108 await expect(collection.mintToken(bob, {Substrate: bob.address}))
115 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
116 await enableAllowListExpectSuccess(alice, collectionId);
117 await setMintPermissionExpectSuccess(alice, collectionId, true);
118
119 await createItemExpectFailure(bob, collectionId, 'NFT');
120 });109 .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
121 });110 });
122});111});
123112
modifiedtests/src/setPublicAccessMode.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
18import {ApiPromise} from '@polkadot/api';
19import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
20import chai from 'chai';
21import chaiAsPromised from 'chai-as-promised';
22import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api';
23import {19import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
24 addToAllowListExpectSuccess,20
25 createCollectionExpectSuccess,21describe('Integration Test setPublicAccessMode(): ', () => {
26 createItemExpectSuccess,
27 destroyCollectionExpectSuccess,
28 enablePublicMintingExpectSuccess,
29 enableAllowListExpectSuccess,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32 getCreatedCollectionCount,
33} from './util/helpers';
34
35chai.use(chaiAsPromised);
36const expect = chai.expect;
37
38let alice: IKeyringPair;22 let alice: IKeyringPair;
39let bob: IKeyringPair;23 let bob: IKeyringPair;
4024
41describe('Integration Test setPublicAccessMode(): ', () => {
42 before(async () => {25 before(async () => {
43 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
44 alice = privateKeyWrapper('//Alice');27 const donor = privateKey('//Alice');
45 bob = privateKeyWrapper('//Bob');28 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
46 });29 });
47 });30 });
4831
49 it('Run extrinsic with collection id parameters, set the allowlist mode for the collection', async () => {32 itSub('Runs extrinsic with collection id parameters, sets the allowlist mode for the collection', async ({helper}) => {
50 await usingApi(async () => {33 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-1', tokenPrefix: 'TF'});
51 const collectionId: number = await createCollectionExpectSuccess();34 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
52 await enableAllowListExpectSuccess(alice, collectionId);
53 await enablePublicMintingExpectSuccess(alice, collectionId);
54 await addToAllowListExpectSuccess(alice, collectionId, bob.address);35 await collection.addToAllowList(alice, {Substrate: bob.address});
36
55 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);37 await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.not.rejected;
56 });
57 });38 });
5839
59 it('Allowlisted collection limits', async () => {40 itSub('Allowlisted collection limits', async ({helper}) => {
41 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-2', tokenPrefix: 'TF'});
42 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
43
60 await usingApi(async (api: ApiPromise) => {44 await expect(collection.mintToken(bob, {Substrate: bob.address}))
61 const collectionId = await createCollectionExpectSuccess();
62 await enableAllowListExpectSuccess(alice, collectionId);
63 await enablePublicMintingExpectSuccess(alice, collectionId);
64 const tx = api.tx.unique.createItem(collectionId, normalizeAccountId(bob.address), 'NFT');
65 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;45 .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
66 });
67 });46 });
47
48 itSub('setPublicAccessMode by collection admin', async ({helper}) => {
49 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-4', tokenPrefix: 'TF'});
50 await collection.addAdmin(alice, {Substrate: bob.address});
51
52 await expect(collection.setPermissions(bob, {access: 'AllowList'})).to.be.not.rejected;
53 });
68});54});
6955
70describe('Negative Integration Test ext. setPublicAccessMode(): ', () => {56describe('Negative Integration Test ext. setPublicAccessMode(): ', () => {
57 let alice: IKeyringPair;
58 let bob: IKeyringPair;
59
71 it('Set a non-existent collection', async () => {60 before(async () => {
72 await usingApi(async (api: ApiPromise) => {61 await usingPlaygrounds(async (helper, privateKey) => {
73 // tslint:disable-next-line: radix
74 const collectionId = await getCreatedCollectionCount(api) + 1;62 const donor = privateKey('//Alice');
75 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});63 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
76 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
77 });64 });
78 });65 });
7966
80 it('Set the collection that has been deleted', async () => {67 itSub('Sets a non-existent collection', async ({helper}) => {
68 const collectionId = (1 << 32) - 1;
81 await usingApi(async (api: ApiPromise) => {69 await expect(helper.collection.setPermissions(alice, collectionId, {access: 'AllowList'}))
82 // tslint:disable-next-line: no-bitwise
83 const collectionId = await createCollectionExpectSuccess();
84 await destroyCollectionExpectSuccess(collectionId);
85 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
86 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;70 .to.be.rejectedWith(/common\.CollectionNotFound/);
87 });
88 });71 });
8972
90 it('Re-set the list mode already set in quantity', async () => {73 itSub('Sets the collection that has been deleted', async ({helper}) => {
74 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-1', tokenPrefix: 'TF'});
75 await collection.burn(alice);
76
91 await usingApi(async () => {77 await expect(collection.setPermissions(alice, {access: 'AllowList'}))
92 const collectionId: number = await createCollectionExpectSuccess();
93 await enableAllowListExpectSuccess(alice, collectionId);
94 await enableAllowListExpectSuccess(alice, collectionId);
95 });78 .to.be.rejectedWith(/common\.CollectionNotFound/);
96 });79 });
9780
98 it('Execute method not on behalf of the collection owner', async () => {81 itSub('Re-sets the list mode already set in quantity', async ({helper}) => {
99 await usingApi(async (api: ApiPromise) => {
100 // tslint:disable-next-line: no-bitwise
101 const collectionId = await createCollectionExpectSuccess();82 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-2', tokenPrefix: 'TF'});
102 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
103 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
104 });83 await collection.setPermissions(alice, {access: 'AllowList'});
84 await collection.setPermissions(alice, {access: 'AllowList'});
105 });85 });
10686
107 it('setPublicAccessMode by collection admin', async () => {87 itSub('Executes method as a malefactor', async ({helper}) => {
88 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-3', tokenPrefix: 'TF'});
89
108 await usingApi(async (api: ApiPromise) => {90 await expect(collection.setPermissions(bob, {access: 'AllowList'}))
109 // tslint:disable-next-line: no-bitwise
110 const collectionId = await createCollectionExpectSuccess();
111 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
112 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
113 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.not.rejected;91 .to.be.rejectedWith(/common\.NoPermission/);
114 });
115 });92 });
116});93});
117
118describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {
119 before(async () => {
120 await usingApi(async (api, privateKeyWrapper) => {
121 alice = privateKeyWrapper('//Alice');
122 bob = privateKeyWrapper('//Bob');
123 });
124 });
125});
12694
modifiedtests/src/toggleContractAllowList.test.tsdiffbeforeafterboth
31const value = 0;31const value = 0;
32const gasLimit = 3000n * 1000000n;32const gasLimit = 3000n * 1000000n;
3333
34// todo:playgrounds skipped ~ postpone
34describe.skip('Integration Test toggleContractAllowList', () => {35describe.skip('Integration Test toggleContractAllowList', () => {
3536
36 it('Enable allow list contract mode', async () => {37 it('Enable allow list contract mode', async () => {
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import {expect} from 'chai';18import {itEth, usingEthPlaygrounds} from './eth/util/playgrounds';
20import getBalance from './substrate/get-balance';
21import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
22import {19import {itSub, Pallets, usingPlaygrounds, expect} from './util/playgrounds';
23 burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,
24 destroyCollectionExpectSuccess,
25 findUnusedAddress,
26 getCreateCollectionResult,
27 getCreateItemResult,
28 transferExpectFailure,
29 transferExpectSuccess,
30 addCollectionAdminExpectSuccess,
31 getCreatedCollectionCount,
32 toSubstrateAddress,
33 getTokenOwner,
34 normalizeAccountId,
35 getBalance as getTokenBalance,
36 transferFromExpectSuccess,
37 transferFromExpectFail,
38 requirePallets,
39 Pallets,
40} from './util/helpers';
41import {
42 subToEth,
43 itWeb3,
44} from './eth/util/helpers';
45import {request} from 'https';
4620
21describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
47let alice: IKeyringPair;22 let alice: IKeyringPair;
48let bob: IKeyringPair;23 let bob: IKeyringPair;
49let charlie: IKeyringPair;
5024
51describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
52 before(async () => {25 before(async () => {
53 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
54 alice = privateKeyWrapper('//Alice');27 const donor = privateKey('//Alice');
55 bob = privateKeyWrapper('//Bob');28 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);
56 });29 });
57 });30 });
58 31
59 it('Balance transfers and check balance', async () => {32 itSub('Balance transfers and check balance', async ({helper}) => {
60 await usingApi(async (api, privateKeyWrapper) => {33 const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);
61 const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alice.address, bob.address]);34 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
6235
63 const transfer = api.tx.balances.transfer(bob.address, 1n);36 expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;
64 const events = await submitTransactionAsync(alice, transfer);
65 const result = getCreateItemResult(events);
66 // tslint:disable-next-line:no-unused-expression
67 expect(result.success).to.be.true;
6837
69 const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alice.address, bob.address]);38 const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);
39 const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);
7040
71 // tslint:disable-next-line:no-unused-expression41 expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
72 expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
73 // tslint:disable-next-line:no-unused-expression42 expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
74 expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
75 });
76 });43 });
7744
78 it('Inability to pay fees error message is correct', async () => {45 itSub('Inability to pay fees error message is correct', async ({helper, privateKey}) => {
79 await usingApi(async (api, privateKeyWrapper) => {
80 // Find unused address46 const donor = privateKey('//Alice');
81 const pk = await findUnusedAddress(api, privateKeyWrapper);47 const [zero] = await helper.arrange.createAccounts([0n], donor);
8248
83 const badTransfer = api.tx.balances.transfer(bob.address, 1n);49 // console.error = () => {};
84 // const events = await submitTransactionAsync(pk, badTransfer);
85 const badTransaction = async () => {
86 const events = await submitTransactionAsync(pk, badTransfer);50 // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.
87 const result = getCreateCollectionResult(events);
88 // tslint:disable-next-line:no-unused-expression
89 expect(result.success).to.be.false;51 await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))
90 };
91 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');52 .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
92 });
93 });53 });
9454
95 it('[nft] User can transfer owned token', async () => {55 itSub('[nft] User can transfer owned token', async ({helper}) => {
96 const nftCollectionId = await createCollectionExpectSuccess();56 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});
97 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');57 const nft = await collection.mintToken(alice);
58
98 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');59 await nft.transfer(alice, {Substrate: bob.address});
60 expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});
99 });61 });
10062
101 it('[fungible] User can transfer owned token', async () => {63 itSub('[fungible] User can transfer owned token', async ({helper}) => {
102 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});64 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});
103 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');65 await collection.mint(alice, 10n);
66
67 await collection.transfer(alice, {Substrate: bob.address}, 9n);
104 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');68 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
69 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
105 });70 });
10671
107 it('[refungible] User can transfer owned token', async function() {72 itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
108 await requirePallets(this, [Pallets.ReFungible]);73 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
74 const rft = await collection.mintToken(alice, 10n);
10975
110 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});76 await rft.transfer(alice, {Substrate: bob.address}, 9n);
111 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');77 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
112 await transferExpectSuccess(78 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
113 reFungibleCollectionId,
114 newReFungibleTokenId,
115 alice,
116 bob,
117 100,
118 'ReFungible',
119 );
120 });79 });
12180
122 it('[nft] Collection admin can transfer owned token', async () => {81 itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {
123 const nftCollectionId = await createCollectionExpectSuccess();82 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});
124 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);83 await collection.addAdmin(alice, {Substrate: bob.address});
84
125 const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);85 const nft = await collection.mintToken(bob, {Substrate: bob.address});
126 await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');86 await nft.transfer(bob, {Substrate: alice.address});
87
88 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
127 });89 });
12890
129 it('[fungible] Collection admin can transfer owned token', async () => {91 itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {
130 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});92 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});
131 await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);93 await collection.addAdmin(alice, {Substrate: bob.address});
94
132 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);95 await collection.mint(bob, 10n, {Substrate: bob.address});
133 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');96 await collection.transfer(bob, {Substrate: alice.address}, 1n);
97
98 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
99 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
134 });100 });
135101
136 it('[refungible] Collection admin can transfer owned token', async function() {102 itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
137 await requirePallets(this, [Pallets.ReFungible]);103 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});
104 await collection.addAdmin(alice, {Substrate: bob.address});
138105
139 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});106 const rft = await collection.mintToken(bob, 10n, {Substrate: bob.address});
140 await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);107 await rft.transfer(bob, {Substrate: alice.address}, 1n);
108
141 const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);109 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
142 await transferExpectSuccess(110 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
143 reFungibleCollectionId,
144 newReFungibleTokenId,
145 bob,
146 alice,
147 100,
148 'ReFungible',
149 );
150 });111 });
151});112});
152113
153describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {114describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
115 let alice: IKeyringPair;
116 let bob: IKeyringPair;
117
154 before(async () => {118 before(async () => {
155 await usingApi(async (api, privateKeyWrapper) => {119 await usingPlaygrounds(async (helper, privateKey) => {
156 alice = privateKeyWrapper('//Alice');120 const donor = privateKey('//Alice');
157 bob = privateKeyWrapper('//Bob');121 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);
158 charlie = privateKeyWrapper('//Charlie');
159 });122 });
160 });123 });
161124
162 it('[nft] Transfer with not existed collection_id', async () => {125 itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {
163 await usingApi(async (api) => {
164 const nftCollectionCount = await getCreatedCollectionCount(api);126 const collectionId = (1 << 32) - 1;
165 await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);127 await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
166 });128 .to.be.rejectedWith(/common\.CollectionNotFound/);
167 });129 });
168130
169 it('[fungible] Transfer with not existed collection_id', async () => {131 itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {
170 await usingApi(async (api) => {
171 const fungibleCollectionCount = await getCreatedCollectionCount(api);132 const collectionId = (1 << 32) - 1;
172 await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);133 await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))
173 });134 .to.be.rejectedWith(/common\.CollectionNotFound/);
174 });135 });
175136
176 it('[refungible] Transfer with not existed collection_id', async function() {137 itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {
177 await requirePallets(this, [Pallets.ReFungible]);
178
179 await usingApi(async (api) => {
180 const reFungibleCollectionCount = await getCreatedCollectionCount(api);138 const collectionId = (1 << 32) - 1;
181 await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);139 await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
182 });140 .to.be.rejectedWith(/common\.CollectionNotFound/);
183 });141 });
184142
185 it('[nft] Transfer with deleted collection_id', async () => {143 itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {
186 const nftCollectionId = await createCollectionExpectSuccess();144 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});
187 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');145 const nft = await collection.mintToken(alice);
146
188 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);147 await nft.burn(alice);
189 await destroyCollectionExpectSuccess(nftCollectionId);148 await collection.burn(alice);
149
190 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);150 await expect(nft.transfer(alice, {Substrate: bob.address}))
151 .to.be.rejectedWith(/common\.CollectionNotFound/);
191 });152 });
192153
193 it('[fungible] Transfer with deleted collection_id', async () => {154 itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {
194 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});155 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});
195 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');156 await collection.mint(alice, 10n);
157
196 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);158 await collection.burnTokens(alice, 10n);
197 await destroyCollectionExpectSuccess(fungibleCollectionId);159 await collection.burn(alice);
160
198 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);161 await expect(collection.transfer(alice, {Substrate: bob.address}))
162 .to.be.rejectedWith(/common\.CollectionNotFound/);
199 });163 });
164
165 itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {
166 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});
167 const rft = await collection.mintToken(alice, 10n);
200168
201 it('[refungible] Transfer with deleted collection_id', async function() {169 await rft.burn(alice, 10n);
202 await requirePallets(this, [Pallets.ReFungible]);170 await collection.burn(alice);
203171
204 const reFungibleCollectionId = await172 await expect(rft.transfer(alice, {Substrate: bob.address}))
205 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
206 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
207 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);173 .to.be.rejectedWith(/common\.CollectionNotFound/);
208 await destroyCollectionExpectSuccess(reFungibleCollectionId);
209 await transferExpectFailure(
210 reFungibleCollectionId,
211 newReFungibleTokenId,
212 alice,
213 bob,
214 1,
215 );
216 });174 });
217175
218 it('[nft] Transfer with not existed item_id', async () => {176 itSub('[nft] Transfer with not existed item_id', async ({helper}) => {
219 const nftCollectionId = await createCollectionExpectSuccess();177 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});
220 await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);178 await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
179 .to.be.rejectedWith(/common\.TokenNotFound/);
221 });180 });
222181
223 it('[fungible] Transfer with not existed item_id', async () => {182 itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {
224 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});183 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});
225 await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);184 await expect(collection.transfer(alice, {Substrate: bob.address}))
185 .to.be.rejectedWith(/common\.TokenValueTooLow/);
226 });186 });
227187
228 it('[refungible] Transfer with not existed item_id', async function() {188 itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {
229 await requirePallets(this, [Pallets.ReFungible]);189 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});
230
231 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
232 await transferExpectFailure(190 await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
233 reFungibleCollectionId,
234 2,
235 alice,
236 bob,
237 1,191 .to.be.rejectedWith(/common\.TokenValueTooLow/);
238 );
239 });192 });
240193
241 it('[nft] Transfer with deleted item_id', async () => {194 itSub('[nft] Transfer with deleted item_id', async ({helper}) => {
242 const nftCollectionId = await createCollectionExpectSuccess();195 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});
243 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');196 const nft = await collection.mintToken(alice);
197
244 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);198 await nft.burn(alice);
199
245 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);200 await expect(nft.transfer(alice, {Substrate: bob.address}))
201 .to.be.rejectedWith(/common\.TokenNotFound/);
246 });202 });
247203
248 it('[fungible] Transfer with deleted item_id', async () => {204 itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {
249 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});205 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});
250 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');206 await collection.mint(alice, 10n);
207
251 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);208 await collection.burnTokens(alice, 10n);
209
252 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);210 await expect(collection.transfer(alice, {Substrate: bob.address}))
211 .to.be.rejectedWith(/common\.TokenValueTooLow/);
253 });212 });
254213
255 it('[refungible] Transfer with deleted item_id', async function() {214 itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {
256 await requirePallets(this, [Pallets.ReFungible]);215 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});
216 const rft = await collection.mintToken(alice, 10n);
257217
258 const reFungibleCollectionId = await218 await rft.burn(alice, 10n);
259 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});219
260 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
261 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
262 await transferExpectFailure(220 await expect(rft.transfer(alice, {Substrate: bob.address}))
263 reFungibleCollectionId,
264 newReFungibleTokenId,
265 alice,
266 bob,
267 1,221 .to.be.rejectedWith(/common\.TokenValueTooLow/);
268 );
269 });222 });
270223
271 it('[nft] Transfer with recipient that is not owner', async () => {224 itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {
272 const nftCollectionId = await createCollectionExpectSuccess();225 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});
273 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');226 const nft = await collection.mintToken(alice);
227
274 await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);228 await expect(nft.transfer(bob, {Substrate: bob.address}))
229 .to.be.rejectedWith(/common\.NoPermission/);
230 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
275 });231 });
276232
277 it('[fungible] Transfer with recipient that is not owner', async () => {233 itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {
278 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});234 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});
279 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');235 await collection.mint(alice, 10n);
236
237 await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))
238 .to.be.rejectedWith(/common\.TokenValueTooLow/);
280 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);239 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
240 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);
281 });241 });
282242
283 it('[refungible] Transfer with recipient that is not owner', async function() {243 itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {
284 await requirePallets(this, [Pallets.ReFungible]);244 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
245 const rft = await collection.mintToken(alice, 10n);
285246
286 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});247 await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))
287 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');248 .to.be.rejectedWith(/common\.TokenValueTooLow/);
288 await transferExpectFailure(249 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);
289 reFungibleCollectionId,
290 newReFungibleTokenId,
291 charlie,
292 bob,
293 1,250 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);
294 );
295 });251 });
296});252});
297253
298describe('Zero value transfer(From)', () => {254describe('Transfers to self (potentially over substrate-evm boundary)', () => {
299 before(async () => {255 let donor: IKeyringPair;
256
257 before(async function() {
300 await usingApi(async (api, privateKeyWrapper) => {258 await usingEthPlaygrounds(async (_, privateKey) => {
301 alice = privateKeyWrapper('//Alice');259 donor = privateKey('//Alice');
302 bob = privateKeyWrapper('//Bob');
303 });260 });
304 });261 });
262
263 itEth('Transfers to self. In case of same frontend', async ({helper}) => {
264 const [owner] = await helper.arrange.createAccounts([10n], donor);
265 const collection = await helper.ft.mintCollection(owner, {});
266 await collection.mint(owner, 100n);
305267
306 it('NFT', async () => {268 const ownerProxy = helper.address.substrateToEth(owner.address);
307 await usingApi(async (api: ApiPromise) => {
308 const nftCollectionId = await createCollectionExpectSuccess();
309 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
310269
311 const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);270 // transfer to own proxy
271 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
312 await submitTransactionAsync(alice, transferTx);272 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
313 const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));273 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
314274
315 expect(toSubstrateAddress(address)).to.be.equal(alice.address);275 // transfer-from own proxy to own proxy again
276 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);
277 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
316 });278 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
317 });279 });
318280
319 it('RFT', async function() {281 itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {
320 await requirePallets(this, [Pallets.ReFungible]);282 const [owner] = await helper.arrange.createAccounts([10n], donor);
283 const collection = await helper.ft.mintCollection(owner, {});
284 await collection.mint(owner, 100n);
321285
322 await usingApi(async (api: ApiPromise) => {286 const ownerProxy = helper.address.substrateToEth(owner.address);
323 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
324 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
325 const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);
326 const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);
327287
328 const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);288 // transfer to own proxy
289 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
329 await submitTransactionAsync(alice, transferTx);290 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
291 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
330292
331 const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);293 // transfer-from own proxy to self
332 const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);294 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);
333
334 expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);295 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);
335 expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);296 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);
336 });
337 });297 });
338298
339 it('Fungible', async () => {299 itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {
340 await usingApi(async (api: ApiPromise) => {
341 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});300 const [owner] = await helper.arrange.createAccounts([10n], donor);
342 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');301 const collection = await helper.ft.mintCollection(owner, {});
343 const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);302 await collection.mint(owner, 100n);
344 const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);
345303
346 const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);304 // transfer to self again
305 await collection.transfer(owner, {Substrate: owner.address}, 10n);
347 await submitTransactionAsync(alice, transferTx);306 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
348307
349 const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);308 // transfer-from self to self again
350 const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);309 await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);
351
352 expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);310 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
353 expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);
354 });
355 });311 });
356});
357312
358describe('Transfers to self (potentially over substrate-evm boundary)', () => {313 itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {
359 itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {
360 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});314 const [owner] = await helper.arrange.createAccounts([10n], donor);
361 const aliceProxy = subToEth(alice.address);
362 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
363 await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');
364 const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);315 const collection = await helper.ft.mintCollection(owner, {});
365 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');316 await collection.mint(owner, 10n);
366 const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);
367 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
368 });
369317
370 itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {318 // transfer to self again
371 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});319 await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))
372 const aliceProxy = subToEth(alice.address);
373 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
374 const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
375 await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');
376 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');
377 const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
378 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
379 });
380
381 itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {
382 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
383 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
384 const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
385 await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');320 .to.be.rejectedWith(/common\.TokenValueTooLow/);
386 await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');
387 const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
388 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
389 });
390321
391 itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {322 // transfer-from self to self again
392 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});323 await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))
393 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
394 const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
395 await transferExpectFailure(collectionId, tokenId, alice, alice , 11);324 .to.be.rejectedWith(/common\.TokenValueTooLow/);
396 await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);
397 const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);325 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);
398 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
399 });326 });
400});327});
401328
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import chai from 'chai';18import {itSub, Pallets, usingPlaygrounds, expect} from './util/playgrounds';
20import chaiAsPromised from 'chai-as-promised';
21import {default as usingApi} from './substrate/substrate-api';
22import {
23 approveExpectFail,
24 approveExpectSuccess,
25 createCollectionExpectSuccess,
26 createFungibleItemExpectSuccess,
27 createItemExpectSuccess,
28 getAllowance,
29 transferFromExpectFail,
30 transferFromExpectSuccess,
31 burnItemExpectSuccess,
32 setCollectionLimitsExpectSuccess,
33 getCreatedCollectionCount,
34 requirePallets,
35 Pallets,
36} from './util/helpers';
3719
38chai.use(chaiAsPromised);
39const expect = chai.expect;
40
41describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {20describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
42 let alice: IKeyringPair;21 let alice: IKeyringPair;
43 let bob: IKeyringPair;22 let bob: IKeyringPair;
44 let charlie: IKeyringPair;23 let charlie: IKeyringPair;
4524
46 before(async () => {25 before(async () => {
47 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
48 alice = privateKeyWrapper('//Alice');27 const donor = privateKey('//Alice');
49 bob = privateKeyWrapper('//Bob');28 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
50 charlie = privateKeyWrapper('//Charlie');
51 });29 });
52 });30 });
5331
54 it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {32 itSub('[nft] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
55 const nftCollectionId = await createCollectionExpectSuccess();33 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-1', description: '', tokenPrefix: 'TF'});
56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');34 const nft = await collection.mintToken(alice);
35 await nft.approve(alice, {Substrate: bob.address});
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);36 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
5837
59 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');38 await nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address});
39 expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
60 });40 });
6141
62 it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {42 itSub('[fungible] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
63 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});43 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-2', description: '', tokenPrefix: 'TF'});
64 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');44 await collection.mint(alice, 10n);
45 await collection.approveTokens(alice, {Substrate: bob.address}, 7n);
65 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);46 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
66 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');47
48 await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
49 expect(await collection.getBalance({Substrate: charlie.address})).to.be.equal(6n);
50 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(4n);
51 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
67 });52 });
6853
69 it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {54 itSub.ifWithPallets('[refungible] Execute the extrinsic and check nftItemList - owner of token', [Pallets.ReFungible], async ({helper}) => {
70 await requirePallets(this, [Pallets.ReFungible]);55 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-3', description: '', tokenPrefix: 'TF'});
71
72 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
73 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');56 const rft = await collection.mintToken(alice, 10n);
74 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);57 await rft.approve(alice, {Substrate: bob.address}, 7n);
75 await transferFromExpectSuccess(58 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
76 reFungibleCollectionId,
77 newReFungibleTokenId,59
78 bob,60 await rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
79 alice,
80 charlie,61 expect(await rft.getBalance({Substrate: charlie.address})).to.be.equal(6n);
81 100,62 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(4n);
82 'ReFungible',63 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
83 );
84 });64 });
8565
86 it('Should reduce allowance if value is big', async () => {66 itSub('Should reduce allowance if value is big', async ({helper}) => {
87 await usingApi(async (api, privateKeyWrapper) => {67 // fungible
88 const alice = privateKeyWrapper('//Alice');68 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-4', description: '', tokenPrefix: 'TF'});
89 const bob = privateKeyWrapper('//Bob');
90 const charlie = privateKeyWrapper('//Charlie');69 await collection.mint(alice, 500000n);
9170
92 // fungible71 await collection.approveTokens(alice, {Substrate: bob.address}, 500000n);
93 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
94 const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 500000n});72 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(500000n);
95
96 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 500000n);
97 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');73 await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 500000n);
98 expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, newFungibleTokenId)).to.equal(0n);74 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(0n);
99 });
100 });75 });
10176
102 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {77 itSub('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async ({helper}) => {
103 const collectionId = await createCollectionExpectSuccess();78 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-5', description: '', tokenPrefix: 'TF'});
104 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
105 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);79 await collection.setLimits(alice, {ownerCanTransfer: true});
10680
107 await transferFromExpectSuccess(collectionId, itemId, alice, bob, charlie);81 const nft = await collection.mintToken(alice, {Substrate: bob.address});
82 await nft.transferFrom(alice, {Substrate: bob.address}, {Substrate: charlie.address});
83 expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
108 });84 });
109});85});
11086
114 let charlie: IKeyringPair;90 let charlie: IKeyringPair;
11591
116 before(async () => {92 before(async () => {
117 await usingApi(async (api, privateKeyWrapper) => {93 await usingPlaygrounds(async (helper, privateKey) => {
118 alice = privateKeyWrapper('//Alice');94 const donor = privateKey('//Alice');
119 bob = privateKeyWrapper('//Bob');95 [alice, bob, charlie] = await helper.arrange.createAccounts([50n, 10n, 10n], donor);
120 charlie = privateKeyWrapper('//Charlie');
121 });96 });
122 });97 });
12398
124 it('[nft] transferFrom for a collection that does not exist', async () => {99 itSub('transferFrom for a collection that does not exist', async ({helper}) => {
125 await usingApi(async (api: ApiPromise) => {100 const collectionId = (1 << 32) - 1;
126 const nftCollectionCount = await getCreatedCollectionCount(api);101 await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
127 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);102 .to.be.rejectedWith(/common\.CollectionNotFound/);
128
129 await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);103 await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
130 });104 .to.be.rejectedWith(/common\.CollectionNotFound/);
131 });105 });
132106
133 it('[fungible] transferFrom for a collection that does not exist', async () => {107 /* itSub('transferFrom for a collection that was destroyed', async ({helper}) => {
134 await usingApi(async (api: ApiPromise) => {
135 const fungibleCollectionCount = await getCreatedCollectionCount(api);108 this test copies approve negative test
136 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);109 }); */
137110
138 await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);111 /* itSub('transferFrom a token that does not exist', async ({helper}) => {
112 this test copies approve negative test
113 }); */
114
115 /* itSub('transferFrom a token that was deleted', async ({helper}) => {
116 this test copies approve negative test
117 }); */
118
119 itSub('[nft] transferFrom for not approved address', async ({helper}) => {
120 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
121 const nft = await collection.mintToken(alice);
122
123 await expect(nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
124 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
139 });125 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
140 });126 });
141127
142 it('[refungible] transferFrom for a collection that does not exist', async function() {128 itSub('[fungible] transferFrom for not approved address', async ({helper}) => {
143 await requirePallets(this, [Pallets.ReFungible]);129 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
130 await collection.mint(alice, 10n);
144131
145 await usingApi(async (api: ApiPromise) => {132 await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
146 const reFungibleCollectionCount = await getCreatedCollectionCount(api);133 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
134 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
147 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);135 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
136 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
137 });
148138
149 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);139 itSub.ifWithPallets('[refungible] transferFrom for not approved address', [Pallets.ReFungible], async({helper}) => {
140 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-3', description: '', tokenPrefix: 'TF'});
141 const rft = await collection.mintToken(alice, 10n);
142
143 await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
144 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
150 });145 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
146 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
147 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
151 });148 });
152149
153 /* it('transferFrom for a collection that was destroyed', async () => {150 itSub('[nft] transferFrom incorrect token count', async ({helper}) => {
154 await usingApi(async (api: ApiPromise) => {151 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-4', description: '', tokenPrefix: 'TF'});
155 this test copies approve negative test152 const nft = await collection.mintToken(alice);
156 });
157 }); */
158153
159 /* it('transferFrom a token that does not exist', async () => {154 await nft.approve(alice, {Substrate: bob.address});
160 await usingApi(async (api: ApiPromise) => {155 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
161 this test copies approve negative test
162 });
163 }); */
164156
165 /* it('transferFrom a token that was deleted', async () => {157 await expect(helper.collection.transferTokenFrom(
158 bob,
159 collection.collectionId,
166 await usingApi(async (api: ApiPromise) => {160 nft.tokenId,
161 {Substrate: alice.address},
167 this test copies approve negative test162 {Substrate: charlie.address},
163 2n,
168 });164 )).to.be.rejectedWith(/nonfungible\.NonfungibleItemsHaveNoAmount/);
165 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
169 }); */166 });
170167
171 it('[nft] transferFrom for not approved address', async () => {168 itSub('[fungible] transferFrom incorrect token count', async ({helper}) => {
172 const nftCollectionId = await createCollectionExpectSuccess();169 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-5', description: '', tokenPrefix: 'TF'});
173 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');170 await collection.mint(alice, 10n);
174171
175 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);172 await collection.approveTokens(alice, {Substrate: bob.address}, 2n);
173 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(2n);
174
175 await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
176 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
177 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
178 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
179 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
176 });180 });
177181
178 it('[fungible] transferFrom for not approved address', async () => {182 itSub.ifWithPallets('[refungible] transferFrom incorrect token count', [Pallets.ReFungible], async ({helper}) => {
179 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});183 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-6', description: '', tokenPrefix: 'TF'});
180 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');184 const rft = await collection.mintToken(alice, 10n);
185
186 await rft.approve(alice, {Substrate: bob.address}, 5n);
181 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);187 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(5n);
188
189 await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 7n))
190 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
191 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
192 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
193 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
182 });194 });
183195
184 it('[refungible] transferFrom for not approved address', async function() {196 itSub('[nft] execute transferFrom from account that is not owner of collection', async ({helper}) => {
185 await requirePallets(this, [Pallets.ReFungible]);197 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-7', description: '', tokenPrefix: 'TF'});
198 const nft = await collection.mintToken(alice);
186199
187 const reFungibleCollectionId = await200 await expect(nft.approve(charlie, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
188 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
189 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');201 expect(await nft.isApproved({Substrate: bob.address})).to.be.false;
202
190 await transferFromExpectFail(203 await expect(nft.transferFrom(
191 reFungibleCollectionId,
192 newReFungibleTokenId,
193 bob,
194 alice,
195 charlie,204 charlie,
196 1,205 {Substrate: alice.address},
197 );206 {Substrate: charlie.address},
207 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
208 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
198 });209 });
199210
200 it('[nft] transferFrom incorrect token count', async () => {211 itSub('[fungible] execute transferFrom from account that is not owner of collection', async ({helper}) => {
201 const nftCollectionId = await createCollectionExpectSuccess();212 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-8', description: '', tokenPrefix: 'TF'});
202 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
203 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);213 await collection.mint(alice, 10000n);
204214
205 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);215 await expect(collection.approveTokens(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
216 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
206 });217 expect(await collection.getApprovedTokens({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
207218
208 it('[fungible] transferFrom incorrect token count', async () => {219 await expect(collection.transferFrom(
220 charlie,
209 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});221 {Substrate: alice.address},
222 {Substrate: charlie.address},
223 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
210 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');224 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
211 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);225 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
212 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);226 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
213 });227 });
214228
215 it('[refungible] transferFrom incorrect token count', async function() {229 itSub.ifWithPallets('[refungible] execute transferFrom from account that is not owner of collection', [Pallets.ReFungible], async ({helper}) => {
216 await requirePallets(this, [Pallets.ReFungible]);230 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-9', description: '', tokenPrefix: 'TF'});
231 const rft = await collection.mintToken(alice, 10000n);
217232
218 const reFungibleCollectionId = await233 await expect(rft.approve(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
219 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
220 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');234 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
221 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);235 expect(await rft.getApprovedPieces({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
236
222 await transferFromExpectFail(237 await expect(rft.transferFrom(
223 reFungibleCollectionId,
224 newReFungibleTokenId,
225 bob,
226 alice,
227 charlie,238 charlie,
228 2,239 {Substrate: alice.address},
229 );240 {Substrate: charlie.address},
241 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
242 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
243 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
244 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
230 });245 });
231246
232 it('[nft] execute transferFrom from account that is not owner of collection', async () => {247 itSub('transferFrom burnt token before approve NFT', async ({helper}) => {
233 await usingApi(async (api, privateKeyWrapper) => {
234 const dave = privateKeyWrapper('//Dave');248 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-10', description: '', tokenPrefix: 'TF'});
235 const nftCollectionId = await createCollectionExpectSuccess();
236 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
237 try {
238 await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
239 await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);249 await collection.setLimits(alice, {ownerCanTransfer: true});
240 } catch (e) {250 const nft = await collection.mintToken(alice);
241 // tslint:disable-next-line:no-unused-expression
242 expect(e).to.be.exist;
243 }
244251
245 // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);252 await nft.burn(alice);
253 await expect(nft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.TokenNotFound/);
254
255 await expect(nft.transferFrom(
256 bob,
257 {Substrate: alice.address},
246 });258 {Substrate: charlie.address},
259 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
247 });260 });
248261
249 it('[fungible] execute transferFrom from account that is not owner of collection', async () => {262 itSub('transferFrom burnt token before approve Fungible', async ({helper}) => {
250 await usingApi(async (api, privateKeyWrapper) => {263 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-11', description: '', tokenPrefix: 'TF'});
251 const dave = privateKeyWrapper('//Dave');264 await collection.setLimits(alice, {ownerCanTransfer: true});
265 await collection.mint(alice, 10n);
252266
253 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});267 await collection.burnTokens(alice, 10n);
254 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');268 await expect(collection.approveTokens(alice, {Substrate: bob.address})).to.be.not.rejected;
255 try {269
256 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, dave, bob);270 await expect(collection.transferFrom(
257 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, dave, alice, charlie, 1);271 alice,
258 } catch (e) {272 {Substrate: alice.address},
259 // tslint:disable-next-line:no-unused-expression273 {Substrate: charlie.address},
260 expect(e).to.be.exist;274 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
261 }
262 });
263 });275 });
264276
265 it('[refungible] execute transferFrom from account that is not owner of collection', async function() {277 itSub.ifWithPallets('transferFrom burnt token before approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
278 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-12', description: '', tokenPrefix: 'TF'});
279 await collection.setLimits(alice, {ownerCanTransfer: true});
266 await requirePallets(this, [Pallets.ReFungible]);280 const rft = await collection.mintToken(alice, 10n);
267281
268 await usingApi(async (api, privateKeyWrapper) => {282 await rft.burn(alice, 10n);
269 const dave = privateKeyWrapper('//Dave');
270 const reFungibleCollectionId = await283 await expect(rft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
271 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
272 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
273 try {
274 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
275 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
276 } catch (e) {
277 // tslint:disable-next-line:no-unused-expression
278 expect(e).to.be.exist;
279 }
280 });
281 });
282 it('transferFrom burnt token before approve NFT', async () => {
283 await usingApi(async () => {
284 // nft
285 const nftCollectionId = await createCollectionExpectSuccess();
286 await setCollectionLimitsExpectSuccess(alice, nftCollectionId, {ownerCanTransfer: true});
287 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
288 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
289 await approveExpectFail(nftCollectionId, newNftTokenId, alice, bob);
290 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
291 });
292 });
293 it('transferFrom burnt token before approve Fungible', async () => {
294 await usingApi(async () => {
295 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
296 await setCollectionLimitsExpectSuccess(alice, fungibleCollectionId, {ownerCanTransfer: true});
297 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
298 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
299 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
300 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
301284
302 });285 await expect(rft.transferFrom(
286 alice,
287 {Substrate: alice.address},
288 {Substrate: charlie.address},
289 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
303 });290 });
304 it('transferFrom burnt token before approve ReFungible', async function() {
305 await requirePallets(this, [Pallets.ReFungible]);
306291
307 await usingApi(async () => {292 itSub('transferFrom burnt token after approve NFT', async ({helper}) => {
308 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});293 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-13', description: '', tokenPrefix: 'TF'});
309 await setCollectionLimitsExpectSuccess(alice, reFungibleCollectionId, {ownerCanTransfer: true});
310 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');294 const nft = await collection.mintToken(alice);
311 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
312 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, alice, bob);
313 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
314295
315 });296 await nft.approve(alice, {Substrate: bob.address});
316 });297 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
317298
318 it('transferFrom burnt token after approve NFT', async () => {299 await nft.burn(alice);
319 await usingApi(async () => {300
320 // nft
321 const nftCollectionId = await createCollectionExpectSuccess();301 await expect(nft.transferFrom(
322 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');302 bob,
323 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);303 {Substrate: alice.address},
324 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
325 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);304 {Substrate: charlie.address},
326 });305 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
327 });306 });
328 it('transferFrom burnt token after approve Fungible', async () => {
329 await usingApi(async () => {
330 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
331 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
332 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
333 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
334 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
335307
336 });308 itSub('transferFrom burnt token after approve Fungible', async ({helper}) => {
309 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-14', description: '', tokenPrefix: 'TF'});
310 await collection.mint(alice, 10n);
311
312 await collection.approveTokens(alice, {Substrate: bob.address});
313 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(1n);
314
315 await collection.burnTokens(alice, 10n);
316
317 await expect(collection.transferFrom(
318 bob,
319 {Substrate: alice.address},
320 {Substrate: charlie.address},
321 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
337 });322 });
338 it('transferFrom burnt token after approve ReFungible', async function() {
339 await requirePallets(this, [Pallets.ReFungible]);
340323
341 await usingApi(async () => {324 itSub.ifWithPallets('transferFrom burnt token after approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
342 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});325 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-15', description: '', tokenPrefix: 'TF'});
343 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
344 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
345 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);326 const rft = await collection.mintToken(alice, 10n);
346 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
347327
348 });328 await rft.approve(alice, {Substrate: bob.address}, 10n);
329 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(10n);
330
331 await rft.burn(alice, 10n);
332
333 await expect(rft.transferFrom(
334 bob,
335 {Substrate: alice.address},
336 {Substrate: charlie.address},
337 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
349 });338 });
350339
351 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {340 itSub('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
352 const collectionId = await createCollectionExpectSuccess();341 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-16', description: '', tokenPrefix: 'TF'});
353 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
354 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});342 const nft = await collection.mintToken(alice, {Substrate: bob.address});
355343
356 await transferFromExpectFail(collectionId, itemId, alice, bob, charlie);344 await collection.setLimits(alice, {ownerCanTransfer: false});
345
346 await expect(nft.transferFrom(
347 alice,
348 {Substrate: bob.address},
349 {Substrate: charlie.address},
350 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
357 });351 });
358});352});
359353
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
1651 });1651 });
1652}1652}
16531653
1654export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId) {1654export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId | IKeyringPair) {
1655 return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();1655 return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();
1656}1656}
16571657
modifiedtests/src/util/playgrounds/index.tsdiffbeforeafterboth
2// SPDX-License-Identifier: Apache-2.02// SPDX-License-Identifier: Apache-2.0
33
4import {IKeyringPair} from '@polkadot/types/types';4import {IKeyringPair} from '@polkadot/types/types';
5import chai from 'chai';
6import chaiAsPromised from 'chai-as-promised';
5import {Context} from 'mocha';7import {Context} from 'mocha';
6import config from '../../config';8import config from '../../config';
7import '../../interfaces/augment-api-events';9import '../../interfaces/augment-api-events';
8import {DevUniqueHelper, SilentLogger, SilentConsole} from './unique.dev';10import {DevUniqueHelper, SilentLogger, SilentConsole} from './unique.dev';
911
12
13chai.use(chaiAsPromised);
14export const expect = chai.expect;
1015
11export const usingPlaygrounds = async (code: (helper: DevUniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>) => {16export const usingPlaygrounds = async (code: (helper: DevUniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>) => {
12 const silentConsole = new SilentConsole();17 const silentConsole = new SilentConsole();
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
257 }257 }
258258
259 async forParachainBlockNumber(blockNumber: bigint) {259 async forParachainBlockNumber(blockNumber: bigint) {
260 // eslint-disable-next-line no-async-promise-executor
260 return new Promise<void>(async (resolve) => {261 return new Promise<void>(async (resolve) => {
261 const unsubscribe = await this.helper.api!.rpc.chain.subscribeNewHeads(async (data: any) => {262 const unsubscribe = await this.helper.api!.rpc.chain.subscribeNewHeads(async (data: any) => {
262 if (data.number.toNumber() >= blockNumber) {263 if (data.number.toNumber() >= blockNumber) {
268 }269 }
269 270
270 async forRelayBlockNumber(blockNumber: bigint) {271 async forRelayBlockNumber(blockNumber: bigint) {
272 // eslint-disable-next-line no-async-promise-executor
271 return new Promise<void>(async (resolve) => {273 return new Promise<void>(async (resolve) => {
272 const unsubscribe = await this.helper.api!.query.parachainSystem.validationData(async (data: any) => {274 const unsubscribe = await this.helper.api!.query.parachainSystem.validationData(async (data: any) => {
273 if (data.value.relayParentNumber.toNumber() >= blockNumber) {275 if (data.value.relayParentNumber.toNumber() >= blockNumber) {
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');
730 }730 }
731
732 /**
733 * Check if user is in allow list.
734 *
735 * @param collectionId ID of collection
736 * @param user Account to check
737 * @example await getAdmins(1)
738 * @returns is user in allow list
739 */
740 async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {
741 return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();
742 }
731743
732 /**744 /**
733 * Adds an address to allow list745 * Adds an address to allow list
1666 * @example mintTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq"}, 1000n);1678 * @example mintTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq"}, 1000n);
1667 * @returns ```true``` if extrinsic success, otherwise ```false```1679 * @returns ```true``` if extrinsic success, otherwise ```false```
1668 */1680 */
1669 async mintTokens(signer: TSigner, collectionId: number, owner: ICrossAccountId | string, amount: bigint): Promise<boolean> {1681 async mintTokens(signer: TSigner, collectionId: number, amount: bigint, owner: ICrossAccountId | string): Promise<boolean> {
1670 const creationResult = await this.helper.executeExtrinsic(1682 const creationResult = await this.helper.executeExtrinsic(
1671 signer,1683 signer,
1672 'api.tx.unique.createItem', [collectionId, (typeof owner === 'string') ? {Substrate: owner} : owner, {1684 'api.tx.unique.createItem', [collectionId, (typeof owner === 'string') ? {Substrate: owner} : owner, {
1687 * @param tokens array of tokens with properties and pieces1699 * @param tokens array of tokens with properties and pieces
1688 * @returns ```true``` if extrinsic success, otherwise ```false```1700 * @returns ```true``` if extrinsic success, otherwise ```false```
1689 */1701 */
1690 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {value: bigint}[]): Promise<boolean> {1702 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, tokens: {value: bigint}[], owner: ICrossAccountId): Promise<boolean> {
1691 const rawTokens = [];1703 const rawTokens = [];
1692 for (const token of tokens) {1704 for (const token of tokens) {
1693 const raw = {Fungible: {Value: token.value}};1705 const raw = {Fungible: {Value: token.value}};
2116 return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj);2128 return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj);
2117 }2129 }
2118
2119 async enableCertainPermissions(signer: TSigner, accessMode: 'AllowList' | 'Normal' | undefined = 'AllowList', mintMode: boolean | undefined = true) {
2120 return await this.setPermissions(signer, {access: accessMode, mintMode: mintMode});
2121 }
21222130
2123 async addToAllowList(signer: TSigner, addressObj: ICrossAccountId) {2131 async addToAllowList(signer: TSigner, addressObj: ICrossAccountId) {
2124 return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj);2132 return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj);
2203 return await this.helper.nft.isTokenApproved(this.collectionId, tokenId, toAddressObj);2211 return await this.helper.nft.isTokenApproved(this.collectionId, tokenId, toAddressObj);
2204 }2212 }
22052213
2206 async mintToken(signer: TSigner, owner: ICrossAccountId, properties?: IProperty[]) {2214 async mintToken(signer: TSigner, owner: ICrossAccountId = {Substrate: signer.address}, properties?: IProperty[]) {
2207 return await this.helper.nft.mintToken(signer, {collectionId: this.collectionId, owner, properties});2215 return await this.helper.nft.mintToken(signer, {collectionId: this.collectionId, owner, properties});
2208 }2216 }
22092217
2278 return await this.helper.rft.repartitionToken(signer, this.collectionId, tokenId, amount);2286 return await this.helper.rft.repartitionToken(signer, this.collectionId, tokenId, amount);
2279 }2287 }
22802288
2281 async mintToken(signer: TSigner, owner: ICrossAccountId, pieces=100n, properties?: IProperty[]) {2289 async mintToken(signer: TSigner, pieces=1n, owner: ICrossAccountId = {Substrate: signer.address}, properties?: IProperty[]) {
2282 return await this.helper.rft.mintToken(signer, {collectionId: this.collectionId, owner, pieces, properties});2290 return await this.helper.rft.mintToken(signer, {collectionId: this.collectionId, owner, pieces, properties});
2283 }2291 }
22842292
2285 async mintMultipleTokens(signer: TSigner, tokens: {owner: ICrossAccountId, pieces: bigint, properties?: IProperty[]}[]) {2293 async mintMultipleTokens(signer: TSigner, tokens: {pieces: bigint, owner: ICrossAccountId, properties?: IProperty[]}[]) {
2286 return await this.helper.rft.mintMultipleTokens(signer, this.collectionId, tokens);2294 return await this.helper.rft.mintMultipleTokens(signer, this.collectionId, tokens);
2287 }2295 }
22882296
23052313
23062314
2307class UniqueFTCollection extends UniqueCollectionBase {2315class UniqueFTCollection extends UniqueCollectionBase {
2308 async mint(signer: TSigner, owner: ICrossAccountId, amount: bigint) {2316 async mint(signer: TSigner, amount=1n, owner: ICrossAccountId = {Substrate: signer.address}) {
2309 return await this.helper.ft.mintTokens(signer, this.collectionId, owner, amount);2317 return await this.helper.ft.mintTokens(signer, this.collectionId, amount, owner);
2310 }2318 }
23112319
2312 async mintWithOneOwner(signer: TSigner, owner: ICrossAccountId, tokens: {value: bigint}[]) {2320 async mintWithOneOwner(signer: TSigner, tokens: {value: bigint}[], owner: ICrossAccountId = {Substrate: signer.address}) {
2313 return await this.helper.ft.mintMultipleTokensWithOneOwner(signer, this.collectionId, owner, tokens);2321 return await this.helper.ft.mintMultipleTokensWithOneOwner(signer, this.collectionId, tokens, owner);
2314 }2322 }
23152323
2316 async getBalance(addressObj: ICrossAccountId) {2324 async getBalance(addressObj: ICrossAccountId) {
modifiedtests/src/xcmTransfer.test.tsdiffbeforeafterboth
33const KARURA_PORT = '9946';33const KARURA_PORT = '9946';
34const TRANSFER_AMOUNT = 2000000000000000000000000n;34const TRANSFER_AMOUNT = 2000000000000000000000000n;
3535
36// todo:playgrounds refit when XCM drops
36describe.skip('Integration test: Exchanging QTZ with Karura', () => {37describe.skip('Integration test: Exchanging QTZ with Karura', () => {
37 let alice: IKeyringPair;38 let alice: IKeyringPair;
3839
modifiedtests/yarn.lockdiffbeforeafterboth
17 dependencies:17 dependencies:
18 "@babel/highlight" "^7.18.6"18 "@babel/highlight" "^7.18.6"
1919
20"@babel/compat-data@^7.18.8":20"@babel/compat-data@^7.19.0":
21 version "7.18.8"21 version "7.19.0"
22 resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d"22 resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.0.tgz#2a592fd89bacb1fcde68de31bee4f2f2dacb0e86"
23 integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==23 integrity sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==
2424
25"@babel/core@^7.18.10":25"@babel/core@^7.18.10":
26 version "7.18.10"26 version "7.19.0"
27 resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8"27 resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.0.tgz#d2f5f4f2033c00de8096be3c9f45772563e150c3"
28 integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==28 integrity sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==
29 dependencies:29 dependencies:
30 "@ampproject/remapping" "^2.1.0"30 "@ampproject/remapping" "^2.1.0"
31 "@babel/code-frame" "^7.18.6"31 "@babel/code-frame" "^7.18.6"
32 "@babel/generator" "^7.18.10"32 "@babel/generator" "^7.19.0"
33 "@babel/helper-compilation-targets" "^7.18.9"33 "@babel/helper-compilation-targets" "^7.19.0"
34 "@babel/helper-module-transforms" "^7.18.9"34 "@babel/helper-module-transforms" "^7.19.0"
35 "@babel/helpers" "^7.18.9"35 "@babel/helpers" "^7.19.0"
36 "@babel/parser" "^7.18.10"36 "@babel/parser" "^7.19.0"
37 "@babel/template" "^7.18.10"37 "@babel/template" "^7.18.10"
38 "@babel/traverse" "^7.18.10"38 "@babel/traverse" "^7.19.0"
39 "@babel/types" "^7.18.10"39 "@babel/types" "^7.19.0"
40 convert-source-map "^1.7.0"40 convert-source-map "^1.7.0"
41 debug "^4.1.0"41 debug "^4.1.0"
42 gensync "^1.0.0-beta.2"42 gensync "^1.0.0-beta.2"
43 json5 "^2.2.1"43 json5 "^2.2.1"
44 semver "^6.3.0"44 semver "^6.3.0"
4545
46"@babel/generator@^7.18.10":46"@babel/generator@^7.19.0":
47 version "7.18.12"47 version "7.19.0"
48 resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4"48 resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a"
49 integrity sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==49 integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==
50 dependencies:50 dependencies:
51 "@babel/types" "^7.18.10"51 "@babel/types" "^7.19.0"
52 "@jridgewell/gen-mapping" "^0.3.2"52 "@jridgewell/gen-mapping" "^0.3.2"
53 jsesc "^2.5.1"53 jsesc "^2.5.1"
5454
55"@babel/helper-compilation-targets@^7.18.9":55"@babel/helper-compilation-targets@^7.19.0":
56 version "7.18.9"56 version "7.19.0"
57 resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf"57 resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz#537ec8339d53e806ed422f1e06c8f17d55b96bb0"
58 integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==58 integrity sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==
59 dependencies:59 dependencies:
60 "@babel/compat-data" "^7.18.8"60 "@babel/compat-data" "^7.19.0"
61 "@babel/helper-validator-option" "^7.18.6"61 "@babel/helper-validator-option" "^7.18.6"
62 browserslist "^4.20.2"62 browserslist "^4.20.2"
63 semver "^6.3.0"63 semver "^6.3.0"
67 resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"67 resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
68 integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==68 integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
6969
70"@babel/helper-function-name@^7.18.9":70"@babel/helper-function-name@^7.19.0":
71 version "7.18.9"71 version "7.19.0"
72 resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0"72 resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
73 integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==73 integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
74 dependencies:74 dependencies:
75 "@babel/template" "^7.18.6"75 "@babel/template" "^7.18.10"
76 "@babel/types" "^7.18.9"76 "@babel/types" "^7.19.0"
7777
78"@babel/helper-hoist-variables@^7.18.6":78"@babel/helper-hoist-variables@^7.18.6":
79 version "7.18.6"79 version "7.18.6"
89 dependencies:89 dependencies:
90 "@babel/types" "^7.18.6"90 "@babel/types" "^7.18.6"
9191
92"@babel/helper-module-transforms@^7.18.9":92"@babel/helper-module-transforms@^7.19.0":
93 version "7.18.9"93 version "7.19.0"
94 resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712"94 resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
95 integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==95 integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
96 dependencies:96 dependencies:
97 "@babel/helper-environment-visitor" "^7.18.9"97 "@babel/helper-environment-visitor" "^7.18.9"
98 "@babel/helper-module-imports" "^7.18.6"98 "@babel/helper-module-imports" "^7.18.6"
99 "@babel/helper-simple-access" "^7.18.6"99 "@babel/helper-simple-access" "^7.18.6"
100 "@babel/helper-split-export-declaration" "^7.18.6"100 "@babel/helper-split-export-declaration" "^7.18.6"
101 "@babel/helper-validator-identifier" "^7.18.6"101 "@babel/helper-validator-identifier" "^7.18.6"
102 "@babel/template" "^7.18.6"102 "@babel/template" "^7.18.10"
103 "@babel/traverse" "^7.18.9"103 "@babel/traverse" "^7.19.0"
104 "@babel/types" "^7.18.9"104 "@babel/types" "^7.19.0"
105105
106"@babel/helper-simple-access@^7.18.6":106"@babel/helper-simple-access@^7.18.6":
107 version "7.18.6"107 version "7.18.6"
132 resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"132 resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
133 integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==133 integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
134134
135"@babel/helpers@^7.18.9":135"@babel/helpers@^7.19.0":
136 version "7.18.9"136 version "7.19.0"
137 resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9"137 resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18"
138 integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==138 integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==
139 dependencies:139 dependencies:
140 "@babel/template" "^7.18.6"140 "@babel/template" "^7.18.10"
141 "@babel/traverse" "^7.18.9"141 "@babel/traverse" "^7.19.0"
142 "@babel/types" "^7.18.9"142 "@babel/types" "^7.19.0"
143143
144"@babel/highlight@^7.18.6":144"@babel/highlight@^7.18.6":
145 version "7.18.6"145 version "7.18.6"
150 chalk "^2.0.0"150 chalk "^2.0.0"
151 js-tokens "^4.0.0"151 js-tokens "^4.0.0"
152152
153"@babel/parser@^7.18.10", "@babel/parser@^7.18.11":153"@babel/parser@^7.18.10", "@babel/parser@^7.19.0":
154 version "7.18.11"154 version "7.19.0"
155 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9"155 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c"
156 integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==156 integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==
157157
158"@babel/register@^7.18.9":158"@babel/register@^7.18.9":
159 version "7.18.9"159 version "7.18.9"
167 source-map-support "^0.5.16"167 source-map-support "^0.5.16"
168168
169"@babel/runtime@^7.18.9":169"@babel/runtime@^7.18.9":
170 version "7.18.9"170 version "7.19.0"
171 resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"171 resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259"
172 integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==172 integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
173 dependencies:173 dependencies:
174 regenerator-runtime "^0.13.4"174 regenerator-runtime "^0.13.4"
175175
176"@babel/template@^7.18.10", "@babel/template@^7.18.6":176"@babel/template@^7.18.10":
177 version "7.18.10"177 version "7.18.10"
178 resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"178 resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
179 integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==179 integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
182 "@babel/parser" "^7.18.10"182 "@babel/parser" "^7.18.10"
183 "@babel/types" "^7.18.10"183 "@babel/types" "^7.18.10"
184184
185"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9":185"@babel/traverse@^7.19.0":
186 version "7.18.11"186 version "7.19.0"
187 resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f"187 resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.0.tgz#eb9c561c7360005c592cc645abafe0c3c4548eed"
188 integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==188 integrity sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==
189 dependencies:189 dependencies:
190 "@babel/code-frame" "^7.18.6"190 "@babel/code-frame" "^7.18.6"
191 "@babel/generator" "^7.18.10"191 "@babel/generator" "^7.19.0"
192 "@babel/helper-environment-visitor" "^7.18.9"192 "@babel/helper-environment-visitor" "^7.18.9"
193 "@babel/helper-function-name" "^7.18.9"193 "@babel/helper-function-name" "^7.19.0"
194 "@babel/helper-hoist-variables" "^7.18.6"194 "@babel/helper-hoist-variables" "^7.18.6"
195 "@babel/helper-split-export-declaration" "^7.18.6"195 "@babel/helper-split-export-declaration" "^7.18.6"
196 "@babel/parser" "^7.18.11"196 "@babel/parser" "^7.19.0"
197 "@babel/types" "^7.18.10"197 "@babel/types" "^7.19.0"
198 debug "^4.1.0"198 debug "^4.1.0"
199 globals "^11.1.0"199 globals "^11.1.0"
200200
201"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9":201"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0":
202 version "7.18.10"202 version "7.19.0"
203 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6"203 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600"
204 integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==204 integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==
205 dependencies:205 dependencies:
206 "@babel/helper-string-parser" "^7.18.10"206 "@babel/helper-string-parser" "^7.18.10"
207 "@babel/helper-validator-identifier" "^7.18.6"207 "@babel/helper-validator-identifier" "^7.18.6"
214 dependencies:214 dependencies:
215 "@jridgewell/trace-mapping" "0.3.9"215 "@jridgewell/trace-mapping" "0.3.9"
216216
217"@eslint/eslintrc@^1.3.0":217"@eslint/eslintrc@^1.3.1":
218 version "1.3.0"218 version "1.3.1"
219 resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f"219 resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d"
220 integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==220 integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==
221 dependencies:221 dependencies:
222 ajv "^6.12.4"222 ajv "^6.12.4"
223 debug "^4.3.2"223 debug "^4.3.2"
224 espree "^9.3.2"224 espree "^9.4.0"
225 globals "^13.15.0"225 globals "^13.15.0"
226 ignore "^5.2.0"226 ignore "^5.2.0"
227 import-fresh "^3.2.1"227 import-fresh "^3.2.1"
246 ethereumjs-util "^7.1.5"246 ethereumjs-util "^7.1.5"
247247
248"@ethersproject/abi@^5.6.3":248"@ethersproject/abi@^5.6.3":
249 version "5.6.4"249 version "5.7.0"
250 resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362"250 resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449"
251 integrity sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg==251 integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==
252 dependencies:252 dependencies:
253 "@ethersproject/address" "^5.6.1"253 "@ethersproject/address" "^5.7.0"
254 "@ethersproject/bignumber" "^5.6.2"254 "@ethersproject/bignumber" "^5.7.0"
255 "@ethersproject/bytes" "^5.6.1"255 "@ethersproject/bytes" "^5.7.0"
256 "@ethersproject/constants" "^5.6.1"256 "@ethersproject/constants" "^5.7.0"
257 "@ethersproject/hash" "^5.6.1"257 "@ethersproject/hash" "^5.7.0"
258 "@ethersproject/keccak256" "^5.6.1"258 "@ethersproject/keccak256" "^5.7.0"
259 "@ethersproject/logger" "^5.6.0"259 "@ethersproject/logger" "^5.7.0"
260 "@ethersproject/properties" "^5.6.0"260 "@ethersproject/properties" "^5.7.0"
261 "@ethersproject/strings" "^5.6.1"261 "@ethersproject/strings" "^5.7.0"
262262
263"@ethersproject/abstract-provider@^5.6.1":263"@ethersproject/abstract-provider@^5.7.0":
264 version "5.6.1"264 version "5.7.0"
265 resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz#02ddce150785caf0c77fe036a0ebfcee61878c59"265 resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef"
266 integrity sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==266 integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==
267 dependencies:267 dependencies:
268 "@ethersproject/bignumber" "^5.6.2"268 "@ethersproject/bignumber" "^5.7.0"
269 "@ethersproject/bytes" "^5.6.1"269 "@ethersproject/bytes" "^5.7.0"
270 "@ethersproject/logger" "^5.6.0"270 "@ethersproject/logger" "^5.7.0"
271 "@ethersproject/networks" "^5.6.3"271 "@ethersproject/networks" "^5.7.0"
272 "@ethersproject/properties" "^5.6.0"272 "@ethersproject/properties" "^5.7.0"
273 "@ethersproject/transactions" "^5.6.2"273 "@ethersproject/transactions" "^5.7.0"
274 "@ethersproject/web" "^5.6.1"274 "@ethersproject/web" "^5.7.0"
275275
276"@ethersproject/abstract-signer@^5.6.2":276"@ethersproject/abstract-signer@^5.7.0":
277 version "5.6.2"277 version "5.7.0"
278 resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz#491f07fc2cbd5da258f46ec539664713950b0b33"278 resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2"
279 integrity sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==279 integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==
280 dependencies:280 dependencies:
281 "@ethersproject/abstract-provider" "^5.6.1"281 "@ethersproject/abstract-provider" "^5.7.0"
282 "@ethersproject/bignumber" "^5.6.2"282 "@ethersproject/bignumber" "^5.7.0"
283 "@ethersproject/bytes" "^5.6.1"283 "@ethersproject/bytes" "^5.7.0"
284 "@ethersproject/logger" "^5.6.0"284 "@ethersproject/logger" "^5.7.0"
285 "@ethersproject/properties" "^5.6.0"285 "@ethersproject/properties" "^5.7.0"
286286
287"@ethersproject/address@^5.6.1":287"@ethersproject/address@^5.7.0":
288 version "5.6.1"288 version "5.7.0"
289 resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.1.tgz#ab57818d9aefee919c5721d28cd31fd95eff413d"289 resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37"
290 integrity sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==290 integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==
291 dependencies:291 dependencies:
292 "@ethersproject/bignumber" "^5.6.2"292 "@ethersproject/bignumber" "^5.7.0"
293 "@ethersproject/bytes" "^5.6.1"293 "@ethersproject/bytes" "^5.7.0"
294 "@ethersproject/keccak256" "^5.6.1"294 "@ethersproject/keccak256" "^5.7.0"
295 "@ethersproject/logger" "^5.6.0"295 "@ethersproject/logger" "^5.7.0"
296 "@ethersproject/rlp" "^5.6.1"296 "@ethersproject/rlp" "^5.7.0"
297297
298"@ethersproject/base64@^5.6.1":298"@ethersproject/base64@^5.7.0":
299 version "5.6.1"299 version "5.7.0"
300 resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.1.tgz#2c40d8a0310c9d1606c2c37ae3092634b41d87cb"300 resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c"
301 integrity sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==301 integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==
302 dependencies:302 dependencies:
303 "@ethersproject/bytes" "^5.6.1"303 "@ethersproject/bytes" "^5.7.0"
304304
305"@ethersproject/bignumber@^5.6.2":305"@ethersproject/bignumber@^5.7.0":
306 version "5.6.2"306 version "5.7.0"
307 resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.2.tgz#72a0717d6163fab44c47bcc82e0c550ac0315d66"307 resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2"
308 integrity sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==308 integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==
309 dependencies:309 dependencies:
310 "@ethersproject/bytes" "^5.6.1"310 "@ethersproject/bytes" "^5.7.0"
311 "@ethersproject/logger" "^5.6.0"311 "@ethersproject/logger" "^5.7.0"
312 bn.js "^5.2.1"312 bn.js "^5.2.1"
313313
314"@ethersproject/bytes@^5.6.1":314"@ethersproject/bytes@^5.7.0":
315 version "5.6.1"315 version "5.7.0"
316 resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7"316 resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d"
317 integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==317 integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==
318 dependencies:318 dependencies:
319 "@ethersproject/logger" "^5.6.0"319 "@ethersproject/logger" "^5.7.0"
320320
321"@ethersproject/constants@^5.6.1":321"@ethersproject/constants@^5.7.0":
322 version "5.6.1"322 version "5.7.0"
323 resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.1.tgz#e2e974cac160dd101cf79fdf879d7d18e8cb1370"323 resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e"
324 integrity sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==324 integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==
325 dependencies:325 dependencies:
326 "@ethersproject/bignumber" "^5.6.2"326 "@ethersproject/bignumber" "^5.7.0"
327327
328"@ethersproject/hash@^5.6.1":328"@ethersproject/hash@^5.7.0":
329 version "5.6.1"329 version "5.7.0"
330 resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.1.tgz#224572ea4de257f05b4abf8ae58b03a67e99b0f4"330 resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7"
331 integrity sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==331 integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==
332 dependencies:332 dependencies:
333 "@ethersproject/abstract-signer" "^5.6.2"333 "@ethersproject/abstract-signer" "^5.7.0"
334 "@ethersproject/address" "^5.6.1"334 "@ethersproject/address" "^5.7.0"
335 "@ethersproject/bignumber" "^5.6.2"335 "@ethersproject/base64" "^5.7.0"
336 "@ethersproject/bignumber" "^5.7.0"
336 "@ethersproject/bytes" "^5.6.1"337 "@ethersproject/bytes" "^5.7.0"
337 "@ethersproject/keccak256" "^5.6.1"338 "@ethersproject/keccak256" "^5.7.0"
338 "@ethersproject/logger" "^5.6.0"339 "@ethersproject/logger" "^5.7.0"
339 "@ethersproject/properties" "^5.6.0"340 "@ethersproject/properties" "^5.7.0"
340 "@ethersproject/strings" "^5.6.1"341 "@ethersproject/strings" "^5.7.0"
341342
342"@ethersproject/keccak256@^5.6.1":343"@ethersproject/keccak256@^5.7.0":
343 version "5.6.1"344 version "5.7.0"
344 resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.1.tgz#b867167c9b50ba1b1a92bccdd4f2d6bd168a91cc"345 resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a"
345 integrity sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==346 integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==
346 dependencies:347 dependencies:
347 "@ethersproject/bytes" "^5.6.1"348 "@ethersproject/bytes" "^5.7.0"
348 js-sha3 "0.8.0"349 js-sha3 "0.8.0"
349350
350"@ethersproject/logger@^5.6.0":351"@ethersproject/logger@^5.7.0":
351 version "5.6.0"352 version "5.7.0"
352 resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a"353 resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892"
353 integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==354 integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==
354355
355"@ethersproject/networks@^5.6.3":356"@ethersproject/networks@^5.7.0":
356 version "5.6.4"357 version "5.7.0"
357 resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.4.tgz#51296d8fec59e9627554f5a8a9c7791248c8dc07"358 resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.0.tgz#df72a392f1a63a57f87210515695a31a245845ad"
358 integrity sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ==359 integrity sha512-MG6oHSQHd4ebvJrleEQQ4HhVu8Ichr0RDYEfHzsVAVjHNM+w36x9wp9r+hf1JstMXtseXDtkiVoARAG6M959AA==
359 dependencies:360 dependencies:
360 "@ethersproject/logger" "^5.6.0"361 "@ethersproject/logger" "^5.7.0"
361362
362"@ethersproject/properties@^5.6.0":363"@ethersproject/properties@^5.7.0":
363 version "5.6.0"364 version "5.7.0"
364 resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.6.0.tgz#38904651713bc6bdd5bdd1b0a4287ecda920fa04"365 resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30"
365 integrity sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==366 integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==
366 dependencies:367 dependencies:
367 "@ethersproject/logger" "^5.6.0"368 "@ethersproject/logger" "^5.7.0"
368369
369"@ethersproject/rlp@^5.6.1":370"@ethersproject/rlp@^5.7.0":
370 version "5.6.1"371 version "5.7.0"
371 resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.1.tgz#df8311e6f9f24dcb03d59a2bac457a28a4fe2bd8"372 resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304"
372 integrity sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==373 integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==
373 dependencies:374 dependencies:
374 "@ethersproject/bytes" "^5.6.1"375 "@ethersproject/bytes" "^5.7.0"
375 "@ethersproject/logger" "^5.6.0"376 "@ethersproject/logger" "^5.7.0"
376377
377"@ethersproject/signing-key@^5.6.2":378"@ethersproject/signing-key@^5.7.0":
378 version "5.6.2"379 version "5.7.0"
379 resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.2.tgz#8a51b111e4d62e5a62aee1da1e088d12de0614a3"380 resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3"
380 integrity sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==381 integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==
381 dependencies:382 dependencies:
382 "@ethersproject/bytes" "^5.6.1"383 "@ethersproject/bytes" "^5.7.0"
383 "@ethersproject/logger" "^5.6.0"384 "@ethersproject/logger" "^5.7.0"
384 "@ethersproject/properties" "^5.6.0"385 "@ethersproject/properties" "^5.7.0"
385 bn.js "^5.2.1"386 bn.js "^5.2.1"
386 elliptic "6.5.4"387 elliptic "6.5.4"
387 hash.js "1.1.7"388 hash.js "1.1.7"
388389
389"@ethersproject/strings@^5.6.1":390"@ethersproject/strings@^5.7.0":
390 version "5.6.1"391 version "5.7.0"
391 resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.1.tgz#dbc1b7f901db822b5cafd4ebf01ca93c373f8952"392 resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2"
392 integrity sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==393 integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==
393 dependencies:394 dependencies:
394 "@ethersproject/bytes" "^5.6.1"395 "@ethersproject/bytes" "^5.7.0"
395 "@ethersproject/constants" "^5.6.1"396 "@ethersproject/constants" "^5.7.0"
396 "@ethersproject/logger" "^5.6.0"397 "@ethersproject/logger" "^5.7.0"
397398
398"@ethersproject/transactions@^5.6.2":399"@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0":
399 version "5.6.2"400 version "5.7.0"
400 resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.2.tgz#793a774c01ced9fe7073985bb95a4b4e57a6370b"401 resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b"
401 integrity sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==402 integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==
402 dependencies:403 dependencies:
403 "@ethersproject/address" "^5.6.1"404 "@ethersproject/address" "^5.7.0"
404 "@ethersproject/bignumber" "^5.6.2"405 "@ethersproject/bignumber" "^5.7.0"
405 "@ethersproject/bytes" "^5.6.1"406 "@ethersproject/bytes" "^5.7.0"
406 "@ethersproject/constants" "^5.6.1"407 "@ethersproject/constants" "^5.7.0"
407 "@ethersproject/keccak256" "^5.6.1"408 "@ethersproject/keccak256" "^5.7.0"
408 "@ethersproject/logger" "^5.6.0"409 "@ethersproject/logger" "^5.7.0"
409 "@ethersproject/properties" "^5.6.0"410 "@ethersproject/properties" "^5.7.0"
410 "@ethersproject/rlp" "^5.6.1"411 "@ethersproject/rlp" "^5.7.0"
411 "@ethersproject/signing-key" "^5.6.2"412 "@ethersproject/signing-key" "^5.7.0"
412413
413"@ethersproject/web@^5.6.1":414"@ethersproject/web@^5.7.0":
414 version "5.6.1"415 version "5.7.0"
415 resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.1.tgz#6e2bd3ebadd033e6fe57d072db2b69ad2c9bdf5d"416 resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.0.tgz#40850c05260edad8b54827923bbad23d96aac0bc"
416 integrity sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==417 integrity sha512-ApHcbbj+muRASVDSCl/tgxaH2LBkRMEYfLOLVa0COipx0+nlu0QKet7U2lEg0vdkh8XRSLf2nd1f1Uk9SrVSGA==
417 dependencies:418 dependencies:
418 "@ethersproject/base64" "^5.6.1"419 "@ethersproject/base64" "^5.7.0"
419 "@ethersproject/bytes" "^5.6.1"420 "@ethersproject/bytes" "^5.7.0"
420 "@ethersproject/logger" "^5.6.0"421 "@ethersproject/logger" "^5.7.0"
421 "@ethersproject/properties" "^5.6.0"422 "@ethersproject/properties" "^5.7.0"
422 "@ethersproject/strings" "^5.6.1"423 "@ethersproject/strings" "^5.7.0"
423424
424"@humanwhocodes/config-array@^0.10.4":425"@humanwhocodes/config-array@^0.10.4":
425 version "0.10.4"426 version "0.10.4"
435 resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d"436 resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d"
436 integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==437 integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==
437438
439"@humanwhocodes/module-importer@^1.0.1":
440 version "1.0.1"
441 resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
442 integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
443
438"@humanwhocodes/object-schema@^1.2.1":444"@humanwhocodes/object-schema@^1.2.1":
439 version "1.2.1"445 version "1.2.1"
440 resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"446 resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
597 rxjs "^7.5.6"603 rxjs "^7.5.6"
598604
599"@polkadot/keyring@^10.1.4":605"@polkadot/keyring@^10.1.4":
600 version "10.1.4"606 version "10.1.7"
601 resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-10.1.4.tgz#7c60002cb442d2a160ee215b21c1319e85d97eaf"607 resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-10.1.7.tgz#d51be1dc5807c961889847d8f0e10e4bbdd19d3f"
602 integrity sha512-dCMejp5heZwKSFeO+1vCHFoo1h1KgNvu4AaKQdNxpyr/3eCINrCFI74/qT9XGypblxd61caOpJcMl8B1R/UWFA==608 integrity sha512-lArwaAS3hDs+HHupDIC4r2mFaAfmNQV2YzwL2wM5zhOqB2RugN03BFrgwNll0y9/Bg8rYDqM3Y5BvVMzgMZ6XA==
603 dependencies:609 dependencies:
604 "@babel/runtime" "^7.18.9"610 "@babel/runtime" "^7.18.9"
605 "@polkadot/util" "10.1.4"611 "@polkadot/util" "10.1.7"
606 "@polkadot/util-crypto" "10.1.4"612 "@polkadot/util-crypto" "10.1.7"
607613
608"@polkadot/networks@10.1.1":614"@polkadot/networks@10.1.7", "@polkadot/networks@^10.1.4":
609 version "10.1.1"615 version "10.1.7"
610 resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.1.tgz#d3deeff5c4cfad8c1eec85732351d80d1b2d0934"616 resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.7.tgz#33b38d70409e2daf0990ef18ff150c6718ffb700"
611 integrity sha512-upM8r0mrsCVA+vPVbJUjtnkAfdleBMHB+Fbxvy3xtbK1IFpzQTUhSOQb6lBnBAPBFGyxMtQ3TytnInckAdYZeg==617 integrity sha512-ol864SZ/GwAF72GQOPRy+Y9r6NtgJJjMBlDLESvV5VK64eEB0MRSSyiOdd7y/4SumR9crrrNimx3ynACFgxZ8A==
612 dependencies:618 dependencies:
613 "@babel/runtime" "^7.18.9"619 "@babel/runtime" "^7.18.9"
614 "@polkadot/util" "10.1.1"620 "@polkadot/util" "10.1.7"
615 "@substrate/ss58-registry" "^1.24.0"621 "@substrate/ss58-registry" "^1.28.0"
616622
617"@polkadot/networks@10.1.4", "@polkadot/networks@^10.1.4":
618 version "10.1.4"
619 resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.4.tgz#d8b375aad8f858f611165d8288eb5eab7275ca24"
620 integrity sha512-5wMwqD+DeVMh29OZZBVkA4DQE9EBsUj5FjmUS2CloA8RzE6SV0qL34zhTwOdq95KJV1OoDbp9aGjCBqhEuozKw==
621 dependencies:
622 "@babel/runtime" "^7.18.9"
623 "@polkadot/util" "10.1.4"
624 "@substrate/ss58-registry" "^1.25.0"
625
626"@polkadot/rpc-augment@9.2.2":623"@polkadot/rpc-augment@9.2.2":
627 version "9.2.2"624 version "9.2.2"
628 resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-9.2.2.tgz#7246e6a43536296ad19be8460a81e434d718ff4c"625 resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-9.2.2.tgz#7246e6a43536296ad19be8460a81e434d718ff4c"
758 "@polkadot/util-crypto" "^10.1.4"755 "@polkadot/util-crypto" "^10.1.4"
759 rxjs "^7.5.6"756 rxjs "^7.5.6"
760757
761"@polkadot/util-crypto@10.1.1":758"@polkadot/util-crypto@10.1.7", "@polkadot/util-crypto@^10.1.4":
762 version "10.1.1"759 version "10.1.7"
763 resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.1.tgz#c6e16e626e55402fdb44c8bb20ce4a9d7c50b9db"760 resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.7.tgz#fe5ea006bf23ae19319f3ac9236905a984a65e2f"
764 integrity sha512-R0V++xXbL2pvnCFIuXnKc/TlNhBkyxcno1u8rmjYNuH9S5GOmi2jY/8cNhbrwk6wafBsi+xMPHrEbUnduk82Ag==761 integrity sha512-zGmSU7a0wdWfpDtfc+Q7fUuW+extu9o1Uh4JpkuwwZ/dxmyW5xlfqVsIScM1pdPyjJsyamX8KwsKiVsW4slasg==
765 dependencies:762 dependencies:
766 "@babel/runtime" "^7.18.9"763 "@babel/runtime" "^7.18.9"
767 "@noble/hashes" "1.1.2"764 "@noble/hashes" "1.1.2"
768 "@noble/secp256k1" "1.6.3"765 "@noble/secp256k1" "1.6.3"
769 "@polkadot/networks" "10.1.1"766 "@polkadot/networks" "10.1.7"
770 "@polkadot/util" "10.1.1"767 "@polkadot/util" "10.1.7"
771 "@polkadot/wasm-crypto" "^6.3.1"768 "@polkadot/wasm-crypto" "^6.3.1"
772 "@polkadot/x-bigint" "10.1.1"769 "@polkadot/x-bigint" "10.1.7"
773 "@polkadot/x-randomvalues" "10.1.1"770 "@polkadot/x-randomvalues" "10.1.7"
774 "@scure/base" "1.1.1"771 "@scure/base" "1.1.1"
775 ed2curve "^0.3.0"772 ed2curve "^0.3.0"
776 tweetnacl "^1.0.3"773 tweetnacl "^1.0.3"
777774
778"@polkadot/util-crypto@10.1.4", "@polkadot/util-crypto@^10.1.4":775"@polkadot/util@10.1.7", "@polkadot/util@^10.1.4":
779 version "10.1.4"776 version "10.1.7"
780 resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.4.tgz#1d65a9b3d979f1cb078636a413cdf664db760a8b"777 resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.7.tgz#c54ca2a5b29cb834b40d8a876baefa3a0efb93af"
781 integrity sha512-6rdUwCdbwmQ0PBWBNYh55RsXAcFjhco/TGLuM7GJ7YufrN9qqv1sr40HlneLbtpiZnfukZ3q/qOpj0h7Hrw2JQ==778 integrity sha512-s7gDLdNb4HUpoe3faXwoO6HwiUp8pi66voYKiUYRh1kEtW1o9vGBgyZPHPGC/FBgILzTJKii/9XxnSex60zBTA==
782 dependencies:779 dependencies:
783 "@babel/runtime" "^7.18.9"780 "@babel/runtime" "^7.18.9"
784 "@noble/hashes" "1.1.2"781 "@polkadot/x-bigint" "10.1.7"
785 "@noble/secp256k1" "1.6.3"
786 "@polkadot/networks" "10.1.4"
787 "@polkadot/util" "10.1.4"
788 "@polkadot/wasm-crypto" "^6.3.1"
789 "@polkadot/x-bigint" "10.1.4"
790 "@polkadot/x-randomvalues" "10.1.4"
791 "@scure/base" "1.1.1"
792 ed2curve "^0.3.0"
793 tweetnacl "^1.0.3"
794
795"@polkadot/util@10.1.1":
796 version "10.1.1"
797 resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.1.tgz#5aa20eac03806e70dc21e618a7f8cd767dac0fd0"
798 integrity sha512-/g0sEqOOXfiNmQnWcFK3H1+wKBjbJEfGj6lTmbQ0xnL4TS5mFFQ7ZZEvxD60EkoXVMuCmSSh9E54goNLzh+Zyg==
799 dependencies:
800 "@babel/runtime" "^7.18.9"
801 "@polkadot/x-bigint" "10.1.1"782 "@polkadot/x-global" "10.1.7"
802 "@polkadot/x-global" "10.1.1"
803 "@polkadot/x-textdecoder" "10.1.1"783 "@polkadot/x-textdecoder" "10.1.7"
804 "@polkadot/x-textencoder" "10.1.1"784 "@polkadot/x-textencoder" "10.1.7"
805 "@types/bn.js" "^5.1.0"785 "@types/bn.js" "^5.1.1"
806 bn.js "^5.2.1"786 bn.js "^5.2.1"
807787
808"@polkadot/util@10.1.4", "@polkadot/util@^10.1.4":
809 version "10.1.4"
810 resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.4.tgz#29654dd52d5028fd9ca175e9cebad605fa79396c"
811 integrity sha512-MHz1UxYXuV+XxPl+GR++yOUE0OCiVd+eJBqLgpjpVJNRkudbAmfGAbB2TNR0+76M0fevIeHj4DGEd0gY6vqKLw==
812 dependencies:
813 "@babel/runtime" "^7.18.9"
814 "@polkadot/x-bigint" "10.1.4"
815 "@polkadot/x-global" "10.1.4"
816 "@polkadot/x-textdecoder" "10.1.4"
817 "@polkadot/x-textencoder" "10.1.4"
818 "@types/bn.js" "^5.1.0"
819 bn.js "^5.2.1"
820
821"@polkadot/wasm-bridge@6.3.1":788"@polkadot/wasm-bridge@6.3.1":
822 version "6.3.1"789 version "6.3.1"
823 resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-6.3.1.tgz#439fa78e80947a7cb695443e1f64b25c30bb1487"790 resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-6.3.1.tgz#439fa78e80947a7cb695443e1f64b25c30bb1487"
869 dependencies:836 dependencies:
870 "@babel/runtime" "^7.18.9"837 "@babel/runtime" "^7.18.9"
871838
872"@polkadot/x-bigint@10.1.1":839"@polkadot/x-bigint@10.1.7", "@polkadot/x-bigint@^10.1.4":
873 version "10.1.1"840 version "10.1.7"
874 resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.1.tgz#c084cfdfe48633da07423f4d9916563882947563"841 resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.7.tgz#1338689476ffdbb9f9cb243df1954ae8186134b9"
875 integrity sha512-YNYN64N4icKyqiDIw0tcGyWwz3g/282Kk0ozfcA5TM0wGRe2BwmoB4gYrZ7pJDxvsHnRPR6Dw0r9Xxh8DNIzHQ==842 integrity sha512-uaClHpI6cnDumIfejUKvNTkB43JleEb0V6OIufDKJ/e1aCLE3f/Ws9ggwL8ea05lQP5k5xqOzbPdizi/UvrgKQ==
876 dependencies:843 dependencies:
877 "@babel/runtime" "^7.18.9"844 "@babel/runtime" "^7.18.9"
878 "@polkadot/x-global" "10.1.1"845 "@polkadot/x-global" "10.1.7"
879846
880"@polkadot/x-bigint@10.1.4", "@polkadot/x-bigint@^10.1.4":
881 version "10.1.4"
882 resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.4.tgz#a084a9d2f80f25ffd529faafdf95cd6c3044ef74"
883 integrity sha512-qgLetTukFhkxNxNcUWMmnrfE9bp4TNbrqNoVBVH7wqSuEVpDPITBXsQ/78LbaaZGWD80Ew0wGxcZ/rqX+dLVUA==
884 dependencies:
885 "@babel/runtime" "^7.18.9"
886 "@polkadot/x-global" "10.1.4"
887
888"@polkadot/x-fetch@^10.1.4":847"@polkadot/x-fetch@^10.1.4":
889 version "10.1.4"848 version "10.1.7"
890 resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-10.1.4.tgz#72db88007c74f3aee47f72091a33d553f7ca241a"849 resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-10.1.7.tgz#1b76051a495563403a20ef235a8558c6d91b11a6"
891 integrity sha512-hVhLpOvx+ys6klkqWJnINi9FU/JcDnc+6cyU9fa+Dum3mqO1XnngOYDO9mpf5HODIwrFNFmohll9diRP+TW0yQ==850 integrity sha512-NL+xrlqUoCLwCIAvQLwOA189gSUgeSGOFjCmZ9uMkBqf35KXeZoHWse6YaoseTSlnAal3dQOGbXnYWZ4Ck2OSA==
892 dependencies:851 dependencies:
893 "@babel/runtime" "^7.18.9"852 "@babel/runtime" "^7.18.9"
894 "@polkadot/x-global" "10.1.4"853 "@polkadot/x-global" "10.1.7"
895 "@types/node-fetch" "^2.6.2"854 "@types/node-fetch" "^2.6.2"
896 node-fetch "^3.2.10"855 node-fetch "^3.2.10"
897856
898"@polkadot/x-global@10.1.1":857"@polkadot/x-global@10.1.7", "@polkadot/x-global@^10.1.4":
899 version "10.1.1"858 version "10.1.7"
900 resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.1.tgz#d0d90ef71fd94f59605e8c73dcd1aa3e3dd4fc37"859 resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.7.tgz#91a472ac2f83fd0858dcd0df528844a5b650790e"
901 integrity sha512-wB3rZTTNN14umLSfR2GLL0dJrlGM1YRUNw7XvbA+3B8jxGCIOmjSyAkdZBeiCxg2XIbJD3EkB0hBhga2mNuS6g==860 integrity sha512-k2ZUZyBVgDnP/Ysxapa0mthn63j6gsN2V0kZejEQPyOfCHtQQkse3jFvAWdslpWoR8j2k8SN5O6reHc0F4f7mA==
902 dependencies:861 dependencies:
903 "@babel/runtime" "^7.18.9"862 "@babel/runtime" "^7.18.9"
904863
905"@polkadot/x-global@10.1.4", "@polkadot/x-global@^10.1.4":864"@polkadot/x-randomvalues@10.1.7":
906 version "10.1.4"865 version "10.1.7"
907 resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.4.tgz#657f7054fe07a7c027b4d18fcfa3438d2ffaef07"866 resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.7.tgz#d537f1f7bf3fb03e6c08ae6e6ac36e069c1f9844"
908 integrity sha512-67f53H872wHvmjmL96DvhC3dG7gKRG1ghEbHXeFIGwkix+9zGEMV9krYW1+OAvGAuCQZqUIUGiJ7lad4Zjb7wQ==867 integrity sha512-3er4UYOlozLGgFYWwcbmcFslmO8m82u4cAGR4AaEag0VdV7jLO/M5lTmivT/3rtLSww6sjkEfr522GM2Q5lmFg==
909 dependencies:868 dependencies:
910 "@babel/runtime" "^7.18.9"869 "@babel/runtime" "^7.18.9"
870 "@polkadot/x-global" "10.1.7"
911871
912"@polkadot/x-randomvalues@10.1.1":872"@polkadot/x-textdecoder@10.1.7":
913 version "10.1.1"873 version "10.1.7"
914 resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.1.tgz#3b1f590e6641e322e3a28bb4f17f0a53005d9ada"874 resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.7.tgz#1dd4e6141b1669acdd321a4da1fc6fdc271b7908"
915 integrity sha512-opVFNEnzCir7cWsFfyDqNlrGazkpjnL+JpkxE/b9WmSco6y0IUzn/Q7rL3EaBzBEvxY0/J8KeSGGs3W+mf6tBQ==875 integrity sha512-iAFOHludmZFOyVL8sQFv4TDqbcqQU5gwwYv74duTA+WQBgbSITJrBahSCV/rXOjUqds9pzQO3qBFzziznNnkiQ==
916 dependencies:876 dependencies:
917 "@babel/runtime" "^7.18.9"877 "@babel/runtime" "^7.18.9"
918 "@polkadot/x-global" "10.1.1"878 "@polkadot/x-global" "10.1.7"
919879
920"@polkadot/x-randomvalues@10.1.4":880"@polkadot/x-textencoder@10.1.7":
921 version "10.1.4"881 version "10.1.7"
922 resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.4.tgz#de337a046826223081697e6fc1991c547f685787"882 resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.7.tgz#b208601f33b936c7a059f126dbb6b26a87f45864"
923 integrity sha512-sfYz3GmyG739anj07Y+8PUX+95upO1zlsADAEfK1w1mMpTw97xEoMZf66CduAQOe43gEwQXc/JuKq794C/Hr7Q==883 integrity sha512-GzjaWZDbgzZ0IQT60xuZ7cZ0wnlNVYMqpfI9KvBc58X9dPI3TIMwzbXDVzZzpjY1SAqJGs4hJse9HMWZazfhew==
924 dependencies:884 dependencies:
925 "@babel/runtime" "^7.18.9"885 "@babel/runtime" "^7.18.9"
926 "@polkadot/x-global" "10.1.4"886 "@polkadot/x-global" "10.1.7"
927887
928"@polkadot/x-textdecoder@10.1.1":
929 version "10.1.1"
930 resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.1.tgz#536d0093749fcc14a60d4ae29c35f699dea7e651"
931 integrity sha512-a52ah/sUS+aGZcCCL7BhrytAeV/7kiqu1zbuCoZtIzxP6x34a2vcic3bLPoyynLcX2ruzvLKFhJDGOJ4Bq5lcA==
932 dependencies:
933 "@babel/runtime" "^7.18.9"
934 "@polkadot/x-global" "10.1.1"
935
936"@polkadot/x-textdecoder@10.1.4":
937 version "10.1.4"
938 resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.4.tgz#d85028f6fcd00adc1e3581ab97668a61299270f9"
939 integrity sha512-B8XcAmJLnuppSr4RUNPevh5MH3tWZBwBR0wUsSdIyiGXuncgnkj9jmpbGLgV1tSn+BGxX3SNsRho3/4CNmndWQ==
940 dependencies:
941 "@babel/runtime" "^7.18.9"
942 "@polkadot/x-global" "10.1.4"
943
944"@polkadot/x-textencoder@10.1.1":
945 version "10.1.1"
946 resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.1.tgz#c1a86b3d0fe0ca65d30c8ce5c6f75c4035e95847"
947 integrity sha512-prTzUXXW9OxFyf17EwGSBxe2GvVFG60cmKV8goC50nghhNMl1y0GdGpvKNQTFG6hIk5fIon9/pBpWsas4iAf+Q==
948 dependencies:
949 "@babel/runtime" "^7.18.9"
950 "@polkadot/x-global" "10.1.1"
951
952"@polkadot/x-textencoder@10.1.4":
953 version "10.1.4"
954 resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.4.tgz#253e828bb571eb2a92a8377acd57d9bfcbe52fe8"
955 integrity sha512-vDpo0rVV4jBmr0L2tCZPZzxmzV2vZhpH1Dw9H7MpmZSPePz4ZF+o4RBJz/ocwQh3+1qV1SKQm7+fj4lPwUZdEw==
956 dependencies:
957 "@babel/runtime" "^7.18.9"
958 "@polkadot/x-global" "10.1.4"
959
960"@polkadot/x-ws@^10.1.4":888"@polkadot/x-ws@^10.1.4":
961 version "10.1.4"889 version "10.1.7"
962 resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-10.1.4.tgz#b3fa515598bc6f8e85d92754d5f1c4be19ca44a1"890 resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-10.1.7.tgz#b1fbfe3e16fa809f35f24ef47fde145b018d8cdc"
963 integrity sha512-hi7hBRRCLlHgqVW2p5TkoJuTxV7sVprl+aAnmcIpPU4J8Ai6PKQvXR+fLK01T8moBYmH5ztHrBWvY/XRzmQ8Vg==891 integrity sha512-aNkotxHx3qPVjiItD9lbNONs4GNzqeeZ98wHtCjd9JWl/g+xNkOVF3xQ8++1qSHPBEYSwKh9URjQH2+CD2XlvQ==
964 dependencies:892 dependencies:
965 "@babel/runtime" "^7.18.9"893 "@babel/runtime" "^7.18.9"
966 "@polkadot/x-global" "10.1.4"894 "@polkadot/x-global" "10.1.7"
967 "@types/websocket" "^1.0.5"895 "@types/websocket" "^1.0.5"
968 websocket "^1.0.34"896 websocket "^1.0.34"
969897
972 resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"900 resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
973 integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==901 integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
974902
975"@sindresorhus/is@^4.6.0":903"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0":
976 version "4.6.0"904 version "4.6.0"
977 resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"905 resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
978 integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==906 integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
999 pako "^2.0.4"927 pako "^2.0.4"
1000 websocket "^1.0.32"928 websocket "^1.0.32"
1001929
1002"@substrate/ss58-registry@^1.24.0", "@substrate/ss58-registry@^1.25.0":930"@substrate/ss58-registry@^1.28.0":
1003 version "1.25.0"931 version "1.29.0"
1004 resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.25.0.tgz#0fcd8c9c0e53963a88fbed41f2cbd8a1a5c74cde"932 resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.29.0.tgz#0dea078271b5318c5eff7176e1df1f9b2c27e43f"
1005 integrity sha512-LmCH4QJRdHaeLsLTPSgJaXguMoIW+Ig9fA9LRPpeya9HefVAJ7gZuUYinldv+QmX7evNm5CL0rspNUS8l1DvXg==933 integrity sha512-KTqwZgTjtWPhCAUJJx9qswP/p9cRKUU9GOHYUDKNdISFDiFafWmpI54JHfYLkgjvkSKEUgRZnvLpe0LMF1fXvw==
1006934
935"@szmarczak/http-timer@^4.0.5":
936 version "4.0.6"
937 resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
938 integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
939 dependencies:
940 defer-to-connect "^2.0.0"
941
1007"@szmarczak/http-timer@^5.0.1":942"@szmarczak/http-timer@^5.0.1":
1008 version "5.0.1"943 version "5.0.1"
1009 resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a"944 resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a"
1031 resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"966 resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
1032 integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==967 integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
1033968
1034"@types/bn.js@^5.1.0":969"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1":
1035 version "5.1.0"970 version "5.1.1"
1036 resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68"971 resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682"
1037 integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==972 integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==
1038 dependencies:973 dependencies:
1039 "@types/node" "*"974 "@types/node" "*"
1040975
1041"@types/cacheable-request@^6.0.2":976"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2":
1042 version "6.0.2"977 version "6.0.2"
1043 resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9"978 resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9"
1044 integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==979 integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==
1097 resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"1032 resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"
1098 integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==1033 integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==
10991034
1100"@types/json-buffer@~3.0.0":
1101 version "3.0.0"
1102 resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64"
1103 integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==
1104
1105"@types/json-schema@^7.0.9":1035"@types/json-schema@^7.0.9":
1106 version "7.0.11"1036 version "7.0.11"
1107 resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"1037 resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
1128 form-data "^3.0.0"1058 form-data "^3.0.0"
11291059
1130"@types/node@*":1060"@types/node@*":
1131 version "18.7.5"1061 version "18.7.16"
1132 resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.5.tgz#f1c1d4b7d8231c0278962347163656f9c36f3e83"1062 resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.16.tgz#0eb3cce1e37c79619943d2fd903919fc30850601"
1133 integrity sha512-NcKK6Ts+9LqdHJaW6HQmgr7dT/i3GOHG+pt6BiWv++5SnjtRd4NXeiuN2kA153SjhXPR/AhHIPHPbrsbpUVOww==1063 integrity sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==
11341064
1135"@types/node@^12.12.6":1065"@types/node@^12.12.6":
1136 version "12.20.55"1066 version "12.20.55"
1171 "@types/node" "*"1101 "@types/node" "*"
11721102
1173"@typescript-eslint/eslint-plugin@^5.26.0":1103"@typescript-eslint/eslint-plugin@^5.26.0":
1174 version "5.33.1"1104 version "5.36.2"
1175 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz#c0a480d05211660221eda963cc844732fe9b1714"1105 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.2.tgz#6df092a20e0f9ec748b27f293a12cb39d0c1fe4d"
1176 integrity sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==1106 integrity sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==
1177 dependencies:1107 dependencies:
1178 "@typescript-eslint/scope-manager" "5.33.1"1108 "@typescript-eslint/scope-manager" "5.36.2"
1179 "@typescript-eslint/type-utils" "5.33.1"1109 "@typescript-eslint/type-utils" "5.36.2"
1180 "@typescript-eslint/utils" "5.33.1"1110 "@typescript-eslint/utils" "5.36.2"
1181 debug "^4.3.4"1111 debug "^4.3.4"
1182 functional-red-black-tree "^1.0.1"1112 functional-red-black-tree "^1.0.1"
1183 ignore "^5.2.0"1113 ignore "^5.2.0"
1186 tsutils "^3.21.0"1116 tsutils "^3.21.0"
11871117
1188"@typescript-eslint/parser@^5.26.0":1118"@typescript-eslint/parser@^5.26.0":
1189 version "5.33.1"1119 version "5.36.2"
1190 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.1.tgz#e4b253105b4d2a4362cfaa4e184e2d226c440ff3"1120 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.36.2.tgz#3ddf323d3ac85a25295a55fcb9c7a49ab4680ddd"
1191 integrity sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==1121 integrity sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==
1192 dependencies:1122 dependencies:
1193 "@typescript-eslint/scope-manager" "5.33.1"1123 "@typescript-eslint/scope-manager" "5.36.2"
1194 "@typescript-eslint/types" "5.33.1"1124 "@typescript-eslint/types" "5.36.2"
1195 "@typescript-eslint/typescript-estree" "5.33.1"1125 "@typescript-eslint/typescript-estree" "5.36.2"
1196 debug "^4.3.4"1126 debug "^4.3.4"
11971127
1198"@typescript-eslint/scope-manager@5.33.1":1128"@typescript-eslint/scope-manager@5.36.2":
1199 version "5.33.1"1129 version "5.36.2"
1200 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz#8d31553e1b874210018ca069b3d192c6d23bc493"1130 resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz#a75eb588a3879ae659514780831370642505d1cd"
1201 integrity sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==1131 integrity sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==
1202 dependencies:1132 dependencies:
1203 "@typescript-eslint/types" "5.33.1"1133 "@typescript-eslint/types" "5.36.2"
1204 "@typescript-eslint/visitor-keys" "5.33.1"1134 "@typescript-eslint/visitor-keys" "5.36.2"
12051135
1206"@typescript-eslint/type-utils@5.33.1":1136"@typescript-eslint/type-utils@5.36.2":
1207 version "5.33.1"1137 version "5.36.2"
1208 resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz#1a14e94650a0ae39f6e3b77478baff002cec4367"1138 resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.36.2.tgz#752373f4babf05e993adf2cd543a763632826391"
1209 integrity sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==1139 integrity sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==
1210 dependencies:1140 dependencies:
1211 "@typescript-eslint/utils" "5.33.1"1141 "@typescript-eslint/typescript-estree" "5.36.2"
1142 "@typescript-eslint/utils" "5.36.2"
1212 debug "^4.3.4"1143 debug "^4.3.4"
1213 tsutils "^3.21.0"1144 tsutils "^3.21.0"
12141145
1215"@typescript-eslint/types@5.33.1":1146"@typescript-eslint/types@5.36.2":
1216 version "5.33.1"1147 version "5.36.2"
1217 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.1.tgz#3faef41793d527a519e19ab2747c12d6f3741ff7"1148 resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.36.2.tgz#a5066e500ebcfcee36694186ccc57b955c05faf9"
1218 integrity sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==1149 integrity sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==
12191150
1220"@typescript-eslint/typescript-estree@5.33.1":1151"@typescript-eslint/typescript-estree@5.36.2":
1221 version "5.33.1"1152 version "5.36.2"
1222 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz#a573bd360790afdcba80844e962d8b2031984f34"1153 resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz#0c93418b36c53ba0bc34c61fe9405c4d1d8fe560"
1223 integrity sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==1154 integrity sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==
1224 dependencies:1155 dependencies:
1225 "@typescript-eslint/types" "5.33.1"1156 "@typescript-eslint/types" "5.36.2"
1226 "@typescript-eslint/visitor-keys" "5.33.1"1157 "@typescript-eslint/visitor-keys" "5.36.2"
1227 debug "^4.3.4"1158 debug "^4.3.4"
1228 globby "^11.1.0"1159 globby "^11.1.0"
1229 is-glob "^4.0.3"1160 is-glob "^4.0.3"
1230 semver "^7.3.7"1161 semver "^7.3.7"
1231 tsutils "^3.21.0"1162 tsutils "^3.21.0"
12321163
1233"@typescript-eslint/utils@5.33.1":1164"@typescript-eslint/utils@5.36.2":
1234 version "5.33.1"1165 version "5.36.2"
1235 resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.1.tgz#171725f924fe1fe82bb776522bb85bc034e88575"1166 resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.36.2.tgz#b01a76f0ab244404c7aefc340c5015d5ce6da74c"
1236 integrity sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==1167 integrity sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg==
1237 dependencies:1168 dependencies:
1238 "@types/json-schema" "^7.0.9"1169 "@types/json-schema" "^7.0.9"
1239 "@typescript-eslint/scope-manager" "5.33.1"1170 "@typescript-eslint/scope-manager" "5.36.2"
1240 "@typescript-eslint/types" "5.33.1"1171 "@typescript-eslint/types" "5.36.2"
1241 "@typescript-eslint/typescript-estree" "5.33.1"1172 "@typescript-eslint/typescript-estree" "5.36.2"
1242 eslint-scope "^5.1.1"1173 eslint-scope "^5.1.1"
1243 eslint-utils "^3.0.0"1174 eslint-utils "^3.0.0"
12441175
1245"@typescript-eslint/visitor-keys@5.33.1":1176"@typescript-eslint/visitor-keys@5.36.2":
1246 version "5.33.1"1177 version "5.36.2"
1247 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz#0155c7571c8cd08956580b880aea327d5c34a18b"1178 resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz#2f8f78da0a3bad3320d2ac24965791ac39dace5a"
1248 integrity sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==1179 integrity sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==
1249 dependencies:1180 dependencies:
1250 "@typescript-eslint/types" "5.33.1"1181 "@typescript-eslint/types" "5.36.2"
1251 eslint-visitor-keys "^3.3.0"1182 eslint-visitor-keys "^3.3.0"
12521183
1253"@ungap/promise-all-settled@1.1.2":1184"@ungap/promise-all-settled@1.1.2":
1621 resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"1552 resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
1622 integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==1553 integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
16231554
1555cacheable-lookup@^5.0.3:
1556 version "5.0.4"
1557 resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
1558 integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
1559
1624cacheable-lookup@^6.0.4:1560cacheable-lookup@^6.0.4:
1625 version "6.1.0"1561 version "6.1.0"
1626 resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385"1562 resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385"
1658 integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==1594 integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
16591595
1660caniuse-lite@^1.0.30001370:1596caniuse-lite@^1.0.30001370:
1661 version "1.0.30001377"1597 version "1.0.30001393"
1662 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001377.tgz#fa446cef27f25decb0c7420759c9ea17a2221a70"1598 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz#1aa161e24fe6af2e2ccda000fc2b94be0b0db356"
1663 integrity sha512-I5XeHI1x/mRSGl96LFOaSk528LA/yZG3m3iQgImGujjO8gotd/DL8QaI1R1h1dg5ATeI2jqPblMpKq4Tr5iKfQ==1599 integrity sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==
16641600
1665caseless@~0.12.0:1601caseless@~0.12.0:
1666 version "0.12.0"1602 version "0.12.0"
1834 resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"1770 resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
1835 integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==1771 integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
18361772
1837compress-brotli@^1.3.8:
1838 version "1.3.8"
1839 resolved "https://registry.yarnpkg.com/compress-brotli/-/compress-brotli-1.3.8.tgz#0c0a60c97a989145314ec381e84e26682e7b38db"
1840 integrity sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==
1841 dependencies:
1842 "@types/json-buffer" "~3.0.0"
1843 json-buffer "~3.0.1"
1844
1845concat-map@0.0.1:1773concat-map@0.0.1:
1846 version "0.0.1"1774 version "0.0.1"
1847 resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"1775 resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
2016 resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"1944 resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
2017 integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==1945 integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==
20181946
2019decompress-response@^3.2.0:
2020 version "3.3.0"
2021 resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
2022 integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==
2023 dependencies:
2024 mimic-response "^1.0.0"
2025
2026decompress-response@^6.0.0:1947decompress-response@^6.0.0:
2027 version "6.0.0"1948 version "6.0.0"
2028 resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"1949 resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
2042 resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"1963 resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
2043 integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==1964 integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
20441965
2045defer-to-connect@^2.0.1:1966defer-to-connect@^2.0.0, defer-to-connect@^2.0.1:
2046 version "2.0.1"1967 version "2.0.1"
2047 resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"1968 resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
2048 integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==1969 integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
2116 resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"2037 resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
2117 integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==2038 integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
21182039
2119duplexer3@^0.1.4:
2120 version "0.1.5"
2121 resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
2122 integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
2123
2124ecc-jsbn@~0.1.1:2040ecc-jsbn@~0.1.1:
2125 version "0.1.2"2041 version "0.1.2"
2126 resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"2042 resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
2142 integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==2058 integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
21432059
2144electron-to-chromium@^1.4.202:2060electron-to-chromium@^1.4.202:
2145 version "1.4.221"2061 version "1.4.246"
2146 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.221.tgz#1ff8425d257a8bfc8269d552a426993c5b525471"2062 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.246.tgz#802132d1bbd3ff32ce82fcd6a6ed6ab59b4366dc"
2147 integrity sha512-aWg2mYhpxZ6Q6Xvyk7B2ziBca4YqrCDlXzmcD7wuRs65pVEVkMT1u2ifdjpAQais2O2o0rW964ZWWWYRlAL/kw==2063 integrity sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==
21482064
2149elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4:2065elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4:
2150 version "6.5.4"2066 version "6.5.4"
2177 once "^1.4.0"2093 once "^1.4.0"
21782094
2179es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0:2095es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0:
2180 version "1.20.1"2096 version "1.20.2"
2181 resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"2097 resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3"
2182 integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==2098 integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==
2183 dependencies:2099 dependencies:
2184 call-bind "^1.0.2"2100 call-bind "^1.0.2"
2185 es-to-primitive "^1.2.1"2101 es-to-primitive "^1.2.1"
2186 function-bind "^1.1.1"2102 function-bind "^1.1.1"
2187 function.prototype.name "^1.1.5"2103 function.prototype.name "^1.1.5"
2188 get-intrinsic "^1.1.1"2104 get-intrinsic "^1.1.2"
2189 get-symbol-description "^1.0.0"2105 get-symbol-description "^1.0.0"
2190 has "^1.0.3"2106 has "^1.0.3"
2191 has-property-descriptors "^1.0.0"2107 has-property-descriptors "^1.0.0"
2197 is-shared-array-buffer "^1.0.2"2113 is-shared-array-buffer "^1.0.2"
2198 is-string "^1.0.7"2114 is-string "^1.0.7"
2199 is-weakref "^1.0.2"2115 is-weakref "^1.0.2"
2200 object-inspect "^1.12.0"2116 object-inspect "^1.12.2"
2201 object-keys "^1.1.1"2117 object-keys "^1.1.1"
2202 object.assign "^4.1.2"2118 object.assign "^4.1.4"
2203 regexp.prototype.flags "^1.4.3"2119 regexp.prototype.flags "^1.4.3"
2204 string.prototype.trimend "^1.0.5"2120 string.prototype.trimend "^1.0.5"
2205 string.prototype.trimstart "^1.0.5"2121 string.prototype.trimstart "^1.0.5"
2299 integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==2215 integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
23002216
2301eslint@^8.16.0:2217eslint@^8.16.0:
2302 version "8.22.0"2218 version "8.23.0"
2303 resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48"2219 resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040"
2304 integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==2220 integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==
2305 dependencies:2221 dependencies:
2306 "@eslint/eslintrc" "^1.3.0"2222 "@eslint/eslintrc" "^1.3.1"
2307 "@humanwhocodes/config-array" "^0.10.4"2223 "@humanwhocodes/config-array" "^0.10.4"
2308 "@humanwhocodes/gitignore-to-minimatch" "^1.0.2"2224 "@humanwhocodes/gitignore-to-minimatch" "^1.0.2"
2225 "@humanwhocodes/module-importer" "^1.0.1"
2309 ajv "^6.10.0"2226 ajv "^6.10.0"
2310 chalk "^4.0.0"2227 chalk "^4.0.0"
2311 cross-spawn "^7.0.2"2228 cross-spawn "^7.0.2"
2315 eslint-scope "^7.1.1"2232 eslint-scope "^7.1.1"
2316 eslint-utils "^3.0.0"2233 eslint-utils "^3.0.0"
2317 eslint-visitor-keys "^3.3.0"2234 eslint-visitor-keys "^3.3.0"
2318 espree "^9.3.3"2235 espree "^9.4.0"
2319 esquery "^1.4.0"2236 esquery "^1.4.0"
2320 esutils "^2.0.2"2237 esutils "^2.0.2"
2321 fast-deep-equal "^3.1.3"2238 fast-deep-equal "^3.1.3"
2341 strip-ansi "^6.0.1"2258 strip-ansi "^6.0.1"
2342 strip-json-comments "^3.1.0"2259 strip-json-comments "^3.1.0"
2343 text-table "^0.2.0"2260 text-table "^0.2.0"
2344 v8-compile-cache "^2.0.3"
23452261
2346espree@^9.3.2, espree@^9.3.3:2262espree@^9.4.0:
2347 version "9.3.3"2263 version "9.4.0"
2348 resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d"2264 resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
2349 integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==2265 integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
2350 dependencies:2266 dependencies:
2351 acorn "^8.8.0"2267 acorn "^8.8.0"
2352 acorn-jsx "^5.3.2"2268 acorn-jsx "^5.3.2"
2518 vary "~1.1.2"2434 vary "~1.1.2"
25192435
2520ext@^1.1.2:2436ext@^1.1.2:
2521 version "1.6.0"2437 version "1.7.0"
2522 resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52"2438 resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
2523 integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==2439 integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
2524 dependencies:2440 dependencies:
2525 type "^2.5.0"2441 type "^2.7.2"
25262442
2527extend@~3.0.2:2443extend@~3.0.2:
2528 version "3.0.2"2444 version "3.0.2"
2545 integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==2461 integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
25462462
2547fast-glob@^3.2.9:2463fast-glob@^3.2.9:
2548 version "3.2.11"2464 version "3.2.12"
2549 resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"2465 resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
2550 integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==2466 integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
2551 dependencies:2467 dependencies:
2552 "@nodelib/fs.stat" "^2.0.2"2468 "@nodelib/fs.stat" "^2.0.2"
2553 "@nodelib/fs.walk" "^1.2.3"2469 "@nodelib/fs.walk" "^1.2.3"
2654 integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==2570 integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
26552571
2656flatted@^3.1.0:2572flatted@^3.1.0:
2657 version "3.2.6"2573 version "3.2.7"
2658 resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"2574 resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
2659 integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==2575 integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
26602576
2661follow-redirects@^1.12.1:2577follow-redirects@^1.12.1:
2662 version "1.15.1"2578 version "1.15.1"
2781 resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"2697 resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
2782 integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==2698 integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
27832699
2784get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:2700get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.2:
2785 version "1.1.2"2701 version "1.1.2"
2786 resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"2702 resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
2787 integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==2703 integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
2790 has "^1.0.3"2706 has "^1.0.3"
2791 has-symbols "^1.0.3"2707 has-symbols "^1.0.3"
27922708
2793get-stream@^3.0.0:
2794 version "3.0.0"
2795 resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
2796 integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==
2797
2798get-stream@^5.1.0:2709get-stream@^5.1.0:
2799 version "5.2.0"2710 version "5.2.0"
2800 resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"2711 resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
2911 p-cancelable "^3.0.0"2822 p-cancelable "^3.0.0"
2912 responselike "^2.0.0"2823 responselike "^2.0.0"
29132824
2914got@^7.1.0:2825got@^11.8.5:
2915 version "7.1.0"2826 version "11.8.5"
2916 resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"2827 resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046"
2917 integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==2828 integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==
2918 dependencies:2829 dependencies:
2919 decompress-response "^3.2.0"2830 "@sindresorhus/is" "^4.0.0"
2920 duplexer3 "^0.1.4"
2921 get-stream "^3.0.0"
2922 is-plain-obj "^1.1.0"2831 "@szmarczak/http-timer" "^4.0.5"
2923 is-retry-allowed "^1.0.0"2832 "@types/cacheable-request" "^6.0.1"
2924 is-stream "^1.0.0"2833 "@types/responselike" "^1.0.0"
2925 isurl "^1.0.0-alpha5"2834 cacheable-lookup "^5.0.3"
2926 lowercase-keys "^1.0.0"2835 cacheable-request "^7.0.2"
2927 p-cancelable "^0.3.0"2836 decompress-response "^6.0.0"
2928 p-timeout "^1.1.1"2837 http2-wrapper "^1.0.0-beta.5.2"
2929 safe-buffer "^5.0.1"
2930 timed-out "^4.0.0"2838 lowercase-keys "^2.0.0"
2931 url-parse-lax "^1.0.0"2839 p-cancelable "^2.0.0"
2932 url-to-options "^1.0.1"2840 responselike "^2.0.0"
29332841
2934graceful-fs@^4.1.2, graceful-fs@^4.1.6:2842graceful-fs@^4.1.2, graceful-fs@^4.1.6:
2935 version "4.2.10"2843 version "4.2.10"
2988 dependencies:2896 dependencies:
2989 get-intrinsic "^1.1.1"2897 get-intrinsic "^1.1.1"
29902898
2991has-symbol-support-x@^1.4.1:
2992 version "1.4.2"
2993 resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
2994 integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
2995
2996has-symbols@^1.0.2, has-symbols@^1.0.3:2899has-symbols@^1.0.2, has-symbols@^1.0.3:
2997 version "1.0.3"2900 version "1.0.3"
2998 resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"2901 resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
2999 integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==2902 integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
30002903
3001has-to-string-tag-x@^1.2.0:
3002 version "1.4.1"
3003 resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
3004 integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
3005 dependencies:
3006 has-symbol-support-x "^1.4.1"
3007
3008has-tostringtag@^1.0.0:2904has-tostringtag@^1.0.0:
3009 version "1.0.0"2905 version "1.0.0"
3010 resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"2906 resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
3080 jsprim "^1.2.2"2976 jsprim "^1.2.2"
3081 sshpk "^1.7.0"2977 sshpk "^1.7.0"
30822978
2979http2-wrapper@^1.0.0-beta.5.2:
2980 version "1.0.3"
2981 resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
2982 integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
2983 dependencies:
2984 quick-lru "^5.1.1"
2985 resolve-alpn "^1.0.0"
2986
3083http2-wrapper@^2.1.10:2987http2-wrapper@^2.1.10:
3084 version "2.1.11"2988 version "2.1.11"
3085 resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.1.11.tgz#d7c980c7ffb85be3859b6a96c800b2951ae257ef"2989 resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.1.11.tgz#d7c980c7ffb85be3859b6a96c800b2951ae257ef"
3245 resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"3149 resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
3246 integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==3150 integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
32473151
3248is-object@^1.0.1:
3249 version "1.0.2"
3250 resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf"
3251 integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==
3252
3253is-plain-obj@^1.1.0:
3254 version "1.1.0"
3255 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
3256 integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
3257
3258is-plain-obj@^2.1.0:3152is-plain-obj@^2.1.0:
3259 version "2.1.0"3153 version "2.1.0"
3260 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"3154 resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
3275 call-bind "^1.0.2"3169 call-bind "^1.0.2"
3276 has-tostringtag "^1.0.0"3170 has-tostringtag "^1.0.0"
32773171
3278is-retry-allowed@^1.0.0:
3279 version "1.2.0"
3280 resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
3281 integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
3282
3283is-shared-array-buffer@^1.0.2:3172is-shared-array-buffer@^1.0.2:
3284 version "1.0.2"3173 version "1.0.2"
3285 resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"3174 resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
3286 integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==3175 integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
3287 dependencies:3176 dependencies:
3288 call-bind "^1.0.2"3177 call-bind "^1.0.2"
32893178
3290is-stream@^1.0.0:
3291 version "1.1.0"
3292 resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
3293 integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
3294
3295is-string@^1.0.5, is-string@^1.0.7:3179is-string@^1.0.5, is-string@^1.0.7:
3296 version "1.0.7"3180 version "1.0.7"
3297 resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"3181 resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
3349 resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"3233 resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
3350 integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==3234 integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
33513235
3352isurl@^1.0.0-alpha5:
3353 version "1.0.0"
3354 resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
3355 integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
3356 dependencies:
3357 has-to-string-tag-x "^1.2.0"
3358 is-object "^1.0.1"
3359
3360js-sha3@0.8.0, js-sha3@^0.8.0:3236js-sha3@0.8.0, js-sha3@^0.8.0:
3361 version "0.8.0"3237 version "0.8.0"
3362 resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"3238 resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
3389 resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"3265 resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
3390 integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==3266 integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
33913267
3392json-buffer@3.0.1, json-buffer@~3.0.1:3268json-buffer@3.0.1:
3393 version "3.0.1"3269 version "3.0.1"
3394 resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"3270 resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
3395 integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==3271 integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
3446 readable-stream "^3.6.0"3322 readable-stream "^3.6.0"
34473323
3448keyv@^4.0.0:3324keyv@^4.0.0:
3449 version "4.3.3"3325 version "4.5.0"
3450 resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.3.3.tgz#6c1bcda6353a9e96fc1b4e1aeb803a6e35090ba9"3326 resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.0.tgz#dbce9ade79610b6e641a9a65f2f6499ba06b9bc6"
3451 integrity sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==3327 integrity sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==
3452 dependencies:3328 dependencies:
3453 compress-brotli "^1.3.8"
3454 json-buffer "3.0.1"3329 json-buffer "3.0.1"
34553330
3456kind-of@^6.0.2:3331kind-of@^6.0.2:
3506 dependencies:3381 dependencies:
3507 get-func-name "^2.0.0"3382 get-func-name "^2.0.0"
35083383
3509lowercase-keys@^1.0.0:
3510 version "1.0.1"
3511 resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
3512 integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
3513
3514lowercase-keys@^2.0.0:3384lowercase-keys@^2.0.0:
3515 version "2.0.0"3385 version "2.0.0"
3516 resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"3386 resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
3885 resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"3755 resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
3886 integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==3756 integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
38873757
3888object-inspect@^1.12.0, object-inspect@^1.9.0:3758object-inspect@^1.12.2, object-inspect@^1.9.0:
3889 version "1.12.2"3759 version "1.12.2"
3890 resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"3760 resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
3891 integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==3761 integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
3895 resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"3765 resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
3896 integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==3766 integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
38973767
3898object.assign@^4.1.2:3768object.assign@^4.1.4:
3899 version "4.1.3"3769 version "4.1.4"
3900 resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.3.tgz#d36b7700ddf0019abb6b1df1bb13f6445f79051f"3770 resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
3901 integrity sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA==3771 integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
3902 dependencies:3772 dependencies:
3903 call-bind "^1.0.2"3773 call-bind "^1.0.2"
3904 define-properties "^1.1.4"3774 define-properties "^1.1.4"
3943 resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"3813 resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
3944 integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==3814 integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
39453815
3946p-cancelable@^0.3.0:3816p-cancelable@^2.0.0:
3947 version "0.3.0"3817 version "2.1.1"
3948 resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"3818 resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
3949 integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==3819 integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
39503820
3951p-cancelable@^3.0.0:3821p-cancelable@^3.0.0:
3952 version "3.0.0"3822 version "3.0.0"
3953 resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050"3823 resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050"
3954 integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==3824 integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==
39553825
3956p-finally@^1.0.0:
3957 version "1.0.0"
3958 resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
3959 integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
3960
3961p-limit@^2.0.0:3826p-limit@^2.0.0:
3962 version "2.3.0"3827 version "2.3.0"
3963 resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"3828 resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
3986 dependencies:3851 dependencies:
3987 p-limit "^3.0.2"3852 p-limit "^3.0.2"
39883853
3989p-timeout@^1.1.1:
3990 version "1.2.1"
3991 resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
3992 integrity sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==
3993 dependencies:
3994 p-finally "^1.0.0"
3995
3996p-try@^2.0.0:3854p-try@^2.0.0:
3997 version "2.2.0"3855 version "2.2.0"
3998 resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"3856 resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
4114 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"3972 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
4115 integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==3973 integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
41163974
4117prepend-http@^1.0.1:
4118 version "1.0.4"
4119 resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
4120 integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==
4121
4122process@^0.11.10:3975process@^0.11.10:
4123 version "0.11.10"3976 version "0.11.10"
4124 resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"3977 resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
4299 resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"4152 resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
4300 integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==4153 integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
43014154
4302resolve-alpn@^1.2.0:4155resolve-alpn@^1.0.0, resolve-alpn@^1.2.0:
4303 version "1.2.1"4156 version "1.2.1"
4304 resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"4157 resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
4305 integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==4158 integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
4641 has-flag "^4.0.0"4494 has-flag "^4.0.0"
46424495
4643swarm-js@^0.1.40:4496swarm-js@^0.1.40:
4644 version "0.1.40"4497 version "0.1.42"
4645 resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99"4498 resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979"
4646 integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==4499 integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==
4647 dependencies:4500 dependencies:
4648 bluebird "^3.5.0"4501 bluebird "^3.5.0"
4649 buffer "^5.0.5"4502 buffer "^5.0.5"
4650 eth-lib "^0.1.26"4503 eth-lib "^0.1.26"
4651 fs-extra "^4.0.2"4504 fs-extra "^4.0.2"
4652 got "^7.1.0"4505 got "^11.8.5"
4653 mime-types "^2.1.16"4506 mime-types "^2.1.16"
4654 mkdirp-promise "^5.0.1"4507 mkdirp-promise "^5.0.1"
4655 mock-fs "^4.1.0"4508 mock-fs "^4.1.0"
4675 resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"4528 resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
4676 integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==4529 integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
46774530
4678timed-out@^4.0.0, timed-out@^4.0.1:4531timed-out@^4.0.1:
4679 version "4.0.1"4532 version "4.0.1"
4680 resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"4533 resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
4681 integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==4534 integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==
4800 resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"4653 resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
4801 integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==4654 integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
48024655
4803type@^2.5.0:4656type@^2.7.2:
4804 version "2.7.2"4657 version "2.7.2"
4805 resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"4658 resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
4806 integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==4659 integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
4813 is-typedarray "^1.0.0"4666 is-typedarray "^1.0.0"
48144667
4815typescript@^4.7.2:4668typescript@^4.7.2:
4816 version "4.7.4"4669 version "4.8.3"
4817 resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"4670 resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88"
4818 integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==4671 integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==
48194672
4820uglify-js@^3.1.4:4673uglify-js@^3.1.4:
4821 version "3.16.3"4674 version "3.17.0"
4822 resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.3.tgz#94c7a63337ee31227a18d03b8a3041c210fd1f1d"4675 resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.0.tgz#55bd6e9d19ce5eef0d5ad17cd1f587d85b180a85"
4823 integrity sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==4676 integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==
48244677
4825ultron@~1.1.0:4678ultron@~1.1.0:
4826 version "1.1.1"4679 version "1.1.1"
4848 integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==4701 integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
48494702
4850update-browserslist-db@^1.0.5:4703update-browserslist-db@^1.0.5:
4851 version "1.0.5"4704 version "1.0.7"
4852 resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38"4705 resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz#16279639cff1d0f800b14792de43d97df2d11b7d"
4853 integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==4706 integrity sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==
4854 dependencies:4707 dependencies:
4855 escalade "^3.1.1"4708 escalade "^3.1.1"
4856 picocolors "^1.0.0"4709 picocolors "^1.0.0"
4862 dependencies:4715 dependencies:
4863 punycode "^2.1.0"4716 punycode "^2.1.0"
48644717
4865url-parse-lax@^1.0.0:
4866 version "1.0.0"
4867 resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
4868 integrity sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==
4869 dependencies:
4870 prepend-http "^1.0.1"
4871
4872url-set-query@^1.0.0:4718url-set-query@^1.0.0:
4873 version "1.0.0"4719 version "1.0.0"
4874 resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339"4720 resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339"
4875 integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==4721 integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==
48764722
4877url-to-options@^1.0.1:
4878 version "1.0.1"
4879 resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
4880 integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==
4881
4882utf-8-validate@^5.0.2:4723utf-8-validate@^5.0.2:
4883 version "5.0.9"4724 version "5.0.9"
4884 resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3"4725 resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3"
4927 version "3.0.1"4768 version "3.0.1"
4928 resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"4769 resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
4929 integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==4770 integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
4930
4931v8-compile-cache@^2.0.3:
4932 version "2.3.0"
4933 resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
4934 integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
49354771
4936varint@^5.0.0:4772varint@^5.0.0:
4937 version "5.0.2"4773 version "5.0.2"