difftreelog
Merge branch 'develop' into chore/fix-warnings
in: master
76 files changed
.docker/Dockerfile-try-runtimediffbeforeafterboth46 echo "Fork from: $REPLICA_FROM\n" && \46 echo "Fork from: $REPLICA_FROM\n" && \47 cargo build --features=try-runtime,${NETWORK}-runtime --release47 cargo build --features=try-runtime,${NETWORK}-runtime --release484849CMD cargo run --features=try-runtime,${NETWORK}-runtime --release -- try-runtime -ltry-runtime::cli=debug --no-spec-check-panic on-runtime-upgrade live --uri $REPLICA_FROM49CMD cargo run --release --features ${NETWORK}-runtime,try-runtime -- try-runtime --runtime target/release/wbuild/${NETWORK}-runtime/${NETWORK}_runtime.compact.compressed.wasm -lruntime=debug -ltry-runtime::cli=debug on-runtime-upgrade --checks live --uri $REPLICA_FROM5050.envdiffbeforeafterboth5STATEMINT_BUILD_BRANCH=release-parachains-v93205STATEMINT_BUILD_BRANCH=release-parachains-v93206ACALA_BUILD_BRANCH=2.11.06ACALA_BUILD_BRANCH=2.11.07MOONBEAM_BUILD_BRANCH=runtime-19017MOONBEAM_BUILD_BRANCH=runtime-19018UNIQUE_MAINNET_BRANCH=release-v9300338UNIQUE_MAINNET_BRANCH=release-v930033-fix-gas-price9UNIQUE_REPLICA_FROM=wss://eu-ws.unique.network:4439UNIQUE_REPLICA_FROM=wss://eu-ws.unique.network:443101011KUSAMA_MAINNET_BRANCH=release-v0.9.3511KUSAMA_MAINNET_BRANCH=release-v0.9.3512STATEMINE_BUILD_BRANCH=release-parachains-v933012STATEMINE_BUILD_BRANCH=release-parachains-v933013KARURA_BUILD_BRANCH=release-karura-2.11.013KARURA_BUILD_BRANCH=release-karura-2.11.014MOONRIVER_BUILD_BRANCH=runtime-200014MOONRIVER_BUILD_BRANCH=runtime-200015QUARTZ_MAINNET_BRANCH=release-v93003415QUARTZ_MAINNET_BRANCH=release-v930034-fix-gas-price16QUARTZ_REPLICA_FROM=wss://eu-ws-quartz.unique.network:44316QUARTZ_REPLICA_FROM=wss://eu-ws-quartz.unique.network:443171718UNQWND_MAINNET_BRANCH=release-v0.9.3018UNQWND_MAINNET_BRANCH=release-v0.9.3019WESTMINT_BUILD_BRANCH=parachains-v933019WESTMINT_BUILD_BRANCH=parachains-v933020OPAL_MAINNET_BRANCH=release-v93003420OPAL_MAINNET_BRANCH=release-v930034-fix-gas-price21OPAL_REPLICA_FROM=wss://eu-ws-opal.unique.network:44321OPAL_REPLICA_FROM=wss://eu-ws-opal.unique.network:443222223POLKADOT_LAUNCH_BRANCH=unique-network23POLKADOT_LAUNCH_BRANCH=unique-network.github/workflows/ci-master.ymldiffbeforeafterboth43 codestyle:43 codestyle:44 uses: ./.github/workflows/codestyle.yml44 uses: ./.github/workflows/codestyle.yml454546 polkadot-types:47 uses: ./.github/workflows/polkadot-types.yml.github/workflows/polkadot-types.ymldiffbeforeafterbothno changes
.github/workflows/schedule-trigger-for-develop-build.ymldiffbeforeafterboth1name: schedule-trigger-for-develop-build1name: schedule-trigger-for-develop-build2on:2on:3 # update the branch ci/develop-scheduler every night3 # update the branch ci/develop-scheduler every night4 schedule:4 # schedule:5 - cron: '0 1 * * *'5 # - cron: '0 1 * * *'6 # or update the branch manually6 # or update the branch manually7 workflow_dispatch:7 workflow_dispatch:8 # pull_request:8 # pull_request:9 # branches: [ 'develop' ]9 # branches: [ 'develop' ]Cargo.lockdiffbeforeafterboth2467[[package]]2467[[package]]2468name = "fc-consensus"2468name = "fc-consensus"2469version = "2.0.0-dev"2469version = "2.0.0-dev"2470source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2470source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2471dependencies = [2471dependencies = [2472 "async-trait",2472 "async-trait",2473 "fc-db",2473 "fc-db",2486[[package]]2486[[package]]2487name = "fc-db"2487name = "fc-db"2488version = "2.0.0-dev"2488version = "2.0.0-dev"2489source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2489source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2490dependencies = [2490dependencies = [2491 "fp-storage",2491 "fp-storage",2492 "kvdb-rocksdb",2492 "kvdb-rocksdb",2505[[package]]2505[[package]]2506name = "fc-mapping-sync"2506name = "fc-mapping-sync"2507version = "2.0.0-dev"2507version = "2.0.0-dev"2508source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2508source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2509dependencies = [2509dependencies = [2510 "fc-db",2510 "fc-db",2511 "fp-consensus",2511 "fp-consensus",2522[[package]]2522[[package]]2523name = "fc-rpc"2523name = "fc-rpc"2524version = "2.0.0-dev"2524version = "2.0.0-dev"2525source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2525source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2526dependencies = [2526dependencies = [2527 "ethereum 0.14.0",2527 "ethereum 0.14.0",2528 "ethereum-types 0.14.1",2528 "ethereum-types 0.14.1",2565[[package]]2565[[package]]2566name = "fc-rpc-core"2566name = "fc-rpc-core"2567version = "1.1.0-dev"2567version = "1.1.0-dev"2568source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2568source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2569dependencies = [2569dependencies = [2570 "ethereum 0.14.0",2570 "ethereum 0.14.0",2571 "ethereum-types 0.14.1",2571 "ethereum-types 0.14.1",2730[[package]]2730[[package]]2731name = "fp-consensus"2731name = "fp-consensus"2732version = "2.0.0-dev"2732version = "2.0.0-dev"2733source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2733source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2734dependencies = [2734dependencies = [2735 "ethereum 0.14.0",2735 "ethereum 0.14.0",2736 "parity-scale-codec 3.2.1",2736 "parity-scale-codec 3.2.1",2742[[package]]2742[[package]]2743name = "fp-ethereum"2743name = "fp-ethereum"2744version = "1.0.0-dev"2744version = "1.0.0-dev"2745source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2745source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2746dependencies = [2746dependencies = [2747 "ethereum 0.14.0",2747 "ethereum 0.14.0",2748 "ethereum-types 0.14.1",2748 "ethereum-types 0.14.1",2757[[package]]2757[[package]]2758name = "fp-evm"2758name = "fp-evm"2759version = "3.0.0-dev"2759version = "3.0.0-dev"2760source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2760source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2761dependencies = [2761dependencies = [2762 "evm",2762 "evm",2763 "frame-support",2763 "frame-support",2771[[package]]2771[[package]]2772name = "fp-evm-mapping"2772name = "fp-evm-mapping"2773version = "0.1.0"2773version = "0.1.0"2774source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2774source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2775dependencies = [2775dependencies = [2776 "frame-support",2776 "frame-support",2777 "sp-core",2777 "sp-core",2780[[package]]2780[[package]]2781name = "fp-rpc"2781name = "fp-rpc"2782version = "3.0.0-dev"2782version = "3.0.0-dev"2783source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2783source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2784dependencies = [2784dependencies = [2785 "ethereum 0.14.0",2785 "ethereum 0.14.0",2786 "ethereum-types 0.14.1",2786 "ethereum-types 0.14.1",2797[[package]]2797[[package]]2798name = "fp-self-contained"2798name = "fp-self-contained"2799version = "1.0.0-dev"2799version = "1.0.0-dev"2800source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2800source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2801dependencies = [2801dependencies = [2802 "ethereum 0.14.0",2802 "ethereum 0.14.0",2803 "frame-support",2803 "frame-support",2810[[package]]2810[[package]]2811name = "fp-storage"2811name = "fp-storage"2812version = "2.0.0"2812version = "2.0.0"2813source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"2813source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2814dependencies = [2814dependencies = [2815 "parity-scale-codec 3.2.1",2815 "parity-scale-codec 3.2.1",2816 "serde",2816 "serde",5682[[package]]5682[[package]]5683name = "pallet-base-fee"5683name = "pallet-base-fee"5684version = "1.0.0"5684version = "1.0.0"5685source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"5685source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"5686dependencies = [5686dependencies = [5687 "fp-evm",5687 "fp-evm",5688 "frame-support",5688 "frame-support",5918[[package]]5918[[package]]5919name = "pallet-ethereum"5919name = "pallet-ethereum"5920version = "4.0.0-dev"5920version = "4.0.0-dev"5921source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"5921source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"5922dependencies = [5922dependencies = [5923 "ethereum 0.14.0",5923 "ethereum 0.14.0",5924 "ethereum-types 0.14.1",5924 "ethereum-types 0.14.1",5946[[package]]5946[[package]]5947name = "pallet-evm"5947name = "pallet-evm"5948version = "6.0.0-dev"5948version = "6.0.0-dev"5949source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"5949source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"5950dependencies = [5950dependencies = [5951 "environmental",5951 "environmental",5952 "evm",5952 "evm",6032[[package]]6032[[package]]6033name = "pallet-evm-precompile-simple"6033name = "pallet-evm-precompile-simple"6034version = "2.0.0-dev"6034version = "2.0.0-dev"6035source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"6035source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"6036dependencies = [6036dependencies = [6037 "fp-evm",6037 "fp-evm",6038 "ripemd",6038 "ripemd",12965 "sp-core",12965 "sp-core",12966 "sp-finality-grandpa",12966 "sp-finality-grandpa",12967 "sp-inherents",12967 "sp-inherents",12968 "sp-io",12968 "sp-keystore",12969 "sp-keystore",12969 "sp-offchain",12970 "sp-offchain",12970 "sp-runtime",12971 "sp-runtime",crates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth143 )143 )144}144}145145146pub fn check_and_count_options(de: &syn::DataEnum) -> syn::Result<usize> {146pub fn check_enum_fields(de: &syn::DataEnum) -> syn::Result<()> {147 let mut count = 0;148 for v in de.variants.iter() {147 for v in de.variants.iter() {149 if !v.fields.is_empty() {148 if !v.fields.is_empty() {150 return Err(syn::Error::new(149 return Err(syn::Error::new(156 v.ident.span(),155 v.ident.span(),157 "Enumeration options should not have an explicit specified value",156 "Enumeration options should not have an explicit specified value",158 ));157 ));159 } else {158 }160 count += 1;161 }162 }159 }163160164 Ok(count)161 Ok(())165}162}166163167pub fn check_repr_u8(name: &syn::Ident, attrs: &[syn::Attribute]) -> syn::Result<()> {164pub fn check_repr_u8(name: &syn::Ident, attrs: &[syn::Attribute]) -> syn::Result<()> {crates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth70) -> syn::Result<proc_macro2::TokenStream> {70) -> syn::Result<proc_macro2::TokenStream> {71 let name = &ast.ident;71 let name = &ast.ident;72 check_repr_u8(name, &ast.attrs)?;72 check_repr_u8(name, &ast.attrs)?;73 check_enum_fields(de)?;73 let docs = extract_docs(&ast.attrs)?;74 let docs = extract_docs(&ast.attrs)?;74 let enum_options = de.variants.iter();75 let enum_options = de.variants.iter();7576node/cli/Cargo.tomldiffbeforeafterboth122git = "https://github.com/paritytech/substrate"122git = "https://github.com/paritytech/substrate"123branch = "polkadot-v0.9.36"123branch = "polkadot-v0.9.36"124125[dependencies.sp-io]126git = "https://github.com/paritytech/substrate"127branch = "polkadot-v0.9.36"124128125[dependencies.sp-finality-grandpa]129[dependencies.sp-finality-grandpa]126git = "https://github.com/paritytech/substrate"130git = "https://github.com/paritytech/substrate"node/cli/src/command.rsdiffbeforeafterboth412 #[cfg(feature = "try-runtime")]412 #[cfg(feature = "try-runtime")]413 Some(Subcommand::TryRuntime(cmd)) => {413 Some(Subcommand::TryRuntime(cmd)) => {414 use std::{future::Future, pin::Pin};414 use std::{future::Future, pin::Pin};415 use sc_executor::{sp_wasm_interface::ExtendedHostFunctions, NativeExecutionDispatch};415416416 let runner = cli.create_runner(cmd)?;417 let runner = cli.create_runner(cmd)?;417418429 Ok((430 Ok((430 match config.chain_spec.runtime_id() {431 match config.chain_spec.runtime_id() {431 #[cfg(feature = "unique-runtime")]432 #[cfg(feature = "unique-runtime")]432 RuntimeId::Unique => Box::pin(cmd.run::<Block, UniqueRuntimeExecutor>(config)),433 RuntimeId::Unique => Box::pin(cmd.run::<Block, ExtendedHostFunctions<434 sp_io::SubstrateHostFunctions,435 <UniqueRuntimeExecutor as NativeExecutionDispatch>::ExtendHostFunctions,436 >>()),433437434 #[cfg(feature = "quartz-runtime")]438 #[cfg(feature = "quartz-runtime")]435 RuntimeId::Quartz => Box::pin(cmd.run::<Block, QuartzRuntimeExecutor>(config)),439 RuntimeId::Quartz => Box::pin(cmd.run::<Block, ExtendedHostFunctions<440 sp_io::SubstrateHostFunctions,441 <QuartzRuntimeExecutor as NativeExecutionDispatch>::ExtendHostFunctions,442 >>()),436443437 RuntimeId::Opal => Box::pin(cmd.run::<Block, OpalRuntimeExecutor>(config)),444 RuntimeId::Opal => Box::pin(cmd.run::<Block, ExtendedHostFunctions<445 sp_io::SubstrateHostFunctions,446 <OpalRuntimeExecutor as NativeExecutionDispatch>::ExtendHostFunctions,447 >>()),438 RuntimeId::Unknown(chain) => return Err(no_runtime_err!(chain).into()),448 RuntimeId::Unknown(chain) => return Err(no_runtime_err!(chain).into()),439 },449 },440 task_manager,450 task_manager,node/cli/src/service.rsdiffbeforeafterboth106106107#[cfg(feature = "unique-runtime")]107#[cfg(feature = "unique-runtime")]108impl NativeExecutionDispatch for UniqueRuntimeExecutor {108impl NativeExecutionDispatch for UniqueRuntimeExecutor {109 /// Only enable the benchmarking host functions when we actually want to benchmark.110 #[cfg(feature = "runtime-benchmarks")]109 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;111 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;112 /// Otherwise we only use the default Substrate host functions.113 #[cfg(not(feature = "runtime-benchmarks"))]114 type ExtendHostFunctions = ();110115111 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {116 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {112 unique_runtime::api::dispatch(method, data)117 unique_runtime::api::dispatch(method, data)119124120#[cfg(feature = "quartz-runtime")]125#[cfg(feature = "quartz-runtime")]121impl NativeExecutionDispatch for QuartzRuntimeExecutor {126impl NativeExecutionDispatch for QuartzRuntimeExecutor {127 /// Only enable the benchmarking host functions when we actually want to benchmark.128 #[cfg(feature = "runtime-benchmarks")]122 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;129 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;130 /// Otherwise we only use the default Substrate host functions.131 #[cfg(not(feature = "runtime-benchmarks"))]132 type ExtendHostFunctions = ();123133124 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {134 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {125 quartz_runtime::api::dispatch(method, data)135 quartz_runtime::api::dispatch(method, data)131}141}132142133impl NativeExecutionDispatch for OpalRuntimeExecutor {143impl NativeExecutionDispatch for OpalRuntimeExecutor {144 /// Only enable the benchmarking host functions when we actually want to benchmark.145 #[cfg(feature = "runtime-benchmarks")]134 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;146 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;147 /// Otherwise we only use the default Substrate host functions.148 #[cfg(not(feature = "runtime-benchmarks"))]149 type ExtendHostFunctions = ();135150136 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {151 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {137 opal_runtime::api::dispatch(method, data)152 opal_runtime::api::dispatch(method, data)pallets/common/src/eth.rsdiffbeforeafterboth127pub struct OptionCrossAddress {127pub struct OptionCrossAddress {128 /// Whether or not this CrossAdress is valid and has meaning.128 /// Whether or not this CrossAdress is valid and has meaning.129 pub status: bool,129 pub status: bool,130 /// The underlying CrossAddress. If the status is false, can be set to whatever.130 /// The underlying CrossAddress value. If the status is false, can be set to whatever.131 pub value: CrossAddress,131 pub value: CrossAddress,132}132}133133pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth283283284/// Ethereum representation of Optional value with CrossAddress.284/// Ethereum representation of Optional value with CrossAddress.285struct OptionCrossAddress {285struct OptionCrossAddress {286 /// TODO: field description286 bool status;287 bool status;288 /// TODO: field description287 CrossAddress value;289 CrossAddress value;288}290}289291pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth228 owner: sub; collection: collection(owner); owner: cross_from_sub;228 owner: sub; collection: collection(owner); owner: cross_from_sub;229 operator: cross_sub;229 operator: cross_sub;230 };230 };231 }: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)}231 }: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?}232232233 allowance_for_all {233 allowance_for_all {234 bench_init!{234 bench_init!{pallets/refungible/src/benchmarking.rsdiffbeforeafterboth22use frame_benchmarking::{benchmarks, account};22use frame_benchmarking::{benchmarks, account};23use pallet_common::{23use pallet_common::{24 bench_init,24 bench_init,25 benchmarking::{create_collection_raw, property_key, property_value, create_data},25 benchmarking::{create_collection_raw, property_key, property_value},26};26};27use sp_core::H160;28use sp_std::prelude::*;27use sp_std::prelude::*;29use up_data_structs::{28use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};30 CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,31 budget::Unlimited,32};332934const SEED: u32 = 1;30const SEED: u32 = 1;353136fn create_max_item_data<CrossAccountId: Ord>(32fn create_max_item_data<T: Config>(37 users: impl IntoIterator<Item = (CrossAccountId, u128)>,33 users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,38) -> CreateItemData<CrossAccountId> {34) -> CreateItemData<T> {39 CreateItemData {35 CreateItemData::<T> {40 users: users36 users: users41 .into_iter()37 .into_iter()42 .collect::<BTreeMap<_, _>>()38 .collect::<BTreeMap<_, _>>()51 sender: &T::CrossAccountId,47 sender: &T::CrossAccountId,52 users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,48 users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,53) -> Result<TokenId, DispatchError> {49) -> Result<TokenId, DispatchError> {54 let data: CreateItemData<T::CrossAccountId> = create_max_item_data(users);50 let data: CreateItemData<T> = create_max_item_data::<T>(users);55 <Pallet<T>>::create_item(&collection, sender, data, &Unlimited)?;51 <Pallet<T>>::create_item(&collection, sender, data, &Unlimited)?;56 Ok(TokenId(<TokensMinted<T>>::get(&collection.id)))52 Ok(TokenId(<TokensMinted<T>>::get(&collection.id)))57}53}83 owner: sub; collection: collection(owner);79 owner: sub; collection: collection(owner);84 sender: cross_from_sub(owner); to: cross_sub;80 sender: cross_from_sub(owner); to: cross_sub;85 };81 };86 let data = (0..b).map(|_| create_max_item_data([(to.clone(), 200)])).collect();82 let data = (0..b).map(|_| create_max_item_data::<T>([(to.clone(), 200)])).collect();87 }: {<Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?}83 }: {<Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?}888489 create_multiple_items_ex_multiple_items {85 create_multiple_items_ex_multiple_items {94 };90 };95 let data = (0..b).map(|t| {91 let data = (0..b).map(|t| {96 bench_init!(to: cross_sub(t););92 bench_init!(to: cross_sub(t););97 create_max_item_data([(to, 200)])93 create_max_item_data::<T>([(to, 200)])98 }).collect();94 }).collect();99 }: {<Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?}95 }: {<Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?}10096104 owner: sub; collection: collection(owner);100 owner: sub; collection: collection(owner);105 sender: cross_from_sub(owner);101 sender: cross_from_sub(owner);106 };102 };107 let data = vec![create_max_item_data((0..b).map(|u| {103 let data = vec![create_max_item_data::<T>((0..b).map(|u| {108 bench_init!(to: cross_sub(u););104 bench_init!(to: cross_sub(u););109 (to, 200)105 (to, 200)110 }))].try_into().unwrap();106 }))].try_into().unwrap();296 owner: sub; collection: collection(owner); owner: cross_from_sub;292 owner: sub; collection: collection(owner); owner: cross_from_sub;297 operator: cross_sub;293 operator: cross_sub;298 };294 };299 }: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)}295 }: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?}300296301 allowance_for_all {297 allowance_for_all {302 bench_init!{298 bench_init!{pallets/refungible/src/erc_token.rsdiffbeforeafterboth43 TotalSupply, weights::WeightInfo,43 TotalSupply, weights::WeightInfo,44};44};454546/// Refungible token handle contains information about token's collection and id47///48/// RefungibleTokenHandle doesn't check token's existance upon creation46pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);49pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);475048#[solidity_interface(name = ERC1633)]51#[solidity_interface(name = ERC1633)]runtime/common/ethereum/sponsoring.rsdiffbeforeafterboth32 Config as FungibleConfig,32 Config as FungibleConfig,33 erc::{UniqueFungibleCall, ERC20Call},33 erc::{UniqueFungibleCall, ERC20Call},34};34};35use pallet_refungible::Config as RefungibleConfig;35use pallet_refungible::{36 Config as RefungibleConfig,37 erc::UniqueRefungibleCall,38 erc_token::{RefungibleTokenHandle, UniqueRefungibleTokenCall},39 RefungibleHandle,40};36use pallet_unique::Config as UniqueConfig;41use pallet_unique::Config as UniqueConfig;37use sp_std::prelude::*;42use sp_std::prelude::*;38use up_data_structs::{CollectionMode, CreateItemData, CreateNftData, TokenId};43use up_data_structs::{44 CollectionMode, CreateItemData, CreateNftData, mapping::TokenAddressMapping, TokenId,45};39use up_sponsorship::SponsorshipHandler;46use up_sponsorship::SponsorshipHandler;4041use crate::{Runtime, runtime_common::sponsoring::*};47use crate::{Runtime, runtime_common::sponsoring::*};4849mod refungible;425043pub type EvmSponsorshipHandler = (51pub type EvmSponsorshipHandler = (44 UniqueEthSponsorshipHandler<Runtime>,52 UniqueEthSponsorshipHandler<Runtime>,53 who: &T::CrossAccountId,61 who: &T::CrossAccountId,54 call_context: &CallContext,62 call_context: &CallContext,55 ) -> Option<T::CrossAccountId> {63 ) -> Option<T::CrossAccountId> {56 let collection_id = map_eth_to_id(&call_context.contract_address)?;64 if let Some(collection_id) = map_eth_to_id(&call_context.contract_address) {57 let collection = <CollectionHandle<T>>::new(collection_id)?;65 let collection = <CollectionHandle<T>>::new(collection_id)?;58 let sponsor = collection.sponsorship.sponsor()?.clone();66 let sponsor = collection.sponsorship.sponsor()?.clone();59 let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;67 let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;106 _ => None,116 _ => None,107 }117 }108 }118 }119 CollectionMode::ReFungible => {120 let call = <UniqueRefungibleCall<T>>::parse(method_id, &mut reader).ok()??;121 refungible::call_sponsor(call, collection, who).map(|()| sponsor)122 }109 CollectionMode::Fungible(_) => {123 CollectionMode::Fungible(_) => {110 let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;124 let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;111 #[allow(clippy::single_match)]112 match call {125 match call {113 UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {126 UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {114 withdraw_transfer::<T>(&collection, who, &TokenId::default())127 withdraw_transfer::<T>(&collection, who, &TokenId::default())126 _ => None,139 _ => None,127 }140 }128 }141 }129 _ => None,130 }?))142 }?))143 } else {144 let (collection_id, token_id) =145 T::EvmTokenAddressMapping::address_to_token(&call_context.contract_address)?;146 let collection = <CollectionHandle<T>>::new(collection_id)?;147 if collection.mode != CollectionMode::ReFungible {148 return None;149 }150 let sponsor = collection.sponsorship.sponsor()?.clone();151 let rft_collection = RefungibleHandle::cast(collection);152 // Token existance isn't checked at this point and should be checked in `withdraw` method.153 let token = RefungibleTokenHandle(rft_collection, token_id);154155 let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;156 let call = <UniqueRefungibleTokenCall<T>>::parse(method_id, &mut reader).ok()??;157 Some(T::CrossAccountId::from_sub(158 refungible::token_call_sponsor(call, token, who).map(|()| sponsor)?,159 ))160 }131 }161 }132}162}163164mod common {165 use super::*;166167 use pallet_common::erc::{CollectionCall};168169 pub fn collection_call_sponsor<T>(170 call: CollectionCall<T>,171 _collection: CollectionHandle<T>,172 _who: &T::CrossAccountId,173 ) -> Option<()>174 where175 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,176 {177 use CollectionCall::*;178179 match call {180 // Readonly181 ERC165Call(_, _)182 | CollectionProperty { .. }183 | CollectionProperties { .. }184 | HasCollectionPendingSponsor185 | CollectionSponsor186 | ContractAddress187 | AllowlistedCross { .. }188 | IsOwnerOrAdminEth { .. }189 | IsOwnerOrAdminCross { .. }190 | CollectionOwner191 | CollectionAdmins192 | CollectionLimits193 | CollectionNestingRestrictedIds194 | CollectionNestingPermissions195 | UniqueCollectionType => None,196197 // Not sponsored198 AddToCollectionAllowList { .. }199 | AddToCollectionAllowListCross { .. }200 | RemoveFromCollectionAllowList { .. }201 | RemoveFromCollectionAllowListCross { .. }202 | AddCollectionAdminCross { .. }203 | RemoveCollectionAdminCross { .. }204 | AddCollectionAdmin { .. }205 | RemoveCollectionAdmin { .. }206 | SetNestingBool { .. }207 | SetNesting { .. }208 | SetCollectionAccess { .. }209 | SetCollectionMintMode { .. }210 | SetOwner { .. }211 | ChangeCollectionOwnerCross { .. }212 | SetCollectionProperty { .. }213 | SetCollectionProperties { .. }214 | DeleteCollectionProperty { .. }215 | DeleteCollectionProperties { .. }216 | SetCollectionSponsor { .. }217 | SetCollectionSponsorCross { .. }218 | SetCollectionLimit { .. }219 | ConfirmCollectionSponsorship220 | RemoveCollectionSponsor => None,221 }222 }223}133224runtime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterbothno changes
runtime/common/runtime_apis.rsdiffbeforeafterboth780780781 #[cfg(feature = "try-runtime")]781 #[cfg(feature = "try-runtime")]782 impl frame_try_runtime::TryRuntime<Block> for Runtime {782 impl frame_try_runtime::TryRuntime<Block> for Runtime {783 fn on_runtime_upgrade() -> (frame_support::pallet_prelude::Weight, frame_support::pallet_prelude::Weight) {783 fn on_runtime_upgrade(checks: bool) -> (frame_support::pallet_prelude::Weight, frame_support::pallet_prelude::Weight) {784 log::info!("try-runtime::on_runtime_upgrade unique-chain.");784 log::info!("try-runtime::on_runtime_upgrade unique-chain.");785 let weight = Executive::try_runtime_upgrade().unwrap();785 let weight = Executive::try_runtime_upgrade(checks).unwrap();786 (weight, crate::config::substrate::RuntimeBlockWeights::get().max_block)786 (weight, crate::config::substrate::RuntimeBlockWeights::get().max_block)787 }787 }788788789 fn execute_block(789 fn execute_block(790 block: Block,790 block: Block,791 state_root_check: bool,791 state_root_check: bool,792 signature_check: bool,792 select: frame_try_runtime::TryStateSelect793 select: frame_try_runtime::TryStateSelect793 ) -> frame_support::pallet_prelude::Weight {794 ) -> frame_support::pallet_prelude::Weight {794 log::info!(795 log::info!(799 select,800 select,800 );801 );801802802 Executive::try_execute_block(block, state_root_check, select).unwrap()803 Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()803 }804 }804 }805 }805 }806 }runtime/opal/Cargo.tomldiffbeforeafterboth91 'pallet-unique-scheduler-v2/try-runtime',91 'pallet-unique-scheduler-v2/try-runtime',92 'pallet-maintenance/try-runtime',92 'pallet-maintenance/try-runtime',93 'pallet-test-utils?/try-runtime',93 'pallet-test-utils?/try-runtime',94 'fp-self-contained/try-runtime',94]95]95std = [96std = [96 'codec/std',97 'codec/std',runtime/quartz/Cargo.tomldiffbeforeafterboth86 'pallet-evm-transaction-payment/try-runtime',86 'pallet-evm-transaction-payment/try-runtime',87 'pallet-evm-migration/try-runtime',87 'pallet-evm-migration/try-runtime',88 'pallet-maintenance/try-runtime',88 'pallet-maintenance/try-runtime',89 'fp-self-contained/try-runtime',89]90]90std = [91std = [91 'codec/std',92 'codec/std',runtime/unique/Cargo.tomldiffbeforeafterboth87 'pallet-evm-transaction-payment/try-runtime',87 'pallet-evm-transaction-payment/try-runtime',88 'pallet-evm-migration/try-runtime',88 'pallet-evm-migration/try-runtime',89 'pallet-maintenance/try-runtime',89 'pallet-maintenance/try-runtime',90 'fp-self-contained/try-runtime',90]91]91std = [92std = [92 'codec/std',93 'codec/std',tests/.eslintrc.jsondiffbeforeafterboth18 "mocha"18 "mocha"19 ],19 ],20 "rules": {20 "rules": {21 "@typescript-eslint/no-floating-promises": [22 "error"23 ],21 "indent": [24 "indent": [22 "error",25 "error",23 2,26 2,tests/package.jsondiffbeforeafterboth11 "@types/chai-subset": "^1.3.3",11 "@types/chai-subset": "^1.3.3",12 "@types/mocha": "^10.0.0",12 "@types/mocha": "^10.0.0",13 "@types/node": "^18.11.2",13 "@types/node": "^18.11.2",14 "@typescript-eslint/eslint-plugin": "^5.40.1",14 "@typescript-eslint/eslint-plugin": "^5.47.0",15 "@typescript-eslint/parser": "^5.40.1",15 "@typescript-eslint/parser": "^5.47.0",16 "chai": "^4.3.6",16 "chai": "^4.3.6",17 "chai-subset": "^1.6.0",17 "chai-subset": "^1.6.0",18 "eslint": "^8.25.0",18 "eslint": "^8.25.0",tests/src/apiConsts.test.tsdiffbeforeafterbothno syntactic changes
tests/src/app-promotion.seqtest.tsdiffbeforeafterbothno syntactic changes
tests/src/approve.test.tsdiffbeforeafterbothno syntactic changes
tests/src/burnItem.test.tsdiffbeforeafterbothno syntactic changes
tests/src/calibrate.tsdiffbeforeafterboth295 }295 }296}296}297297298// eslint-disable-next-line @typescript-eslint/no-floating-promises298(async () => {299(async () => {299 await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {300 await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {300 // Subsequent runs reduce error, as price line is not actually straight, this is a curve301 // Subsequent runs reduce error, as price line is not actually straight, this is a curvetests/src/createCollection.test.tsdiffbeforeafterbothno syntactic changes
tests/src/createMultipleItems.test.tsdiffbeforeafterbothno syntactic changes
tests/src/eth/abi/reFungibleDeprecated.jsondiffbeforeafterboth98 "outputs": [],98 "outputs": [],99 "stateMutability": "nonpayable",99 "stateMutability": "nonpayable",100 "type": "function"100 "type": "function"101 }101 },102 {103 "inputs": [104 { "internalType": "address", "name": "to", "type": "address" },105 { "internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]" }106 ],107 "name": "mintBulk",108 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],109 "stateMutability": "nonpayable",110 "type": "function"111 },112 {113 "inputs": [114 { "internalType": "address", "name": "to", "type": "address" },115 {116 "components": [117 { "internalType": "uint256", "name": "field_0", "type": "uint256" },118 { "internalType": "string", "name": "field_1", "type": "string" }119 ],120 "internalType": "struct Tuple0[]",121 "name": "tokens",122 "type": "tuple[]"123 }124 ],125 "name": "mintBulkWithTokenURI",126 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],127 "stateMutability": "nonpayable",128 "type": "function"129 }102]130]103131tests/src/eth/api/ContractHelpers.soldiffbeforeafterboth183183184/// Ethereum representation of Optional value with CrossAddress.184/// Ethereum representation of Optional value with CrossAddress.185struct OptionCrossAddress {185struct OptionCrossAddress {186 /// TODO: field description186 bool status;187 bool status;188 /// TODO: field description187 CrossAddress value;189 CrossAddress value;188}190}189191tests/src/eth/collectionSponsoring.test.tsdiffbeforeafterboth15// 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/>.161617import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';18import {usingPlaygrounds} from '../util/index';18import {Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../util/index';19import {itEth, expect} from './util';19import {itEth, expect} from './util';202021describe('evm collection sponsoring', () => {21describe('evm nft collection sponsoring', () => {22 let donor: IKeyringPair;22 let donor: IKeyringPair;23 let alice: IKeyringPair;23 let alice: IKeyringPair;24 let nominal: bigint;24 let nominal: bigint;101 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;101 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;102102103 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});103 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});104 let sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});105 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorStruct.sub))).to.be.eq(helper.address.ethToSubstrate(sponsor, true));104 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;106 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;105107106 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});108 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});107109108 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});110 sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});109 expect(sponsorTuple.eth).to.be.eq('0x0000000000000000000000000000000000000000');111 expect(sponsorStruct.eth).to.be.eq('0x0000000000000000000000000000000000000000');110 }));112 }));111113112 [114 [142 expect(nextTokenId).to.be.equal('1');144 expect(nextTokenId).to.be.equal('1');143145144 // Set collection permissions:146 // Set collection permissions:145 const oldPermissions = (await collectionSub.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();147 const oldPermissions = (await collectionSub.getData())!.raw.permissions;146 expect(oldPermissions.mintMode).to.be.false;148 expect(oldPermissions.mintMode).to.be.false;147 expect(oldPermissions.access).to.be.equal('Normal');149 expect(oldPermissions.access).to.be.equal('Normal');148150149 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});151 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});150 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});152 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});151 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});153 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});152154153 const newPermissions = (await collectionSub.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();155 const newPermissions = (await collectionSub.getData())!.raw.permissions;154 expect(newPermissions.mintMode).to.be.true;156 expect(newPermissions.mintMode).to.be.true;155 expect(newPermissions.access).to.be.equal('AllowList');157 expect(newPermissions.access).to.be.equal('AllowList');156158157 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));159 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));158 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));160 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));161 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));159162160 // User can mint token without balance:163 // User can mint token without balance:161 {164 {179182180 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');183 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');181 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);184 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);182 expect(userBalanceAfter).to.be.eq(0n);185 expect(userBalanceAfter).to.be.eq(userBalanceBefore);183 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;186 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;184 }187 }185 }));188 }));316 });319 });317});320});321322describe('evm RFT collection sponsoring', () => {323 let donor: IKeyringPair;324 let alice: IKeyringPair;325 let nominal: bigint;326327 before(async function() {328 await usingPlaygrounds(async (helper, privateKey) => {329 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);330 donor = await privateKey({filename: __filename});331 [alice] = await helper.arrange.createAccounts([100n], donor);332 nominal = helper.balance.getOneTokenNominal();333 });334 });335336 [337 'mintCross',338 'mintWithTokenURI',339 ].map(testCase =>340 itEth(`[${testCase}] sponsors mint transactions`, async ({helper}) => {341 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'spnr', permissions: {mintMode: true}, tokenPropertyPermissions: [342 {key: 'URI', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},343 ]});344345 const owner = await helper.eth.createAccountWithBalance(donor);346 await collection.setSponsor(alice, alice.address);347 await collection.confirmSponsorship(alice);348349 const minter = helper.eth.createAccount();350 const minterCross = helper.ethCrossAccount.fromAddress(minter);351 expect(await helper.balance.getEthereum(minter)).to.equal(0n);352353 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);354 const contract = await helper.ethNativeContract.collection(collectionAddress, 'rft', minter, true);355356 await collection.addToAllowList(alice, {Ethereum: minter});357 await collection.addAdmin(alice, {Ethereum: owner});358 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);359 await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, 'base/')360 .send();361362 let mintingResult;363 let tokenId;364 switch (testCase) {365 case 'mintCross':366 mintingResult = await contract.methods.mintCross(minterCross, []).send();367 break;368 case 'mintWithTokenURI':369 mintingResult = await contract.methods.mintWithTokenURI(minter, 'Test URI').send();370 tokenId = mintingResult.events.Transfer.returnValues.tokenId;371 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');372 break;373 }374375 const events = helper.eth.normalizeEvents(mintingResult.events);376 expect(events).to.deep.include({377 address: collectionAddress,378 event: 'Transfer',379 args: {380 from: '0x0000000000000000000000000000000000000000',381 to: minter,382 tokenId: '1',383 },384 });385 }));386387 [388 'setCollectionSponsorCross',389 'setCollectionSponsor', // Soft-deprecated390 ].map(testCase =>391 itEth(`[${testCase}] can remove collection sponsor`, async ({helper}) => {392 const owner = await helper.eth.createAccountWithBalance(donor);393 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);394395 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});396 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);397 const sponsor = await helper.eth.createAccountWithBalance(donor);398 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);399 const collectionEvm = await helper.ethNativeContract.collection(collectionIdAddress, 'rft', owner, testCase === 'setCollectionSponsor');400401 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;402 result = await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send({from: owner});403 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;404405 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});406 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;407408 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});409410 const sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});411 expect(sponsorStruct.eth).to.be.eq('0x0000000000000000000000000000000000000000');412 }));413414 [415 'setCollectionSponsorCross',416 'setCollectionSponsor', // Soft-deprecated417 ].map(testCase =>418 itEth(`[${testCase}] Can sponsor from evm address via access list`, async ({helper}) => {419 const owner = await helper.eth.createAccountWithBalance(donor);420 const sponsorEth = await helper.eth.createAccountWithBalance(donor);421 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);422423 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Sponsor collection', '1', '1', '');424425 const collectionSub = helper.rft.getCollectionObject(collectionId);426 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');427428 // Set collection sponsor:429 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsorEth : sponsorCrossEth).send({from: owner});430 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;431 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));432 // Account cannot confirm sponsorship if it is not set as a sponsor433 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');434435 // Sponsor can confirm sponsorship:436 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});437 sponsorship = (await collectionSub.getData())!.raw.sponsorship;438 expect(sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));439440 // Create user with no balance:441 const user = helper.eth.createAccount();442 const userCross = helper.ethCrossAccount.fromAddress(user);443 const nextTokenId = await collectionEvm.methods.nextTokenId().call();444 expect(nextTokenId).to.be.equal('1');445446 // Set collection permissions:447 const oldPermissions = (await collectionSub.getData())!.raw.permissions;448 expect(oldPermissions.mintMode).to.be.false;449 expect(oldPermissions.access).to.be.equal('Normal');450451 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});452 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});453 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});454455 const newPermissions = (await collectionSub.getData())!.raw.permissions;456 expect(newPermissions.mintMode).to.be.true;457 expect(newPermissions.access).to.be.equal('AllowList');458459 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));460 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));461 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));462463 // User can mint token without balance:464 {465 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});466 const events = helper.eth.normalizeEvents(result.events);467468 expect(events).to.deep.include({469 address: collectionAddress,470 event: 'Transfer',471 args: {472 from: '0x0000000000000000000000000000000000000000',473 to: user,474 tokenId: '1',475 },476 });477478 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));479 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));480 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));481482 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');483 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);484 expect(userBalanceAfter).to.be.eq(userBalanceBefore);485 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;486 }487 }));488489 [490 'setCollectionSponsorCross',491 'setCollectionSponsor', // Soft-deprecated492 ].map(testCase =>493 itEth(`[${testCase}] Check that collection admin EVM transaction spend money from sponsor eth address`, async ({helper}) => {494 const owner = await helper.eth.createAccountWithBalance(donor);495 const sponsor = await helper.eth.createAccountWithBalance(donor);496 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);497498 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');499500 const collectionSub = helper.rft.getCollectionObject(collectionId);501 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');502 // Set collection sponsor:503 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;504 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();505 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;506 let collectionData = (await collectionSub.getData())!;507 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));508 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');509 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;510511 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});512 collectionData = (await collectionSub.getData())!;513 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));514 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;515 const sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});516 const sponsorSubAddress = helper.address.normalizeSubstrateToChainFormat(helper.address.ethToSubstrate(sponsor));517 const actualSubAddress = helper.address.normalizeSubstrateToChainFormat(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorStruct.sub)));518 expect(actualSubAddress).to.be.equal(sponsorSubAddress);519520 const user = helper.eth.createAccount();521 const userCross = helper.ethCrossAccount.fromAddress(user);522 await collectionEvm.methods.addCollectionAdminCross(userCross).send();523524 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));525 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));526527 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});528 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;529530 const events = helper.eth.normalizeEvents(mintingResult.events);531 const address = helper.ethAddress.fromCollectionId(collectionId);532533 expect(events).to.deep.include({534 address,535 event: 'Transfer',536 args: {537 from: '0x0000000000000000000000000000000000000000',538 to: user,539 tokenId: '1',540 },541 });542 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');543544 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));545 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);546 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));547 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;548 }));549550 itEth('Check that collection admin EVM transaction spend money from sponsor sub address', async ({helper}) => {551 const owner = await helper.eth.createAccountWithBalance(donor);552 const sponsor = alice;553 const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);554555 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');556557 const collectionSub = helper.rft.getCollectionObject(collectionId);558 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, false);559 // Set collection sponsor:560 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;561 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();562 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;563 let collectionData = (await collectionSub.getData())!;564 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(sponsor.address);565 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');566567 await collectionSub.confirmSponsorship(sponsor);568 collectionData = (await collectionSub.getData())!;569 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(sponsor.address);570 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;571 const sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});572 expect(BigInt(sponsorStruct.sub)).to.be.equal(BigInt('0x' + Buffer.from(sponsor.addressRaw).toString('hex')));573574 const user = helper.eth.createAccount();575 const userCross = helper.ethCrossAccount.fromAddress(user);576 await collectionEvm.methods.addCollectionAdminCross(userCross).send();577578 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));579 const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);580581 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});582 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;583584 const events = helper.eth.normalizeEvents(mintingResult.events);585586 expect(events).to.deep.include({587 address: collectionAddress,588 event: 'Transfer',589 args: {590 from: '0x0000000000000000000000000000000000000000',591 to: user,592 tokenId: '1',593 },594 });595 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');596597 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));598 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);599 const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);600 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;601 });602603 itEth('Sponsoring collection from substrate address via access list', async ({helper}) => {604 const owner = await helper.eth.createAccountWithBalance(donor);605 const user = helper.eth.createAccount();606 const userCross = helper.ethCrossAccount.fromAddress(user);607 const sponsor = alice;608 const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);609610 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');611 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, false);612613 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send({from: owner});614615 const collectionSub = helper.rft.getCollectionObject(collectionId);616 await collectionSub.confirmSponsorship(sponsor);617618 const nextTokenId = await collectionEvm.methods.nextTokenId().call();619 expect(nextTokenId).to.be.equal('1');620621 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});622623 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});624 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});625626 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));627 const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);628 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));629630 {631 const nextTokenId = await collectionEvm.methods.nextTokenId().call();632 expect(nextTokenId).to.be.equal('1');633 const mintingResult = await collectionEvm.methods.mintWithTokenURI(634 user,635 'Test URI',636 ).send({from: user});637638 const events = helper.eth.normalizeEvents(mintingResult.events);639640641 expect(events).to.deep.include({642 address: collectionAddress,643 event: 'Transfer',644 args: {645 from: '0x0000000000000000000000000000000000000000',646 to: user,647 tokenId: nextTokenId,648 },649 });650651 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));652 const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);653 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));654655 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');656 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);657 expect(userBalanceAfter).to.be.eq(userBalanceBefore);658 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;659 }660 });661662 itEth('Can reassign collection sponsor', async ({helper}) => {663 const owner = await helper.eth.createAccountWithBalance(donor);664 const sponsorEth = await helper.eth.createAccountWithBalance(donor);665 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);666 const [sponsorSub] = await helper.arrange.createAccounts([100n], donor);667 const sponsorCrossSub = helper.ethCrossAccount.fromKeyringPair(sponsorSub);668669 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');670 const collectionSub = helper.rft.getCollectionObject(collectionId);671 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);672673 // Set and confirm sponsor:674 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossEth).send({from: owner});675 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});676677 // Can reassign sponsor:678 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossSub).send({from: owner});679 const collectionSponsor = (await collectionSub.getData())?.raw.sponsorship;680 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});681 });682683 [684 'transfer',685 'transferCross',686 'transferFrom',687 'transferFromCross',688 ].map(testCase =>689 itEth(`[${testCase}] Check that transfer via EVM spend money from sponsor address`, async ({helper}) => {690 const owner = await helper.eth.createAccountWithBalance(donor);691692 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');693 const sponsor = await helper.eth.createAccountWithBalance(donor);694 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);695 const receiver = await helper.eth.createAccountWithBalance(donor);696 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);697698 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();699 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});700701 const user = await helper.eth.createAccountWithBalance(donor);702 const userCross = helper.ethCrossAccount.fromAddress(user);703 await collectionEvm.methods.addCollectionAdminCross(userCross).send();704705 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});706 const tokenId = result.events.Transfer.returnValues.tokenId;707708 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));709 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));710 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));711712 switch (testCase) {713 case 'transfer':714 await collectionEvm.methods.transfer(receiver, tokenId).send({from: user});715 break;716 case 'transferCross':717 await collectionEvm.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});718 break;719 case 'transferFrom':720 await collectionEvm.methods.transferFrom(user, receiver, tokenId).send({from: user});721 break;722 case 'transferFromCross':723 await collectionEvm.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});724 break;725 }726727 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));728 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);729 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));730 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;731 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));732 expect(userBalanceAfter).to.be.eq(userBalanceBefore);733 }));734});735736describe('evm RFT token sponsoring', () => {737 let donor: IKeyringPair;738739 before(async function() {740 await usingPlaygrounds(async (helper, privateKey) => {741 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);742 donor = await privateKey({filename: __filename});743 });744 });745746 [747 'transfer',748 'transferCross',749 'transferFrom',750 'transferFromCross',751 ].map(testCase =>752 itEth(`[${testCase}] Check that token piece transfer via EVM spend money from sponsor address`, async ({helper}) => {753 const owner = await helper.eth.createAccountWithBalance(donor);754755 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');756 const sponsor = await helper.eth.createAccountWithBalance(donor);757 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);758 const receiver = await helper.eth.createAccountWithBalance(donor);759 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);760761 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();762 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});763764 const user = await helper.eth.createAccountWithBalance(donor);765 const userCross = helper.ethCrossAccount.fromAddress(user);766 await collectionEvm.methods.addCollectionAdminCross(userCross).send();767768 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});769 const tokenId = result.events.Transfer.returnValues.tokenId;770771 const tokenContract = await helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);772 await tokenContract.methods.repartition(2).send();773774 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));775 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));776 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));777778 switch (testCase) {779 case 'transfer':780 await tokenContract.methods.transfer(receiver, 1).send();781 break;782 case 'transferCross':783 await tokenContract.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), 1).send();784 break;785 case 'transferFrom':786 await tokenContract.methods.transferFrom(user, receiver, 1).send();787 break;788 case 'transferFromCross':789 await tokenContract.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), 1).send();790 break;791 }792793 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));794 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);795 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));796 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;797 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));798 expect(userBalanceAfter).to.be.eq(userBalanceBefore);799 }));800801 [802 'approve',803 'approveCross',804 ].map(testCase =>805 itEth(`[${testCase}] Check that approve via EVM spend money from sponsor address`, async ({helper}) => {806 const owner = await helper.eth.createAccountWithBalance(donor);807808 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');809 const sponsor = await helper.eth.createAccountWithBalance(donor);810 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);811 const receiver = await helper.eth.createAccountWithBalance(donor);812 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);813814 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();815 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});816817 const user = await helper.eth.createAccountWithBalance(donor);818 const userCross = helper.ethCrossAccount.fromAddress(user);819 await collectionEvm.methods.addCollectionAdminCross(userCross).send();820821 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});822 const tokenId = result.events.Transfer.returnValues.tokenId;823824 const tokenContract = await helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);825 await tokenContract.methods.repartition(2).send();826827 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));828 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));829 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));830831 switch (testCase) {832 case 'approve':833 await tokenContract.methods.approve(receiver, 1).send();834 break;835 case 'approveCross':836 await tokenContract.methods.approveCross(helper.ethCrossAccount.fromAddress(receiver), 1).send();837 break;838 }839840 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));841 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);842 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));843 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;844 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));845 expect(userBalanceAfter).to.be.eq(userBalanceBefore);846 }));847});318848849tests/src/eth/createFTCollection.test.tsdiffbeforeafterboth32 });32 });33 });33 });343435 // TODO move sponsorship tests to another file:35 // Soft-deprecated36 // Soft-deprecated36 itEth('[eth] Set sponsorship', async ({helper}) => {37 itEth('[eth] Set sponsorship', async ({helper}) => {37 const owner = await helper.eth.createAccountWithBalance(donor);38 const owner = await helper.eth.createAccountWithBalance(donor);94 .methods.isCollectionExist(collectionAddress).call())95 .methods.isCollectionExist(collectionAddress).call())95 .to.be.true;96 .to.be.true;9798 // check collectionOwner:99 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);100 const collectionOwner = await collectionEvm.methods.collectionOwner().call();101 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));96 });102 });9710398 itEth('destroyCollection', async ({helper}) => {104 itEth('destroyCollection', async ({helper}) => {tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth135 .methods.isCollectionExist(collectionAddress).call())135 .methods.isCollectionExist(collectionAddress).call())136 .to.be.true;136 .to.be.true;137138 // check collectionOwner:139 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);140 const collectionOwner = await collectionEvm.methods.collectionOwner().call();141 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));137 });142 });138});143});139144tests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth88 ]);88 ]);89 });89 });9091 // this test will occasionally fail when in async environment.92 itEth.skip('Check collection address exist', async ({helper}) => {93 const owner = await helper.eth.createAccountWithBalance(donor);9495 const expectedCollectionId = +(await helper.callRpc('api.rpc.unique.collectionStats')).created + 1;96 const expectedCollectionAddress = helper.ethAddress.fromCollectionId(expectedCollectionId);97 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);9899 expect(await collectionHelpers.methods100 .isCollectionExist(expectedCollectionAddress)101 .call()).to.be.false;102103 await collectionHelpers.methods104 .createRFTCollection('A', 'A', 'A')105 .send({value: Number(2n * helper.balance.getOneTokenNominal())});106107 expect(await collectionHelpers.methods108 .isCollectionExist(expectedCollectionAddress)109 .call()).to.be.true;110 });11190112 // Soft-deprecated91 // Soft-deprecated113 itEth('[eth] Set sponsorship', async ({helper}) => {92 itEth('[eth] Set sponsorship', async ({helper}) => {167 .methods.isCollectionExist(collectionAddress).call())146 .methods.isCollectionExist(collectionAddress).call())168 .to.be.true;147 .to.be.true;148149 // check collectionOwner:150 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);151 const collectionOwner = await collectionEvm.methods.collectionOwner().call();152 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));169 });153 });170});154});171155tests/src/eth/evmCoder.test.tsdiffbeforeafterbothno syntactic changes
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth167 expect(event.returnValues.to).to.be.equal(receiver);167 expect(event.returnValues.to).to.be.equal(receiver);168168169 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');169 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');170 console.log(await contract.methods.crossOwnerOf(tokenId).call());171 expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);170 expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);172 // TODO: this wont work right now, need release 919000 first171 // TODO: this wont work right now, need release 919000 first173 // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();172 // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();tests/src/eth/proxyContract.test.tsdiffbeforeafterbothno syntactic changes
tests/src/eth/scheduling.test.tsdiffbeforeafterbothno syntactic changes
tests/src/eth/util/index.tsdiffbeforeafterbothno syntactic changes
tests/src/fungible.test.tsdiffbeforeafterbothno syntactic changes
tests/src/inflation.seqtest.tsdiffbeforeafterbothno syntactic changes
tests/src/interfaces/unique/definitions.tsdiffbeforeafterbothno syntactic changes
tests/src/limits.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/collectionProperties.seqtest.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/collectionProperties.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/graphs.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/nest.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/propertyPermissions.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/tokenProperties.seqtest.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/tokenProperties.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nesting/unnest.test.tsdiffbeforeafterbothno syntactic changes
tests/src/nextSponsoring.test.tsdiffbeforeafterboth52 await token.transfer(alice, {Substrate: bob.address});52 await token.transfer(alice, {Substrate: bob.address});53 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);53 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);545455 // Non-existing token 55 // Non-existing token56 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;56 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;57 });57 });585891 await token.transfer(alice, {Substrate: bob.address});91 await token.transfer(alice, {Substrate: bob.address});92 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);92 expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);939394 // Non-existing token 94 // Non-existing token95 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;95 expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;96 });96 });97});97});tests/src/refungible.test.tsdiffbeforeafterbothno syntactic changes
tests/src/removeCollectionAdmin.test.tsdiffbeforeafterbothno syntactic changes
tests/src/rpc.test.tsdiffbeforeafterbothno syntactic changes
tests/src/scheduler.seqtest.tsdiffbeforeafterbothno syntactic changes
tests/src/setCollectionLimits.test.tsdiffbeforeafterbothno syntactic changes
tests/src/setCollectionSponsor.test.tsdiffbeforeafterbothno syntactic changes
tests/src/setPermissions.test.tsdiffbeforeafterbothno syntactic changes
tests/src/transfer.nload.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// 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/>.161617/* eslint-disable @typescript-eslint/no-floating-promises */17import os from 'os';18import os from 'os';18import {IKeyringPair} from '@polkadot/types/types';19import {IKeyringPair} from '@polkadot/types/types';19import {usingPlaygrounds} from './util';20import {usingPlaygrounds} from './util';tests/src/transfer.test.tsdiffbeforeafterbothno syntactic changes
tests/src/transferFrom.test.tsdiffbeforeafterbothno syntactic changes
tests/src/util/globalSetup.tsdiffbeforeafterboth17 // 2. Create donors for test files17 // 2. Create donors for test files18 await fundFilenamesWithRetries(3)18 await fundFilenamesWithRetries(3)19 .then((result) => {19 .then((result) => {20 if (!result) Promise.reject();20 if (!result) throw Error('Some problems with fundFilenamesWithRetries');21 });21 });222223 // 3. Configure App Promotion 23 // 3. Configure App Promotion24 const missingPallets = helper.fetchMissingPalletNames([Pallets.AppPromotion]);24 const missingPallets = helper.fetchMissingPalletNames([Pallets.AppPromotion]);25 if (missingPallets.length === 0) {25 if (missingPallets.length === 0) {26 const superuser = await privateKey('//Alice');26 const superuser = await privateKey('//Alice');38 }38 }39 } catch (error) {39 } catch (error) {40 console.error(error);40 console.error(error);41 Promise.reject();41 throw Error('Error during globalSetup');42 }42 }43 });43 });44};44};tests/src/util/index.tsdiffbeforeafterboth41 else {41 else {42 const actualSeed = getTestSeed(seed.filename);42 const actualSeed = getTestSeed(seed.filename);43 let account = helper.util.fromSeed(actualSeed, ss58Format);43 let account = helper.util.fromSeed(actualSeed, ss58Format);44 // here's to hoping that no 44 // here's to hoping that no45 if (!seed.ignoreFundsPresence && ((helper as any)['balance'] == undefined || await (helper as any).balance.getSubstrate(account.address) < MINIMUM_DONOR_FUND)) {45 if (!seed.ignoreFundsPresence && ((helper as any)['balance'] == undefined || await (helper as any).balance.getSubstrate(account.address) < MINIMUM_DONOR_FUND)) {46 console.warn(`${path.basename(seed.filename)}: Not enough funds present on the filename account. Using the default one as the donor instead.`);46 console.warn(`${path.basename(seed.filename)}: Not enough funds present on the filename account. Using the default one as the donor instead.`);47 account = helper.util.fromSeed('//Alice', ss58Format);47 account = helper.util.fromSeed('//Alice', ss58Format);tests/src/util/playgrounds/types.tsdiffbeforeafterbothno syntactic changes
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth187 this.helper = helper;187 this.helper = helper;188 }188 }189189190 /**190 /**191 * Generates accounts with the specified UNQ token balance 191 * Generates accounts with the specified UNQ token balance192 * @param balances balances for generated accounts. Each balance will be multiplied by the token nominal.192 * @param balances balances for generated accounts. Each balance will be multiplied by the token nominal.193 * @param donor donor account for balances193 * @param donor donor account for balances194 * @returns array of newly created accounts194 * @returns array of newly created accounts195 * @example const [acc1, acc2, acc3] = await createAccounts([0n, 10n, 20n], donor); 195 * @example const [acc1, acc2, acc3] = await createAccounts([0n, 10n, 20n], donor);196 */196 */197 createAccounts = async (balances: bigint[], donor: IKeyringPair): Promise<IKeyringPair[]> => {197 createAccounts = async (balances: bigint[], donor: IKeyringPair): Promise<IKeyringPair[]> => {198 let nonce = await this.helper.chain.getNonce(donor.address);198 let nonce = await this.helper.chain.getNonce(donor.address);199 const wait = new WaitGroup(this.helper);199 const wait = new WaitGroup(this.helper);250 const tokenNominal = this.helper.balance.getOneTokenNominal();250 const tokenNominal = this.helper.balance.getOneTokenNominal();251 for (let i = 0; i < accountsToCreate; i++) {251 for (let i = 0; i < accountsToCreate; i++) {252 if (i === 500) { // if there are too many accounts to create252 if (i === 500) { // if there are too many accounts to create253 await Promise.allSettled(transactions); // wait while first 500 (should be 100 for devnode) tx will be settled 253 await Promise.allSettled(transactions); // wait while first 500 (should be 100 for devnode) tx will be settled254 transactions = []; //254 transactions = []; //255 nonce = await this.helper.chain.getNonce(donor.address); // update nonce 255 nonce = await this.helper.chain.getNonce(donor.address); // update nonce256 }256 }257 const recepient = this.helper.util.fromSeed(mnemonicGenerate());257 const recepient = this.helper.util.fromSeed(mnemonicGenerate());258 accounts.push(recepient);258 accounts.push(recepient);421 return promise;421 return promise;422 }422 }423423424 /**424 /**425 * Wait for specified number of blocks425 * Wait for specified number of blocks426 * @param blocksCount number of blocks to wait426 * @param blocksCount number of blocks to wait427 * @returns 427 * @returns428 */428 */429 async newBlocks(blocksCount = 1, timeout?: number): Promise<void> {429 async newBlocks(blocksCount = 1, timeout?: number): Promise<void> {430 timeout = timeout ?? blocksCount * 60_000;430 timeout = timeout ?? blocksCount * 60_000;431 // eslint-disable-next-line no-async-promise-executor431 // eslint-disable-next-line no-async-promise-executortests/src/util/playgrounds/unique.tsdiffbeforeafterboth2420 if (!event) throw Error('Cannot find transfer in events');2420 if (!event) throw Error('Cannot find transfer in events');2421 }2421 }242224222423 /**2423 /**2424 * Get schedule for recepient of vested transfer2424 * Get schedule for recepient of vested transfer2425 * @param address Substrate address of recipient2425 * @param address Substrate address of recipient2426 * @returns 2426 * @returns2427 */2427 */2428 async getVestingSchedules(address: TSubstrateAccount): Promise<{start: bigint, period: bigint, periodCount: bigint, perPeriod: bigint}[]> {2428 async getVestingSchedules(address: TSubstrateAccount): Promise<{start: bigint, period: bigint, periodCount: bigint, perPeriod: bigint}[]> {2429 const schedule = (await this.helper.callRpc('api.query.vesting.vestingSchedules', [address])).toJSON();2429 const schedule = (await this.helper.callRpc('api.query.vesting.vestingSchedules', [address])).toJSON();2430 return schedule.map((schedule: any) => {2430 return schedule.map((schedule: any) => {tests/src/vesting.test.tsdiffbeforeafterbothno syntactic changes
tests/src/xcm/xcmOpal.test.tsdiffbeforeafterboth287 await helper.wait.newBlocks(3);287 await helper.wait.newBlocks(3);288 288289 // The USDT token never paid fees. Its amount not changed from begin value.289 // The USDT token never paid fees. Its amount not changed from begin value.290 // Also check that xcm transfer has been succeeded 290 // Also check that xcm transfer has been succeeded291 expect((await helper.assets.account(ASSET_ID, alice.address))! == ASSET_AMOUNT).to.be.true;291 expect((await helper.assets.account(ASSET_ID, alice.address))! == ASSET_AMOUNT).to.be.true;292 });292 });293 });293 });tests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth321 await helper.wait.newBlocks(3);321 await helper.wait.newBlocks(3);322 322323 // The USDT token never paid fees. Its amount not changed from begin value.323 // The USDT token never paid fees. Its amount not changed from begin value.324 // Also check that xcm transfer has been succeeded 324 // Also check that xcm transfer has been succeeded325 expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;325 expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;326 });326 });327 });327 });tests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth321 await helper.wait.newBlocks(3);321 await helper.wait.newBlocks(3);322 322323 // The USDT token never paid fees. Its amount not changed from begin value.323 // The USDT token never paid fees. Its amount not changed from begin value.324 // Also check that xcm transfer has been succeeded 324 // Also check that xcm transfer has been succeeded325 expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;325 expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;326 });326 });327 });327 });tests/yarn.lockdiffbeforeafterboth1065 dependencies:1065 dependencies:1066 "@types/node" "*"1066 "@types/node" "*"106710671068"@typescript-eslint/eslint-plugin@^5.40.1":1068"@typescript-eslint/eslint-plugin@^5.47.0":1069 version "5.47.0"1069 version "5.47.0"1070 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz#dadb79df3b0499699b155839fd6792f16897d910"1070 resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz#dadb79df3b0499699b155839fd6792f16897d910"1071 integrity sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==1071 integrity sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==1080 semver "^7.3.7"1080 semver "^7.3.7"1081 tsutils "^3.21.0"1081 tsutils "^3.21.0"108210821083"@typescript-eslint/parser@^5.40.1":1083"@typescript-eslint/parser@^5.47.0":1084 version "5.47.0"1084 version "5.47.0"1085 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.47.0.tgz#62e83de93499bf4b500528f74bf2e0554e3a6c8d"1085 resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.47.0.tgz#62e83de93499bf4b500528f74bf2e0554e3a6c8d"1086 integrity sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==1086 integrity sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==