difftreelog
Merge pull request #337 from UniqueNetwork/CORE-178
in: master
feature/core-178
9 files changed
client/rpc/src/lib.rsdiffbeforeafterboth120 #[rpc(name = "unique_collectionStats")]120 #[rpc(name = "unique_collectionStats")]121 fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;121 fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;122123 #[rpc(name = "unique_nextSponsored")]124 fn next_sponsored(125 &self,126 collection: CollectionId,127 account: CrossAccountId,128 token: TokenId,129 at: Option<BlockHash>,130 ) -> Result<Option<u64>>;122 #[rpc(name = "unique_effectiveCollectionLimits")]131 #[rpc(name = "unique_effectiveCollectionLimits")]123 fn effective_collection_limits(132 fn effective_collection_limits(124 &self,133 &self,228 pass_method!(last_token_id(collection: CollectionId) -> TokenId);237 pass_method!(last_token_id(collection: CollectionId) -> TokenId);229 pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);238 pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);230 pass_method!(collection_stats() -> CollectionStats);239 pass_method!(collection_stats() -> CollectionStats);240 pass_method!(next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Option<u64>);231 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>);241 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>);232}242}233243pallets/unique/src/lib.rsdiffbeforeafterboth676768mod eth;68mod eth;69mod sponsorship;69mod sponsorship;70pub use sponsorship::UniqueSponsorshipHandler;70pub use sponsorship::{UniqueSponsorshipHandler, UniqueSponsorshipPredict};71pub use eth::sponsoring::UniqueEthSponsorshipHandler;71pub use eth::sponsoring::UniqueEthSponsorshipHandler;727273pub use eth::UniqueErcSupport;73pub use eth::UniqueErcSupport;82pub mod weights;82pub mod weights;83use weights::WeightInfo;83use weights::WeightInfo;8485pub trait SponsorshipPredict<T: Config> {86 fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>87 where88 u64: From<<T as frame_system::Config>::BlockNumber>;89}849085decl_error! {91decl_error! {86 /// Error for non-fungible-token module.92 /// Error for non-fungible-token module.pallets/unique/src/sponsorship.rsdiffbeforeafterboth29 CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MetaUpdatePermission,29 CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MetaUpdatePermission,30 NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId,30 NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId,31};31};32use sp_runtime::traits::Saturating;32use pallet_common::{CollectionHandle};33use pallet_common::{CollectionHandle};33use pallet_evm::account::CrossAccountId;34use pallet_evm::account::CrossAccountId;3435302 }303 }303}304}305306use crate::SponsorshipPredict;307use up_data_structs::SponsorshipState;308pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);309310impl<T> SponsorshipPredict<T> for UniqueSponsorshipPredict<T>311where312 T: Config,313{314 fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>315 where316 u64: From<<T as frame_system::Config>::BlockNumber>,317 {318 let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;319 let _ = collection.sponsorship.sponsor()?;320321 // sponsor timeout322 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;323 let limit = collection324 .limits325 .sponsor_transfer_timeout(match collection.mode {326 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,327 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,328 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,329 });330331 let last_tx_block = match collection.mode {332 CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),333 CollectionMode::Fungible(_) => {334 <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())335 }336 CollectionMode::ReFungible => {337 <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))338 }339 };340341 if let Some(last_tx_block) = last_tx_block {342 return Some(343 last_tx_block344 .saturating_add(limit.into())345 .saturating_sub(block_number)346 .into(),347 );348 }349350 let token_exists = match collection.mode {351 CollectionMode::NFT => {352 <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))353 }354 CollectionMode::Fungible(_) => true,355 CollectionMode::ReFungible => {356 <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))357 }358 };359360 if token_exists {361 Some(0)362 } else {363 None364 }365 }366}304367primitives/rpc/src/lib.rsdiffbeforeafterboth59 fn last_token_id(collection: CollectionId) -> Result<TokenId>;59 fn last_token_id(collection: CollectionId) -> Result<TokenId>;60 fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;60 fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;61 fn collection_stats() -> Result<CollectionStats>;61 fn collection_stats() -> Result<CollectionStats>;62 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>>;62 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;63 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;63 }64 }64}65}runtime/common/src/runtime_apis.rsdiffbeforeafterboth69 fn collection_stats() -> Result<CollectionStats, DispatchError> {69 fn collection_stats() -> Result<CollectionStats, DispatchError> {70 Ok(<pallet_common::Pallet<Runtime>>::collection_stats())70 Ok(<pallet_common::Pallet<Runtime>>::collection_stats())71 }71 }72 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {73 Ok(<pallet_unique::UniqueSponsorshipPredict<Runtime> as74 pallet_unique::SponsorshipPredict<Runtime>>::predict(75 collection,76 account,77 token))78 }727973 fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {80 fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {74 Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))81 Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth623 * Get token variable metadata623 * Get token variable metadata624 **/624 **/625 variableMetadata: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Bytes>>;625 variableMetadata: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Bytes>>;626 /**627 * nextSponsored transaction628 **/629 nextSponsored: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: AccountId | string | Uint8Array | { Substrate: any } | { Ethereum: any } | string | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<u64>>>;626 };630 };627 web3: {631 web3: {628 /**632 /**tests/src/interfaces/unique/definitions.tsdiffbeforeafterboth55 collectionById: fun('Get collection by specified id', [collectionParam], 'Option<UpDataStructsCollection>'),55 collectionById: fun('Get collection by specified id', [collectionParam], 'Option<UpDataStructsCollection>'),56 collectionStats: fun('Get collection stats', [], 'UpDataStructsCollectionStats'),56 collectionStats: fun('Get collection stats', [], 'UpDataStructsCollectionStats'),57 allowed: fun('Check if user is allowed to use collection', [collectionParam, crossAccountParam()], 'bool'),57 allowed: fun('Check if user is allowed to use collection', [collectionParam, crossAccountParam()], 'bool'),58 nextSponsored: fun('Get number of blocks when sponsored transaction is available', [collectionParam, crossAccountParam(), tokenParam], 'Option<u64>'),58 effectiveCollectionLimits: fun('Get effective collection limits', [collectionParam], 'Option<UpDataStructsCollectionLimits>'),59 effectiveCollectionLimits: fun('Get effective collection limits', [collectionParam], 'Option<UpDataStructsCollectionLimits>'),59 },60 },60};61};tests/src/nextSponsoring.test.tsdiffbeforeafterbothno changes
tests/src/util/helpers.tsdiffbeforeafterboth608 });608 });609}609}610611export async function getNextSponsored(612 api: ApiPromise,613 collectionId: number,614 account: string | CrossAccountId,615 tokenId: number,616): Promise<number> {617 return Number((await api.rpc.unique.nextSponsored(collectionId, account, tokenId)).unwrapOr(-1));618}610619611export async function toggleContractAllowlistExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, value = true) {620export async function toggleContractAllowlistExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, value = true) {612 await usingApi(async (api) => {621 await usingApi(async (api) => {