difftreelog
Merge pull request #158 from usetech-llc/feature/sponsorship-refactor
in: master
Refactor sponsorship logic to reduce cross-crate dependencies
24 files changed
Cargo.lockdiffbeforeafterboth5113 "nft-data-structs",5113 "nft-data-structs",5114 "pallet-aura",5114 "pallet-aura",5115 "pallet-balances",5115 "pallet-balances",5116 "pallet-contract-helpers",5116 "pallet-contracts",5117 "pallet-contracts",5117 "pallet-contracts-primitives",5118 "pallet-contracts-primitives",5118 "pallet-contracts-rpc-runtime-api",5119 "pallet-contracts-rpc-runtime-api",5480 "sp-std",5481 "sp-std",5481]5482]54835484[[package]]5485name = "pallet-contract-helpers"5486version = "0.1.0"5487dependencies = [5488 "frame-support",5489 "frame-system",5490 "pallet-contracts",5491 "parity-scale-codec 2.1.3",5492 "sp-runtime",5493 "sp-std",5494 "up-sponsorship",5495]548254965483[[package]]5497[[package]]5484name = "pallet-contracts"5498name = "pallet-contracts"5871 "sp-io",5885 "sp-io",5872 "sp-runtime",5886 "sp-runtime",5873 "sp-std",5887 "sp-std",5888 "up-sponsorship",5874]5889]587558905876[[package]]5891[[package]]5880 "frame-benchmarking",5895 "frame-benchmarking",5881 "frame-support",5896 "frame-support",5882 "frame-system",5897 "frame-system",5883 "nft-data-structs",5884 "pallet-balances",5898 "pallet-balances",5885 "pallet-contracts",5886 "pallet-nft",5887 "pallet-nft-transaction-payment",5899 "pallet-nft-transaction-payment",5888 "pallet-randomness-collective-flip",5889 "pallet-timestamp",5890 "pallet-transaction-payment",5900 "pallet-transaction-payment",5891 "parity-scale-codec 2.1.3",5901 "parity-scale-codec 2.1.3",5892 "serde",5902 "serde",5903 "frame-benchmarking",5913 "frame-benchmarking",5904 "frame-support",5914 "frame-support",5905 "frame-system",5915 "frame-system",5906 "nft-data-structs",5907 "pallet-balances",5908 "pallet-contracts",5909 "pallet-nft",5910 "pallet-randomness-collective-flip",5911 "pallet-timestamp",5912 "pallet-transaction-payment",5916 "pallet-transaction-payment",5913 "parity-scale-codec 2.1.3",5917 "parity-scale-codec 2.1.3",5914 "serde",5918 "serde",5915 "sp-core",5919 "sp-core",5916 "sp-io",5920 "sp-io",5917 "sp-runtime",5921 "sp-runtime",5918 "sp-std",5922 "sp-std",5923 "up-sponsorship",5919]5924]592059255921[[package]]5926[[package]]5996 "frame-support",6001 "frame-support",5997 "frame-system",6002 "frame-system",5998 "log",6003 "log",5999 "nft-data-structs",6000 "pallet-contracts",6001 "pallet-nft",6002 "pallet-nft-transaction-payment",6003 "parity-scale-codec 2.1.3",6004 "parity-scale-codec 2.1.3",6004 "serde",6005 "serde",6005 "sp-core",6006 "sp-core",6006 "sp-io",6007 "sp-io",6007 "sp-runtime",6008 "sp-runtime",6008 "sp-std",6009 "sp-std",6009 "substrate-test-utils",6010 "substrate-test-utils",6011 "up-sponsorship",6010]6012]601160136012[[package]]6014[[package]]11759source = "registry+https://github.com/rust-lang/crates.io-index"11761source = "registry+https://github.com/rust-lang/crates.io-index"11760checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"11762checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"1176311764[[package]]11765name = "up-sponsorship"11766version = "0.1.0"11767dependencies = [11768 "impl-trait-for-tuples 0.2.1",11769]117611177011762[[package]]11771[[package]]11763name = "url"11772name = "url"Cargo.tomldiffbeforeafterboth3members = [3members = [4 'node/*',4 'node/*',5 'pallets/*',5 'pallets/*',6 'primitives',6 'primitives/*',7 'runtime',7 'runtime',8 'crates/evm-coder',8 'crates/evm-coder',9 'crates/evm-coder-macros',9 'crates/evm-coder-macros',node/cli/Cargo.tomldiffbeforeafterboth284version = '3.0.0'284version = '3.0.0'285285286[dependencies.nft-data-structs]286[dependencies.nft-data-structs]287path="../../primitives"287path="../../primitives/nft"288default-features = false288default-features = false289289290################################################################################290################################################################################pallets/contract-helpers/Cargo.tomldiffbeforeafterbothno changes
pallets/contract-helpers/src/lib.rsdiffbeforeafterbothno changes
pallets/nft-charge-transaction/Cargo.tomldiffbeforeafterboth23frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }23frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }24frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }24frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }25pallet-balances = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }25pallet-balances = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }26pallet-contracts = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }27pallet-timestamp = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }28pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }26pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }29pallet-randomness-collective-flip = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }30sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }27sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }31frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }28frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }32sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }29sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }33sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }30sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }34sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }31sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }353236pallet-nft = { default-features = false, path="../nft" }37pallet-nft-transaction-payment = { default-features = false, path="../nft-transaction-payment" }33pallet-nft-transaction-payment = { default-features = false, path="../nft-transaction-payment" }38nft-data-structs = { default-features = false, path="../../primitives", version = "0.9.0" }393440[features]35[features]41default = ['std']36default = ['std']45 'frame-support/std',40 'frame-support/std',46 'frame-system/std',41 'frame-system/std',47 'pallet-balances/std',42 'pallet-balances/std',48 'pallet-timestamp/std',49 'pallet-randomness-collective-flip/std',50 'pallet-contracts/std',51 'pallet-nft/std',52 'pallet-transaction-payment/std',43 'pallet-transaction-payment/std',53 'pallet-nft-transaction-payment/std',44 'pallet-nft-transaction-payment/std',54 'sp-std/std',45 'sp-std/std',55 'sp-runtime/std',46 'sp-runtime/std',56 'nft-data-structs/std',57 'frame-benchmarking/std',47 'frame-benchmarking/std',58]48]59runtime-benchmarks = ["frame-benchmarking"]49runtime-benchmarks = ["frame-benchmarking"]pallets/nft-charge-transaction/src/lib.rsdiffbeforeafterboth14#[cfg(feature = "runtime-benchmarks")]14#[cfg(feature = "runtime-benchmarks")]15mod benchmarking;15mod benchmarking;1617#[cfg(test)]18mod tests;191620use codec::{Decode, Encode};17use codec::{Decode, Encode};21use frame_support::traits::{ Get};18use frame_support::traits::Get;22use frame_support::{19use frame_support::{23 decl_module, decl_storage,20 decl_module, decl_storage,24 traits::{25 IsSubType, 26 },27 weights::{21 weights::{28 DispatchInfo, PostDispatchInfo, DispatchClass22 DispatchInfo, PostDispatchInfo, DispatchClass29 }23 }37 },31 },38 FixedPointOperand, DispatchResult32 FixedPointOperand, DispatchResult39};33};40use pallet_contracts::chain_extension::UncheckedFrom;41use pallet_transaction_payment::OnChargeTransaction;34use pallet_transaction_payment::OnChargeTransaction;42use sp_std::prelude::*;35use sp_std::prelude::*;4336837684impl<T: Config> ChargeTransactionPayment<T>77impl<T: Config> ChargeTransactionPayment<T>85where78where86 T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo> + IsSubType<pallet_nft::Call<T>> + IsSubType<pallet_contracts::Call<T>>,79 T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>,87 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,80 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,88 T::AccountId: AsRef<[u8]>,89 T::AccountId: UncheckedFrom<T::Hash>,90{81{91 fn traditional_fee(82 fn traditional_fee(92 len: usize,83 len: usize,134 .map(|i| (fee, i));125 .map(|i| (fee, i));135 }126 }136137 // check errors138 let _error = <pallet_nft_transaction_payment::Module<T>>::check_error(who, call);139 match _error {140 Err(_error) => return Err(_error),141 Ok(_error) => {}142 };143127144 // Determine who is paying transaction fee based on ecnomic model128 // Determine who is paying transaction fee based on ecnomic model145 // Parse call to extract collection ID and access collection sponsor 129 // Parse call to extract collection ID and access collection sponsor 156 for ChargeTransactionPayment<T>140 for ChargeTransactionPayment<T>157where141where158 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,142 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,159 T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo> + IsSubType<pallet_nft::Call<T>> + IsSubType<pallet_contracts::Call<T>>,143 T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>,160 T::AccountId: AsRef<[u8]>,161 T::AccountId: UncheckedFrom<T::Hash>,162{144{163 const IDENTIFIER: &'static str = "ChargeTransactionPayment";145 const IDENTIFIER: &'static str = "ChargeTransactionPayment";164 type AccountId = T::AccountId;146 type AccountId = T::AccountId;209 _result: &DispatchResult,191 _result: &DispatchResult,210 ) -> Result<(), TransactionValidityError> {192 ) -> Result<(), TransactionValidityError> {211 let (tip, who, imbalance) = pre;193 let (tip, who, imbalance) = pre;212 let actual_fee = pallet_transaction_payment::Module::<T>::compute_actual_fee(194 let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(213 len as u32,195 len as u32,214 info,196 info,215 post_info,197 post_info,pallets/nft-transaction-payment/Cargo.tomldiffbeforeafterboth22serde = { version = "1.0.119", default-features = false }22serde = { version = "1.0.119", default-features = false }23frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }23frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }24frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }24frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }25pallet-balances = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }26pallet-contracts = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }27pallet-timestamp = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }28pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }25pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }29pallet-randomness-collective-flip = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }30sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }26sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }31frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }27frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }32sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }28sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }33sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }29sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }34sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }30sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }353136pallet-nft = { default-features = false, path="../nft" }37nft-data-structs = { default-features = false, path="../../primitives", version = "0.9.0" }32up-sponsorship = { default-features = false, path = "../../primitives/sponsorship", version = "0.1.0" }383339[features]34[features]40default = ['std']35default = ['std']43 'serde/std',38 'serde/std',44 'frame-support/std',39 'frame-support/std',45 'frame-system/std',40 'frame-system/std',46 'pallet-balances/std',47 'pallet-timestamp/std',48 'pallet-randomness-collective-flip/std',49 'pallet-contracts/std',41 'sp-core/std',50 'pallet-nft/std',42 'sp-io/std',51 'pallet-transaction-payment/std',43 'pallet-transaction-payment/std',52 'sp-std/std',44 'sp-std/std',53 'sp-runtime/std',45 'sp-runtime/std',54 'nft-data-structs/std',55 'frame-benchmarking/std',46 'frame-benchmarking/std',4748 'up-sponsorship/std',56]49]57runtime-benchmarks = ["frame-benchmarking"]50runtime-benchmarks = ["frame-benchmarking"]5851pallets/nft-transaction-payment/src/benchmarking.rsdiffbeforeafterboth1#![cfg(feature = "runtime-benchmarks")]1#![cfg(feature = "runtime-benchmarks")]223use super::*;3use super::*;4use crate::Module as NftTransactionPayment;546use sp_std::prelude::*;5use sp_std::prelude::*;7use frame_system::RawOrigin;6use frame_system::RawOrigin;pallets/nft-transaction-payment/src/lib.rsdiffbeforeafterboth14#[cfg(feature = "runtime-benchmarks")]14#[cfg(feature = "runtime-benchmarks")]15mod benchmarking;15mod benchmarking;1617#[cfg(test)]18mod tests;191620use frame_support::{17use frame_support::{decl_module, decl_storage};21 decl_error, decl_module, decl_storage,22 traits::{23 IsSubType, 24 },25 weights::{26 DispatchInfo27 }28};29use sp_runtime::traits::StaticLookup;30use sp_runtime::{31 traits::{ 32 Hash, Dispatchable,33 },34 transaction_validity::{35 InvalidTransaction, TransactionValidityError,36 },37};38use pallet_contracts::chain_extension::UncheckedFrom;39use sp_std::prelude::*;18use sp_std::prelude::*;40use nft_data_structs::{19use up_sponsorship::SponsorshipHandler;41 CreateItemData,42 CollectionId, CollectionMode, TokenId43};4445type CodeHash<T> = <T as frame_system::Config>::Hash;462047 pub trait Config: frame_system::Config + pallet_contracts::Config + pallet_transaction_payment::Config + pallet_nft::Config {21pub trait Config: frame_system::Config + pallet_transaction_payment::Config {48 }22 type SponsorshipHandler: SponsorshipHandler<Self::AccountId, Self::Call>;4923}50 // Error for non-fungible-token module.51 52 decl_error! {53 /// Error for non-fungible-token module.54 pub enum Error for Module<T: Config> {55 /// No available class ID56 NoAvailableClassId,57 /// No available token ID58 NoAvailableTokenId,59 /// Token(ClassId, TokenId) not found60 TokenNotFound,61 /// Class not found62 CollectionNotFound,63 /// The operator is not the owner of the token and has no permission64 NoPermission,65 /// Arithmetic calculation overflow66 NumOverflow,67 /// Can not destroy class68 /// Total issuance is not 069 CannotDestroyClass,70 }71}722473 decl_storage! {25decl_storage! {74 trait Store for Module<T: Config> as NftTransactionPayment{26 trait Store for Module<T: Config> as NftTransactionPayment{88impl<T: Config> Module<T> 38impl<T: Config> Module<T> {89{9091 pub fn check_error(92 who: &T::AccountId,93 call: &T::Call94 ) -> Result<bool, TransactionValidityError> where 95 T::Call: Dispatchable<Info=DispatchInfo>,96 T::Call: IsSubType<pallet_nft::Call<T>>, 97 T::Call: IsSubType<pallet_contracts::Call<T>>,98 T::AccountId: AsRef<[u8]>,99 T::AccountId: UncheckedFrom<T::Hash>100 {101102 match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {103 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {104 105 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());106 107 let owned_contract = pallet_nft::ContractOwner::<T>::get(called_contract.clone()).as_ref() == Some(who);108 let white_list_enabled = pallet_nft::ContractWhiteListEnabled::<T>::contains_key(called_contract.clone());109 110 if !owned_contract && white_list_enabled {111 if !pallet_nft::ContractWhiteList::<T>::contains_key(called_contract.clone(), who) {112 return Err(InvalidTransaction::Call.into());113 }114 }115 Ok(true)116 },117 _ => { Ok(true) },118 }119 }120121 pub fn withdraw_type(39 pub fn withdraw_type(122 who: &T::AccountId,40 who: &T::AccountId,123 call: &T::Call41 call: &T::Call124 ) -> Option<T::AccountId> where 42 ) -> Option<T::AccountId> {125 T::Call: Dispatchable<Info=DispatchInfo>,126 T::Call: IsSubType<pallet_nft::Call<T>>, 127 T::Call: IsSubType<pallet_contracts::Call<T>>,128 T::AccountId: AsRef<[u8]>,129 T::AccountId: UncheckedFrom<T::Hash>130 {131132 let mut sponsor: Option<T::AccountId> = match IsSubType::<pallet_nft::Call<T>>::is_sub_type(call) {43 T::SponsorshipHandler::get_sponsor(who, call)133 Some(pallet_nft::Call::create_item(collection_id, _owner, _properties)) => {134135 Self::withdraw_create_item(who, collection_id, &_properties)136 },137 Some(pallet_nft::Call::transfer(_new_owner, collection_id, item_id, _value)) => {138139 Self::withdraw_transfer(who, collection_id, item_id)140 },141 Some(pallet_nft::Call::set_variable_meta_data(collection_id, item_id, data)) => {142143 Self::withdraw_set_variable_meta_data(collection_id, item_id, &data)144 },145 _ => None,146 };147148 sponsor = sponsor.or_else(|| match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {149 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {150151 Self::withdraw_contract_call(who, dest)152 },153 Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, _data, salt)) => {154155 Self::withdraw_contract_instantiate(&who, code_hash, salt)156 },157 Some(pallet_contracts::Call::instantiate_with_code(_endowment, _gas_limit, _code, _data, _salt)) => {158159 Self::withdraw_contract_instantiate(&who, &T::Hashing::hash(&_code), _salt)160 },161 _ => None,162 });163164 sponsor165 }44 }166167168169 pub fn withdraw_create_item(170 who: &T::AccountId,171 collection_id: &CollectionId,172 _properties: &CreateItemData,173 ) -> Option<T::AccountId> {174 175 let collection = pallet_nft::CollectionById::<T>::get(collection_id)?;176177 // sponsor timeout178 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;179180 let limit = collection.limits.sponsor_transfer_timeout;181 if pallet_nft::CreateItemBasket::<T>::contains_key((collection_id, &who)) {182 let last_tx_block = pallet_nft::CreateItemBasket::<T>::get((collection_id, &who));183 let limit_time = last_tx_block + limit.into();184 if block_number <= limit_time {185 return None;186 }187 }188 pallet_nft::CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);189190 // check free create limit191 if collection.limits.sponsored_data_size >= (_properties.len() as u32) {192 collection.sponsorship.sponsor()193 .cloned()194 } else {195 None196 }197 }198199 pub fn withdraw_transfer(200 who: &T::AccountId,201 collection_id: &CollectionId,202 item_id: &TokenId,203 ) -> Option<T::AccountId> {204205 let collection = pallet_nft::CollectionById::<T>::get(collection_id)?;206 let limits = pallet_nft::ChainLimit::get();207208 let mut sponsor_transfer = false;209 if collection.sponsorship.confirmed() {210211 let collection_limits = collection.limits.clone();212 let collection_mode = collection.mode.clone();213214 // sponsor timeout215 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;216 sponsor_transfer = match collection_mode {217 CollectionMode::NFT => {218219 // get correct limit220 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {221 collection_limits.sponsor_transfer_timeout222 } else {223 limits.nft_sponsor_transfer_timeout224 };225226 let mut sponsored = true;227 if pallet_nft::NftTransferBasket::<T>::contains_key(collection_id, item_id) {228 let last_tx_block = pallet_nft::NftTransferBasket::<T>::get(collection_id, item_id);229 let limit_time = last_tx_block + limit.into();230 if block_number <= limit_time {231 sponsored = false;232 }233 }234 if sponsored {235 pallet_nft::NftTransferBasket::<T>::insert(collection_id, item_id, block_number);236 }237238 sponsored239 }240 CollectionMode::Fungible(_) => {241242 // get correct limit243 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {244 collection_limits.sponsor_transfer_timeout245 } else {246 limits.fungible_sponsor_transfer_timeout247 };248249 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;250 let mut sponsored = true;251 if pallet_nft::FungibleTransferBasket::<T>::contains_key(collection_id, who) {252 let last_tx_block = pallet_nft::FungibleTransferBasket::<T>::get(collection_id, who);253 let limit_time = last_tx_block + limit.into();254 if block_number <= limit_time {255 sponsored = false;256 }257 }258 if sponsored {259 pallet_nft::FungibleTransferBasket::<T>::insert(collection_id, who, block_number);260 }261262 sponsored263 }264 CollectionMode::ReFungible => {265266 // get correct limit267 let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {268 collection_limits.sponsor_transfer_timeout269 } else {270 limits.refungible_sponsor_transfer_timeout271 };272273 let mut sponsored = true;274 if pallet_nft::ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {275 let last_tx_block = pallet_nft::ReFungibleTransferBasket::<T>::get(collection_id, item_id);276 let limit_time = last_tx_block + limit.into();277 if block_number <= limit_time {278 sponsored = false;279 }280 }281 if sponsored {282 pallet_nft::ReFungibleTransferBasket::<T>::insert(collection_id, item_id, block_number);283 }284285 sponsored286 }287 _ => {288 false289 },290 };291 }292293 if !sponsor_transfer {294 None295 } else {296 collection.sponsorship.sponsor()297 .cloned()298 }299 }300 301 pub fn withdraw_set_variable_meta_data(302 collection_id: &CollectionId,303 item_id: &TokenId,304 data: &Vec<u8>,305 ) -> Option<T::AccountId> {306307 let mut sponsor_metadata_changes = false;308309 let collection = pallet_nft::CollectionById::<T>::get(collection_id)?;310311 if312 collection.sponsorship.confirmed() &&313 // Can't sponsor fungible collection, this tx will be rejected314 // as invalid315 !matches!(collection.mode, CollectionMode::Fungible(_)) &&316 data.len() <= collection.limits.sponsored_data_size as usize317 {318 if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit {319 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;320321 if pallet_nft::VariableMetaDataBasket::<T>::get(collection_id, item_id)322 .map(|last_block| block_number - last_block > rate_limit)323 .unwrap_or(true) 324 {325 sponsor_metadata_changes = true;326 pallet_nft::VariableMetaDataBasket::<T>::insert(collection_id, item_id, block_number);327 }328 }329 }330331 if !sponsor_metadata_changes {332 None333 } else {334 collection.sponsorship.sponsor().cloned()335 }336337 }338339 pub fn withdraw_contract_call(340 who: &T::AccountId,341 dest: &<T::Lookup as StaticLookup>::Source342 ) -> Option<T::AccountId> {343344 let called_contract: T::AccountId = T::Lookup::lookup((dest).clone()).unwrap_or(T::AccountId::default());345346 let owned_contract = pallet_nft::ContractOwner::<T>::get(called_contract.clone()).as_ref() == Some(who);347 let white_list_enabled = pallet_nft::ContractWhiteListEnabled::<T>::contains_key(called_contract.clone());348 349 // ???350 if !owned_contract && white_list_enabled {351 if !pallet_nft::ContractWhiteList::<T>::contains_key(called_contract.clone(), who) {352 return Some(who.clone())353 // return Err(InvalidTransaction::Call.into());354 }355 }356357 let mut sponsor_transfer = false;358 if pallet_nft::ContractSponsoringRateLimit::<T>::contains_key(called_contract.clone()) {359 let last_tx_block = pallet_nft::ContractSponsorBasket::<T>::get((&called_contract, &who));360 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;361 let rate_limit = pallet_nft::ContractSponsoringRateLimit::<T>::get(&called_contract);362 let limit_time = last_tx_block + rate_limit;363364 if block_number >= limit_time {365 pallet_nft::ContractSponsorBasket::<T>::insert((called_contract.clone(), who.clone()), block_number);366 sponsor_transfer = true;367 }368 } else {369 sponsor_transfer = false;370 }371 372 if sponsor_transfer {373 if pallet_nft::ContractSelfSponsoring::<T>::contains_key(called_contract.clone()) {374 if pallet_nft::ContractSelfSponsoring::<T>::get(called_contract.clone()) {375 return Some(called_contract);376 }377 }378 }379380 None381 }382383 pub fn withdraw_contract_instantiate(384 who: &T::AccountId,385 code_hash: &CodeHash<T>,386 salt: &[u8],387 ) -> Option<T::AccountId> where388 T::AccountId: AsRef<[u8]>,389 T::AccountId: UncheckedFrom<T::Hash>390 {391392 let new_contract_address = <pallet_contracts::Pallet<T>>::contract_address(393 &who,394 code_hash,395 salt,396 );397 pallet_nft::ContractOwner::<T>::insert(new_contract_address.clone(), who.clone());398399 None400 }401}45}pallets/nft-transaction-payment/src/tests.rsdiffbeforeafterbothno changes
pallets/nft/Cargo.tomldiffbeforeafterboth30 'pallet-transaction-payment/std',30 'pallet-transaction-payment/std',31 'fp-evm/std',31 'fp-evm/std',32 'nft-data-structs/std',32 'nft-data-structs/std',33 'up-sponsorship/std',33 'sp-std/std',34 'sp-std/std',34 'sp-api/std',35 'sp-api/std',35 'sp-runtime/std',36 'sp-runtime/std',135136136[dependencies.nft-data-structs]137[dependencies.nft-data-structs]137default-features = false138default-features = false138path = '../../primitives'139path = '../../primitives/nft'139version = '0.9.0'140version = '0.9.0'141142[dependencies.up-sponsorship]143default-features = false144path = '../../primitives/sponsorship'145version = '0.1.0'140146141147142[dependencies]148[dependencies]pallets/nft/src/lib.rsdiffbeforeafterboth505051mod default_weights;51mod default_weights;52mod eth;52mod eth;53mod sponsorship;54pub use sponsorship::NftSponsorshipHandler;535554pub use eth::NftErcSupport;56pub use eth::NftErcSupport;55pub use eth::account::*;57pub use eth::account::*;344 /// Collection id (controlled?2), token id (controlled?2)346 /// Collection id (controlled?2), token id (controlled?2)345 pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber> = None;347 pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber> = None;346 347 //#region Contract Sponsorship and Ownership348 /// Contract address (real)349 pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => Option<T::AccountId>;350 /// Contract address (real)351 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;352 /// (Contract address(real), caller (real))353 pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;354 /// Contract address (real)355 pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;356 /// Contract address (real)357 pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 358 /// Contract address (real) => Whitelisted user (controlled?3)359 pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) T::AccountId => bool; 360 //#endregion361 }348 }362 add_extra_genesis {349 add_extra_genesis {363 build(|config: &GenesisConfig<T>| {350 build(|config: &GenesisConfig<T>| {1236 Ok(())1223 Ok(())1237 }1224 }12381239 /// Enable smart contract self-sponsoring.1240 /// 1241 /// # Permissions1242 /// 1243 /// * Contract Owner1244 /// 1245 /// # Arguments1246 /// 1247 /// * contract address1248 /// * enable flag1249 /// 1250 #[weight = <T as Config>::WeightInfo::enable_contract_sponsoring()]1251 #[transactional]1252 pub fn enable_contract_sponsoring(1253 origin,1254 contract_address: T::AccountId,1255 enable: bool1256 ) -> DispatchResult {12571258 let sender = ensure_signed(origin)?;12591260 #[cfg(feature = "runtime-benchmarks")]1261 <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());12621263 Self::ensure_contract_owned(sender, &contract_address)?;12641265 <ContractSelfSponsoring<T>>::insert(contract_address, enable);1266 Ok(())1267 }12681269 /// Set the rate limit for contract sponsoring to specified number of blocks.1270 /// 1271 /// If not set (has the default value of 0 blocks), the sponsoring will be disabled. 1272 /// If set to the number B (for blocks), the transactions will be sponsored with a rate 1273 /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid 1274 /// from contract endowment if there are at least B blocks between such transactions. 1275 /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.1276 /// 1277 /// # Permissions1278 /// 1279 /// * Contract Owner1280 /// 1281 /// # Arguments1282 /// 1283 /// -`contract_address`: Address of the contract to sponsor1284 /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed1285 /// 1286 #[weight = <T as Config>::WeightInfo::set_contract_sponsoring_rate_limit()]1287 #[transactional]1288 pub fn set_contract_sponsoring_rate_limit(1289 origin,1290 contract_address: T::AccountId,1291 rate_limit: T::BlockNumber1292 ) -> DispatchResult {1293 let sender = ensure_signed(origin)?;12941295 #[cfg(feature = "runtime-benchmarks")]1296 <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());12971298 Self::ensure_contract_owned(sender, &contract_address)?;1299 <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);1300 Ok(())1301 }13021303 /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.1304 /// 1305 /// # Permissions1306 /// 1307 /// * Address that deployed smart contract.1308 /// 1309 /// # Arguments1310 /// 1311 /// -`contract_address`: Address of the contract.1312 /// 1313 /// - `enable`: . 1314 #[weight = <T as Config>::WeightInfo::toggle_contract_white_list()]1315 #[transactional]1316 pub fn toggle_contract_white_list(1317 origin,1318 contract_address: T::AccountId,1319 enable: bool1320 ) -> DispatchResult {1321 let sender = ensure_signed(origin)?;13221323 #[cfg(feature = "runtime-benchmarks")]1324 <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());13251326 Self::ensure_contract_owned(sender, &contract_address)?;1327 if enable {1328 <ContractWhiteListEnabled<T>>::insert(contract_address, true);1329 } else {1330 <ContractWhiteListEnabled<T>>::remove(contract_address);1331 }1332 Ok(())1333 }1334 1335 /// Add an address to smart contract white list.1336 /// 1337 /// # Permissions1338 /// 1339 /// * Address that deployed smart contract.1340 /// 1341 /// # Arguments1342 /// 1343 /// -`contract_address`: Address of the contract.1344 ///1345 /// -`account_address`: Address to add.1346 #[weight = <T as Config>::WeightInfo::add_to_contract_white_list()]1347 #[transactional]1348 pub fn add_to_contract_white_list(1349 origin,1350 contract_address: T::AccountId,1351 account_address: T::AccountId1352 ) -> DispatchResult {1353 let sender = ensure_signed(origin)?;13541355 #[cfg(feature = "runtime-benchmarks")]1356 <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());1357 1358 Self::ensure_contract_owned(sender, &contract_address)?; 1359 <ContractWhiteList<T>>::insert(contract_address, account_address, true);1360 Ok(())1361 }13621363 /// Remove an address from smart contract white list.1364 /// 1365 /// # Permissions1366 /// 1367 /// * Address that deployed smart contract.1368 /// 1369 /// # Arguments1370 /// 1371 /// -`contract_address`: Address of the contract.1372 ///1373 /// -`account_address`: Address to remove.1374 #[weight = <T as Config>::WeightInfo::remove_from_contract_white_list()]1375 #[transactional]1376 pub fn remove_from_contract_white_list(1377 origin,1378 contract_address: T::AccountId,1379 account_address: T::AccountId1380 ) -> DispatchResult {1381 let sender = ensure_signed(origin)?;13821383 #[cfg(feature = "runtime-benchmarks")]1384 <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());13851386 Self::ensure_contract_owned(sender, &contract_address)?;1387 <ContractWhiteList<T>>::remove(contract_address, account_address);1388 Ok(())1389 }139012251391 #[weight = <T as Config>::WeightInfo::set_collection_limits()]1226 #[weight = <T as Config>::WeightInfo::set_collection_limits()]1392 #[transactional]1227 #[transactional]2403 Ok(())2238 Ok(())2404 }2239 }2405 2406 fn ensure_contract_owned(account: T::AccountId, contract: &T::AccountId) -> DispatchResult {2407 ensure!(<ContractOwner<T>>::get(contract) == Some(account), Error::<T>::NoPermission);24082409 Ok(())2410 }2411}2240}241222412413sp_api::decl_runtime_apis! {2242sp_api::decl_runtime_apis! {pallets/nft/src/sponsorship.rsdiffbeforeafterbothno changes
pallets/scheduler/Cargo.tomldiffbeforeafterboth14codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }14codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }15frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }15frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }16frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }16frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }17pallet-contracts = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }18sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }17sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }19sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }18sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }20sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }19sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }21frame-benchmarking = { default-features = false, version = '3.0.0', optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }20frame-benchmarking = { default-features = false, version = '3.0.0', optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.3' }222123pallet-nft-transaction-payment = { default-features = false, path = "../nft-transaction-payment" }22up-sponsorship = { default-features = false, path = "../../primitives/sponsorship", version = "0.1.0" }24pallet-nft = { default-features = false, path = "../nft" }25nft-data-structs = { path = '../../primitives', default-features = false }26log = { version = "0.4.14", default-features = false }23log = { version = "0.4.14", default-features = false }272428[dev-dependencies]25[dev-dependencies]37 "frame-benchmarking/std",34 "frame-benchmarking/std",38 "frame-support/std",35 "frame-support/std",39 "frame-system/std",36 "frame-system/std",40 "pallet-nft-transaction-payment/std",41 "pallet-nft/std",42 "pallet-contracts/std",43 "nft-data-structs/std",37 "up-sponsorship/std",44 "sp-io/std",38 "sp-io/std",45 "sp-std/std",39 "sp-std/std",46 "log/std",40 "log/std",pallets/scheduler/src/lib.rsdiffbeforeafterboth64 weights::{GetDispatchInfo, Weight},64 weights::{GetDispatchInfo, Weight},65};65};66use frame_system::{self as system, ensure_signed};66use frame_system::{self as system, ensure_signed};67use pallet_nft::*;67pub use weights::WeightInfo;68// use pallet_nft_transaction_payment::{self as nft_transaction_payment};69use nft_data_structs::*;68use up_sponsorship::SponsorshipHandler;70pub use weights::WeightInfo;716972/// Our pallet's configuration trait. All our types and constants go in here. If the70/// Our pallet's configuration trait. All our types and constants go in here. If the73/// pallet is dependent on specific other pallets, then their configuration traits71/// pallet is dependent on specific other pallets, then their configuration traits103 type MaxScheduledPerBlock: Get<u32>;101 type MaxScheduledPerBlock: Get<u32>;104102105 /// Sponsoring function103 /// Sponsoring function106 type Sponsoring: SponsoringResolve<Self::AccountId, <Self as Config>::Call>;104 type SponsorshipHandler: SponsorshipHandler<Self::AccountId, <Self as Config>::Call>;107105108 /// Weight information for extrinsics in this pallet.106 /// Weight information for extrinsics in this pallet.109 type WeightInfo: WeightInfo;107 type WeightInfo: WeightInfo;405 s.origin.clone()403 s.origin.clone()406 ).into();404 ).into();407 let sender = ensure_signed(origin).unwrap_or(T::AccountId::default());405 let sender = ensure_signed(origin).unwrap_or(T::AccountId::default());408 let who_will_pay = T::Sponsoring::resolve(&sender, &s.call.clone()).unwrap_or(406 let who_will_pay = T::SponsorshipHandler::get_sponsor(&sender, &s.call).unwrap_or(sender);409 sender);410 let sponsor = T::PalletsOrigin::from(system::RawOrigin::Signed(who_will_pay));407 let sponsor = T::PalletsOrigin::from(system::RawOrigin::Signed(who_will_pay));411 let r = s.call.clone().dispatch(sponsor.into());408 let r = s.call.clone().dispatch(sponsor.into());primitives/Cargo.tomldiffbeforeafterbothno changes
primitives/nft/Cargo.tomldiffbeforeafterbothno changes
primitives/nft/src/lib.rsdiffbeforeafterbothno changes
primitives/sponsorship/Cargo.tomldiffbeforeafterbothno changes
primitives/sponsorship/src/lib.rsdiffbeforeafterbothno changes
primitives/src/lib.rsdiffbeforeafterbothno changes
runtime/Cargo.tomldiffbeforeafterboth46 'pallet-contracts/std',46 'pallet-contracts/std',47 'pallet-contracts-primitives/std',47 'pallet-contracts-primitives/std',48 'pallet-contracts-rpc-runtime-api/std',48 'pallet-contracts-rpc-runtime-api/std',49 'pallet-contract-helpers/std',49 'pallet-randomness-collective-flip/std',50 'pallet-randomness-collective-flip/std',50 'pallet-sudo/std',51 'pallet-sudo/std',51 'pallet-timestamp/std',52 'pallet-timestamp/std',372[dependencies]373[dependencies]373pallet-nft = { path = '../pallets/nft', default-features = false, version = '3.0.0' }374pallet-nft = { path = '../pallets/nft', default-features = false, version = '3.0.0' }374pallet-inflation = { path = '../pallets/inflation', default-features = false, version = '3.0.0' }375pallet-inflation = { path = '../pallets/inflation', default-features = false, version = '3.0.0' }375nft-data-structs = { path = '../primitives', default-features = false, version = '0.9.0' }376nft-data-structs = { path = '../primitives/nft', default-features = false, version = '0.9.0' }376pallet-scheduler = { path = '../pallets/scheduler', default-features = false, version = '3.0.0' }377pallet-scheduler = { path = '../pallets/scheduler', default-features = false, version = '3.0.0' }378pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' }377pallet-nft-transaction-payment = { path = '../pallets/nft-transaction-payment', default-features = false, version = '3.0.0' }379pallet-nft-transaction-payment = { path = '../pallets/nft-transaction-payment', default-features = false, version = '3.0.0' }378pallet-nft-charge-transaction = { path = '../pallets/nft-charge-transaction', default-features = false, version = '3.0.0' }380pallet-nft-charge-transaction = { path = '../pallets/nft-charge-transaction', default-features = false, version = '3.0.0' }379381runtime/src/lib.rsdiffbeforeafterboth734 }734 }735}735}736737type SponsorshipHandler = (738 pallet_nft::NftSponsorshipHandler<Runtime>,739 pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,740);736741737impl pallet_scheduler::Config for Runtime {742impl pallet_scheduler::Config for Runtime {738 type Event = Event;743 type Event = Event;742 type MaximumWeight = MaximumSchedulerWeight;747 type MaximumWeight = MaximumSchedulerWeight;743 type ScheduleOrigin = EnsureSigned<AccountId>;748 type ScheduleOrigin = EnsureSigned<AccountId>;744 type MaxScheduledPerBlock = MaxScheduledPerBlock;749 type MaxScheduledPerBlock = MaxScheduledPerBlock;745 type Sponsoring = Sponsoring;750 type SponsorshipHandler = SponsorshipHandler;746 type WeightInfo = ();751 type WeightInfo = ();747}752}748753749impl pallet_nft_transaction_payment::Config for Runtime {754impl pallet_nft_transaction_payment::Config for Runtime {755 type SponsorshipHandler = SponsorshipHandler;750}756}751757752impl pallet_nft_charge_transaction::Config for Runtime {758impl pallet_nft_charge_transaction::Config for Runtime {}753}759760impl pallet_contract_helpers::Config for Runtime {}754761755construct_runtime!(762construct_runtime!(756 pub enum Runtime where763 pub enum Runtime where791 Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>},798 Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>},792 NftPayment: pallet_nft_transaction_payment::{Pallet, Call, Storage},799 NftPayment: pallet_nft_transaction_payment::{Pallet, Call, Storage},793 Charging: pallet_nft_charge_transaction::{Pallet, Call, Storage },800 Charging: pallet_nft_charge_transaction::{Pallet, Call, Storage },801 ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage},794 }802 }795);803);796804829 system::CheckNonce<Runtime>,837 system::CheckNonce<Runtime>,830 system::CheckWeight<Runtime>,838 system::CheckWeight<Runtime>,831 pallet_nft_charge_transaction::ChargeTransactionPayment<Runtime>,839 pallet_nft_charge_transaction::ChargeTransactionPayment<Runtime>,840 pallet_contract_helpers::ContractHelpersExtension<Runtime>,832);841);833/// Unchecked extrinsic type as expected by this runtime.842/// Unchecked extrinsic type as expected by this runtime.834pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;843pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;