Skip to content

Commit

Permalink
Merge branch 'feat/nft-header-info-rpc' of github.com:futureversecom/…
Browse files Browse the repository at this point in the history
…trn-seed into feat/nft-header-info-rpc
  • Loading branch information
KarishmaBothara committed Mar 7, 2024
2 parents 5619ded + a4ed0e9 commit b1a0eef
Show file tree
Hide file tree
Showing 25 changed files with 257 additions and 459 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/generate-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Generate Pallet Documentation

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
pull-requests: write
contents: write

on:
workflow_dispatch:
inputs:
branch:
description: 'Branch name; do not use `main`'
required: true
pallets:
description: 'Pallet names; e.g. `pallet-futurepass`'
required: true

jobs:
build-docs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
fetch-depth: 0

- uses: dtolnay/[email protected]

- name: Install toolchain
run: rustup show

- name: Generate Documentation
run: cargo doc -p ${{ github.event.inputs.pallet_name }}

- name: Zip Documentation
run: zip -r ${GITHUB_WORKSPACE}/${{ github.event.inputs.pallet_name }}-docs.zip ./target/doc

- name: Upload Pallet Doc as Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ github.event.inputs.pallet_name }}-docs.zip
path: ${{ github.workspace }}/${{ github.event.inputs.pallet_name }}-docs.zip
2 changes: 1 addition & 1 deletion evm-precompiles/erc721/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use frame_support::{
traits::OriginTrait,
};
use pallet_evm::{Context, ExitReason, PrecompileSet};
use pallet_nft::traits::NFTExt;
use seed_pallet_common::NFTExt;
use sp_core::{H160, H256, U256};
use sp_runtime::{traits::SaturatedConversion, BoundedVec};
use sp_std::{marker::PhantomData, vec, vec::Vec};
Expand Down
92 changes: 79 additions & 13 deletions pallet/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ use frame_support::{
};
use frame_system::Config;
use scale_info::TypeInfo;
use sp_core::{bounded::BoundedVec, H160, U256};
use sp_std::{fmt::Debug, vec::Vec};

use seed_primitives::{
ethy::{EventClaimId, EventProofId},
AssetId, Balance, CollectionUuid, MetadataScheme, RoyaltiesSchedule, SerialNumber, TokenId,
AssetId, Balance, CollectionUuid, MetadataScheme, OriginChain, RoyaltiesSchedule, SerialNumber,
TokenCount, TokenId, TokenLockReason,
};
use sp_core::{bounded::BoundedVec, H160, U256};
use sp_std::{fmt::Debug, vec::Vec};

#[cfg(feature = "std")]
pub mod test_utils;
Expand Down Expand Up @@ -418,14 +418,87 @@ pub trait ExtrinsicChecker {
fn check_extrinsic(call: &Self::Call, extra: &Self::Extra) -> Self::Result;
}

pub trait NFTExt {
type AccountId: Debug + PartialEq + Clone;
type StringLimit: Get<u32>;

/// Mint a token in a specified collection
fn do_mint(
origin: Self::AccountId,
collection_id: CollectionUuid,
quantity: TokenCount,
token_owner: Option<Self::AccountId>,
) -> DispatchResult;

/// Transfer a token from origin to new_owner
fn do_transfer(
origin: Self::AccountId,
collection_id: CollectionUuid,
serial_numbers: Vec<SerialNumber>,
new_owner: Self::AccountId,
) -> DispatchResult;

/// Create a new collection
fn do_create_collection(
owner: Self::AccountId,
name: BoundedVec<u8, Self::StringLimit>,
initial_issuance: TokenCount,
max_issuance: Option<TokenCount>,
token_owner: Option<Self::AccountId>,
metadata_scheme: MetadataScheme,
royalties_schedule: Option<RoyaltiesSchedule<Self::AccountId>>,
origin_chain: OriginChain,
) -> Result<CollectionUuid, DispatchError>;

/// Returns Some(token_owner) for a token if the owner exists
fn get_token_owner(token_id: &TokenId) -> Option<Self::AccountId>;

/// Returns collection current issuance and max issuance
fn get_collection_issuance(
collection_id: CollectionUuid,
) -> Result<(TokenCount, Option<TokenCount>), DispatchError>;

/// Return the RoyaltiesSchedule if it exists for a collection
/// Returns an error if the collection does not exist
fn get_royalties_schedule(
collection_id: CollectionUuid,
) -> Result<Option<RoyaltiesSchedule<Self::AccountId>>, DispatchError>;

/// Enable XLS20 compatibility for a collection
/// who must be collection owner
fn enable_xls20_compatibility(
who: Self::AccountId,
collection_id: CollectionUuid,
) -> DispatchResult;

/// Returns the next collection_uuid
fn next_collection_uuid() -> Result<CollectionUuid, DispatchError>;

/// Increments the collection_uuid
fn increment_collection_uuid() -> DispatchResult;

/// Returns the token lock status of a token
fn get_token_lock(token_id: TokenId) -> Option<TokenLockReason>;

/// Sets the token lock status of a token
/// who must own the token
fn set_token_lock(
token_id: TokenId,
lock_reason: TokenLockReason,
who: Self::AccountId,
) -> DispatchResult;

/// Remove a token lock without performing checks
fn remove_token_lock(token_id: TokenId);
}

pub trait SFTExt {
type AccountId: Debug + PartialEq + Clone;
type MaxSerialsPerMint: Get<u32>;

fn do_transfer(
origin: Self::AccountId,
collection_id: CollectionUuid,
serial_numbers: BoundedVec<(SerialNumber, Balance), Self::MaxSerialsPerMint>,
serial_numbers: Vec<(SerialNumber, Balance)>,
new_owner: Self::AccountId,
) -> DispatchResult;

Expand All @@ -438,13 +511,6 @@ pub trait SFTExt {
who: &Self::AccountId,
) -> DispatchResult;

fn transfer_reserved_balance(
token_id: TokenId,
amount: Balance,
from: &Self::AccountId,
to: &Self::AccountId,
) -> DispatchResult;

fn get_royalties_schedule(
collection_id: CollectionUuid,
) -> Result<Option<RoyaltiesSchedule<Self::AccountId>>, DispatchError>;
Expand Down
2 changes: 1 addition & 1 deletion pallet/common/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ macro_rules! impl_pallet_sft_config {
parameter_types! {
pub const SftPalletId: PalletId = PalletId(*b"sftokens");
pub const MaxTokensPerSftCollection: u32 = 10_000;
pub const MaxSerialsPerSftMint: u32 = 10;
pub const MaxSerialsPerSftMint: u32 = 100;
pub const MaxOwnersPerSftToken: u32 = 100;
}

Expand Down
1 change: 0 additions & 1 deletion pallet/marketplace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "p
pallet-assets = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
pallet-evm = { git = "https://github.com/futureversecom/frontier", branch = "polkadot-v0.9.30-TRN" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
pallet-sft = { path = "../sft" }

[features]
default = ["std"]
Expand Down
6 changes: 2 additions & 4 deletions pallet/marketplace/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

use crate::*;
use frame_support::{ensure, traits::Get, transactional};
use pallet_nft::traits::NFTExt;
use seed_pallet_common::{log, Hold, TransferExt};
use seed_pallet_common::{log, Hold, NFTExt, TransferExt};
use seed_primitives::{AssetId, Balance, RoyaltiesSchedule, SerialNumber, TokenId};
use sp_runtime::{
traits::{One, Saturating, Zero},
Expand Down Expand Up @@ -311,8 +310,7 @@ impl<T: Config> Pallet<T> {
marketplace_id: Option<MarketplaceId>,
) -> Result<OfferId, DispatchError> {
ensure!(!amount.is_zero(), Error::<T>::ZeroOffer);
let collection_info = T::NFTExt::get_collection_info(token_id.0)?;
ensure!(!collection_info.is_token_owner(&who, token_id.1), Error::<T>::IsTokenOwner);
ensure!(T::NFTExt::get_token_owner(&token_id) != Some(who), Error::<T>::IsTokenOwner);
let offer_id = Self::next_offer_id();
ensure!(offer_id.checked_add(One::one()).is_some(), Error::<T>::NoAvailableIds);

Expand Down
3 changes: 1 addition & 2 deletions pallet/marketplace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ use frame_support::{
transactional, PalletId,
};
pub use pallet::*;
use pallet_nft::traits::NFTExt;
use seed_pallet_common::{CreateExt, Hold, SFTExt, TransferExt};
use seed_pallet_common::{CreateExt, Hold, NFTExt, SFTExt, TransferExt};
use seed_primitives::{
AccountId, AssetId, Balance, CollectionUuid, ListingId, SerialNumber, TokenId, TokenLockReason,
};
Expand Down
23 changes: 23 additions & 0 deletions pallet/marketplace/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2868,6 +2868,29 @@ mod buy_sft {
AssetsExt::reducible_balance(NativeAssetId::get(), &fee_pot_account, false),
5, // 0.5% of 1000
);

System::assert_has_event(MockEvent::Marketplace(
Event::<Test>::FixedPriceSaleComplete {
tokens: sft_token.clone(),
listing_id,
marketplace_id: None,
price,
payment_asset: NativeAssetId::get(),
seller: token_owner,
buyer,
},
));

System::assert_has_event(
pallet_sft::Event::<Test>::Transfer {
previous_owner: token_owner,
collection_id,
serial_numbers: BoundedVec::truncate_from(vec![token_id.1]),
balances: BoundedVec::truncate_from(vec![sell_quantity]),
new_owner: buyer,
}
.into(),
);
});
}

Expand Down
16 changes: 11 additions & 5 deletions pallet/marketplace/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ use crate::{Config, Error};

use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{dispatch::DispatchResult, ensure, RuntimeDebugNoBound};
use pallet_nft::traits::NFTExt;
use scale_info::TypeInfo;
use seed_pallet_common::SFTExt;
use seed_pallet_common::{NFTExt, SFTExt};
use seed_primitives::{
AssetId, Balance, BlockNumber, CollectionUuid, ListingId, RoyaltiesSchedule, SerialNumber,
TokenId, TokenLockReason,
Expand Down Expand Up @@ -146,11 +145,18 @@ impl<T: Config> ListingTokens<T> {
to.clone(),
)?;
},
ListingTokens::Sft(sfts) =>
ListingTokens::Sft(sfts) => {
for (serial_number, balance) in sfts.serial_numbers.iter() {
let token_id = (sfts.collection_id, *serial_number);
T::SFTExt::transfer_reserved_balance(token_id, *balance, from, to)?;
},
T::SFTExt::free_reserved_balance(token_id, *balance, from)?;
}
T::SFTExt::do_transfer(
*from,
sfts.collection_id,
sfts.clone().serial_numbers.into_inner(),
*to,
)?;
},
}
Ok(())
}
Expand Down
33 changes: 23 additions & 10 deletions pallet/nft/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
// limitations under the License.
// You may obtain a copy of the License at the root of this project source code

use crate::{traits::NFTExt, *};
use crate::{traits::NFTCollectionInfo, *};
use frame_support::{ensure, traits::Get, weights::Weight};
use frame_system::RawOrigin;
use precompile_utils::constants::ERC721_PRECOMPILE_ADDRESS_PREFIX;
use seed_pallet_common::{
log,
utils::{next_asset_uuid, PublicMintInformation},
OnNewAssetSubscriber, OnTransferSubscriber,
NFTExt, OnNewAssetSubscriber, OnTransferSubscriber,
};
use seed_primitives::{
CollectionUuid, MetadataScheme, OriginChain, RoyaltiesSchedule, SerialNumber, TokenCount,
Expand Down Expand Up @@ -583,7 +583,6 @@ impl<T: Config> Pallet<T> {

impl<T: Config> NFTExt for Pallet<T> {
type AccountId = T::AccountId;
type MaxTokensPerCollection = T::MaxTokensPerCollection;
type StringLimit = T::StringLimit;

fn do_mint(
Expand Down Expand Up @@ -636,13 +635,12 @@ impl<T: Config> NFTExt for Pallet<T> {
collection.get_token_owner(token_id.1)
}

fn get_collection_info(
fn get_collection_issuance(
collection_id: CollectionUuid,
) -> Result<
CollectionInformation<Self::AccountId, Self::MaxTokensPerCollection, Self::StringLimit>,
DispatchError,
> {
CollectionInfo::<T>::get(collection_id).ok_or(Error::<T>::NoCollectionFound.into())
) -> Result<(TokenCount, Option<TokenCount>), DispatchError> {
let collection_info =
CollectionInfo::<T>::get(collection_id).ok_or(Error::<T>::NoCollectionFound)?;
Ok((collection_info.collection_issuance, collection_info.max_issuance))
}

fn get_royalties_schedule(
Expand All @@ -664,7 +662,7 @@ impl<T: Config> NFTExt for Pallet<T> {
Self::next_collection_uuid()
}

fn increment_collection_id() -> DispatchResult {
fn increment_collection_uuid() -> DispatchResult {
ensure!(<NextCollectionId<T>>::get().checked_add(1).is_some(), Error::<T>::NoAvailableIds);
<NextCollectionId<T>>::mutate(|i| *i += u32::one());
Ok(())
Expand All @@ -689,3 +687,18 @@ impl<T: Config> NFTExt for Pallet<T> {
<TokenLocks<T>>::remove(token_id);
}
}

impl<T: Config> NFTCollectionInfo for Pallet<T> {
type AccountId = T::AccountId;
type MaxTokensPerCollection = T::MaxTokensPerCollection;
type StringLimit = T::StringLimit;

fn get_collection_info(
collection_id: CollectionUuid,
) -> Result<
CollectionInformation<Self::AccountId, Self::MaxTokensPerCollection, Self::StringLimit>,
DispatchError,
> {
CollectionInfo::<T>::get(collection_id).ok_or(Error::<T>::NoCollectionFound.into())
}
}
Loading

0 comments on commit b1a0eef

Please sign in to comment.