difftreelog
CORE-178
in: master
7 files changed
client/rpc/src/lib.rsdiffbeforeafterboth--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -119,6 +119,15 @@
) -> Result<Option<Collection<AccountId>>>;
#[rpc(name = "unique_collectionStats")]
fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;
+
+ #[rpc(name = "unique_nextSponsored")]
+ fn next_sponsored(
+ &self,
+ collection: CollectionId,
+ account: CrossAccountId,
+ token: TokenId,
+ at: Option<BlockHash>,
+ ) -> Result<Option<u64>>;
}
pub struct Unique<C, P> {
@@ -222,4 +231,5 @@
pass_method!(last_token_id(collection: CollectionId) -> TokenId);
pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);
pass_method!(collection_stats() -> CollectionStats);
+ pass_method!(next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Option<u64>);
}
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -69,7 +69,7 @@
mod eth;
mod sponsorship;
-pub use sponsorship::UniqueSponsorshipHandler;
+pub use sponsorship::{UniqueSponsorshipHandler, UniqueSponsorshipPredict};
pub use eth::sponsoring::UniqueEthSponsorshipHandler;
pub use eth::UniqueErcSupport;
@@ -84,6 +84,12 @@
pub mod weights;
use weights::WeightInfo;
+pub trait SponsorshipPredict<T: Config> {
+ fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>
+ where
+ u64: From<<T as frame_system::Config>::BlockNumber>;
+}
+
decl_error! {
/// Error for non-fungible-token module.
pub enum Error for Module<T: Config> {
pallets/unique/src/sponsorship.rsdiffbeforeafterboth--- a/pallets/unique/src/sponsorship.rs
+++ b/pallets/unique/src/sponsorship.rs
@@ -301,3 +301,80 @@
}
}
}
+
+use crate::SponsorshipPredict;
+use up_data_structs::SponsorshipState;
+pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);
+
+impl<T> SponsorshipPredict<T> for UniqueSponsorshipPredict<T>
+where
+ T: Config,
+{
+ fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>
+ where
+ u64: From<<T as frame_system::Config>::BlockNumber>,
+ {
+ let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;
+
+ // preliminary sponsoring correctness check
+ match collection.sponsorship {
+ SponsorshipState::Disabled | SponsorshipState::Unconfirmed(_) => return None,
+ _ => (),
+ }
+
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match collection.mode {
+ CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
+ }
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return Some((timeout - block_number).into());
+ }
+ return Some(0);
+ }
+
+ let token_exists = match collection.mode {
+ CollectionMode::NFT => {
+ <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))
+ }
+ CollectionMode::Fungible(_) => true,
+ CollectionMode::ReFungible => {
+ <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))
+ }
+ };
+
+ if token_exists {
+ Some(0)
+ } else {
+ None
+ }
+
+ // // existance check
+ // match collection.mode {
+ // CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),
+ // CollectionMode::Fungible(_) => {
+ // <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
+ // }
+ // CollectionMode::ReFungible => {
+ // <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))
+ // }
+ // };
+ }
+}
primitives/rpc/src/lib.rsdiffbeforeafterboth--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -59,5 +59,6 @@
fn last_token_id(collection: CollectionId) -> Result<TokenId>;
fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;
fn collection_stats() -> Result<CollectionStats>;
+ fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>>;
}
}
runtime/common/src/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -69,6 +69,13 @@
fn collection_stats() -> Result<CollectionStats, DispatchError> {
Ok(<pallet_common::Pallet<Runtime>>::collection_stats())
}
+ fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {
+ Ok(<pallet_unique::UniqueSponsorshipPredict<Runtime> as
+ pallet_unique::SponsorshipPredict<Runtime>>::predict(
+ collection,
+ account,
+ token))
+ }
}
impl sp_api::Core<Block> for Runtime {
tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -619,6 +619,10 @@
* Get token variable metadata
**/
variableMetadata: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Bytes>>;
+ /**
+ * nextSponsored transaction
+ **/
+ nextSponsored: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, account: PalletCommonAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<u64>>>;
};
web3: {
/**
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('Check if user is allowed to use collection', [collectionParam, crossAccountParam(), tokenParam], 'Option<u64>'),58 },59 },59};60};6061