Skip to content

Commit b444edb

Browse files
committed
Update gated-marketplace pallet documentation
1 parent a769d93 commit b444edb

File tree

3 files changed

+171
-38
lines changed

3 files changed

+171
-38
lines changed

pallets/gated-marketplace/README.md

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ This module allows to:
4949
- Enroll or reject applicants to your marketplace.
5050
- Add or remove users as supported authorities to your marketplace, like administrators and/or asset appraisers
5151
- WIP: Assign a rating to assets as an Appraiser.
52+
- Create sell or buy orders. Users can bid on the item if they don't like the sale price.
5253

5354
### Terminology
5455
- **Authority**: Refers to any user that has special faculties within the marketplace, like enroll new users or grade assets.
@@ -60,6 +61,8 @@ This module allows to:
6061
- **Enroll**: When enrolled, the user's application becomes approved, gaining the ability to sell and buy assets.
6162
- **Reject**: If the user gets rejected, its application becomes rejected and won't have access to the marketplace.
6263
- **Custodian**: When submitting an application, the user can optionally specify a third account that will have access to the confidential documents. A custodian doesn't need to be an authority nor being part of the marketplace.
64+
- **Sell order**: The owner of the item creates sales offer fot the item.
65+
- **Buy order**: Users from the marketplace can bid for the item.
6366

6467
## Interface
6568

@@ -72,16 +75,28 @@ This module allows to:
7275
- `remove_authority` is only callable by the marketplace owner or administrator. Removes the authority enforcer from the marketplace. The marketplace owner cannot be removed and the administrator cannot remove itself.
7376
- `update_label_marketplace` is only callable by the marketplace owner or administrator. Changes the marketplace label. If the new label already exists, the old name won't be changed.
7477
- `remove_marketplace` is only callable by the marketplace owner or administrator. This action allows the user to remove a marketplace as well as all the information related to this marketplace.
78+
- `enlist_sell_offer` is only callable by the owner of the item. It allows the user to sell an item in the selected marketplace.
79+
- `take_sell_offer` any user interested to buy the item can call this extrinsic. User must have enough balance to buy it. When the transaction is completed, the item ownership is transferred to the buyer.
80+
- `duplicate_offer` allows the owner of the item to duplicate an sell order in any marketplace.
81+
- `remove_offer` is only callable by the creator of the offer, it deletes any offer type from all the storages.
82+
- `enlist_buy_offer` is callable by any market participant, the owner of the item can't create buy orders for their own items. User must have the enough balance to call it.
83+
- `take_buy_offer` is only callable by the owner of the item. If the owner accepts the offer, the buyer must have enough balance to finalize the transaction.
7584

7685

7786
### Getters
78-
- `marketplaces`
79-
- `marketplaces_by_authority` (double storage map)
80-
- `authorities_by_marketplace` (double storage map)
81-
- `applications`
82-
- `applications_by_account` (double storage map)
83-
- `applicants_by_marketplace` (double storage map)
84-
- `custodians` (double storage map)
87+
|Name| Type |
88+
|--|--|
89+
|`marketplaces`| storage map|
90+
|`marketplaces_by_authority`|double storage map|
91+
|`authorities_by_marketplace`|double storage map|
92+
|`applications`| storage map|
93+
|`applications_by_account`|double storage map|
94+
|`applicants_by_marketplace`|double storage map|
95+
|`custodians`|double storage map|
96+
|`offers_info` |storage map|
97+
|`offers_by_item`|double storage map|
98+
|`offers_by_account`|storage map|
99+
|`offers_by_marketplace`|storage map|
85100

86101

87102
## Usage
@@ -544,19 +559,34 @@ const removeAuthority = await api.tx.gatedMarketplace.removeAuthority(dave.addre
544559
545560
```rust
546561
/// Marketplaces stored. [owner, admin, market_id]
547-
MarketplaceStored(T::AccountId, T::AccountId, [u8;32]),
562+
1. MarketplaceStored(T::AccountId, T::AccountId, [u8;32])
563+
548564
/// Application stored on the specified marketplace. [application_id, market_id]
549-
ApplicationStored([u8;32], [u8;32]),
565+
2. ApplicationStored([u8;32], [u8;32])
566+
550567
/// An applicant was accepted or rejected on the marketplace. [AccountOrApplication, market_id, status]
551-
ApplicationProcessed(AccountOrApplication<T>,[u8;32], ApplicationStatus),
568+
3. ApplicationProcessed(AccountOrApplication<T>,[u8;32], ApplicationStatus)
569+
552570
/// Add a new authority to the selected marketplace
553-
AuthorityAdded(T::AccountId, MarketplaceAuthority),
571+
4. AuthorityAdded(T::AccountId, MarketplaceAuthority)
572+
554573
/// Remove the selected authority from the selected marketplace
555-
AuthorityRemoved(T::AccountId, MarketplaceAuthority),
574+
5. AuthorityRemoved(T::AccountId, MarketplaceAuthority)
575+
556576
/// The label of the selected marketplace has been updated. [market_id]
557-
MarketplaceLabelUpdated([u8;32]),
577+
6. MarketplaceLabelUpdated([u8;32])
578+
558579
/// The selected marketplace has been removed. [market_id]
559-
MarketplaceRemoved([u8;32])
580+
7. MarketplaceRemoved([u8;32])
581+
582+
/// Offer stored. [collection_id, item_id]
583+
8. OfferStored(T::CollectionId, T::ItemId)
584+
585+
/// Offer was accepted [offer_id, account]
586+
9. OfferWasAccepted([u8;32], T::AccountId)
587+
588+
/// Offer was duplicated. [new_offer_id, new_marketplace_id]
589+
10. OfferDuplicated([u8;32], [u8;32])
560590
```
561591
562592
## Errors
@@ -608,4 +638,32 @@ ApplicationIdNotFound,
608638
ApplicationStatusStillPending,
609639
/// The application has already been approved, application status is approved
610640
ApplicationHasAlreadyBeenApproved,
641+
/// Collection not found
642+
CollectionNotFound,
643+
/// User who calls the function is not the owner of the collection
644+
NotOwner,
645+
/// Offer already exists
646+
OfferAlreadyExists,
647+
/// Offer not found
648+
OfferNotFound,
649+
/// Offer is not available at the moment
650+
OfferIsNotAvailable,
651+
/// Owner cannnot buy its own offer
652+
CannotTakeOffer,
653+
/// User cannot remove the offer from the marketplace
654+
CannotRemoveOffer,
655+
/// Error related to the timestamp
656+
TimestampError,
657+
/// User does not have enough balance to buy the offer
658+
NotEnoughBalance,
659+
/// User cannot delete the offer because is closed
660+
CannotDeleteOffer,
661+
/// There was a problem storing the offer
662+
OfferStorageError,
663+
/// Price must be greater than zero
664+
PriceMustBeGreaterThanZero,
665+
/// User cannot create buy offers for their own items
666+
CannotCreateOffer,
667+
/// This items is not available for sale
668+
ItemNotForSale,
611669
```

pallets/gated-marketplace/src/functions.rs

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -429,11 +429,13 @@ impl<T: Config> Pallet<T> {
429429
//ensure marketplace_id exits
430430
ensure!(<Marketplaces<T>>::contains_key(marketplace_id), Error::<T>::MarketplaceNotFound);
431431

432-
//ensure the offer_id exists & get the offer data
433-
let copy_offer_data = <OffersInfo<T>>::get(offer_id).ok_or(Error::<T>::OfferNotFound)?;
432+
//ensure the offer_id exists
433+
ensure!(<OffersInfo<T>>::contains_key(offer_id), Error::<T>::OfferNotFound);
434+
434435

435436
// ensure the owner is the same as the authority
436-
ensure!(copy_offer_data.creator == authority.clone(), Error::<T>::CannotRemoveOffer);
437+
let offer_creator = Self::get_offer_creator(offer_id).map_err(|_| Error::<T>::OfferNotFound)?;
438+
ensure!(offer_creator == authority.clone(), Error::<T>::CannotRemoveOffer);
437439

438440
//ensure the offer_id exists in OffersByItem
439441
Self::does_exist_offer_id_for_this_item(collection_id, item_id, offer_id)?;
@@ -719,6 +721,7 @@ impl<T: Config> Pallet<T> {
719721

720722
fn get_timestamp_in_milliseconds() -> Option<(u64, u64)> {
721723
let timestamp: <T as pallet_timestamp::Config>::Moment = <pallet_timestamp::Pallet<T>>::get();
724+
722725
let timestamp2 = Self::convert_moment_to_u64_in_milliseconds(timestamp).unwrap_or(0);
723726
let timestamp3 = timestamp2 + (7 * 24 * 60 * 60 * 1000);
724727

@@ -773,26 +776,6 @@ impl<T: Config> Pallet<T> {
773776
fn update_offers_status(buyer: T::AccountId, collection_id: T::CollectionId, item_id: T::ItemId, marketplace_id: [u8;32]) -> DispatchResult{
774777
let offer_ids = <OffersByItem<T>>::try_get(collection_id, item_id).map_err(|_| Error::<T>::OfferNotFound)?;
775778

776-
//This logic is no longer needed, when an offer_id is accepted,
777-
// all the other offers for this item are automatically closed.
778-
// It doesn't matter the offertype.
779-
780-
// let mut sell_offer_ids: BoundedVec<[u8;32], T::MaxOffersPerMarket> = BoundedVec::default();
781-
782-
// for offer_id in offer_ids {
783-
// let offer_info = <OffersInfo<T>>::get(offer_id).ok_or(Error::<T>::OfferNotFound)?;
784-
// //ensure the offer_type is SellOrder, because this vector also contains offers of BuyOrder OfferType.
785-
// if offer_info.offer_type == OfferType::SellOrder {
786-
// sell_offer_ids.try_push(offer_id).map_err(|_| Error::<T>::OfferStorageError)?;
787-
// }
788-
// // //version 2
789-
// // if let Some(offer) = <OffersInfo<T>>::get(offer_id) {
790-
// // if offer.offer_type == OfferType::SellOrder {
791-
// // sell_offer_ids.try_push(offer_id).map_err(|_| Error::<T>::OfferStorageError)?;
792-
// // }
793-
// // }
794-
// }
795-
796779
for offer_id in offer_ids {
797780
<OffersInfo<T>>::try_mutate::<_,_,DispatchError,_>(offer_id, |offer|{
798781
let offer = offer.as_mut().ok_or(Error::<T>::OfferNotFound)?;

pallets/gated-marketplace/src/lib.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,22 @@ pub mod pallet {
513513
Self::do_remove_marketplace(who, marketplace_id)
514514
}
515515

516+
/// Enlist a sell order.
517+
///
518+
/// This extrinsic creates a sell order in the selected marketplace.
519+
///
520+
/// ### Parameters:
521+
/// - `origin`: The user who performs the action.
522+
/// - `marketplace_id`: The id of the marketplace where we want to create the sell order.
523+
/// - `collection_id`: The id of the collection.
524+
/// - `item_id`: The id of the item inside the collection.
525+
/// - `price`: The price of the item.
526+
///
527+
/// ### Considerations:
528+
/// - You can only create a sell order in the marketplace if you are the owner of the item.
529+
/// - You can create only one sell order for each item per marketplace.
530+
/// - If the selected marketplace doesn't exist, it will throw an error.
531+
/// - If the selected collection doesn't exist, it will throw an error.
516532
#[transactional]
517533
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
518534
pub fn enlist_sell_offer(origin: OriginFor<T>, marketplace_id: [u8;32], collection_id: T::CollectionId, item_id: T::ItemId, price: BalanceOf<T>,) -> DispatchResult {
@@ -521,6 +537,20 @@ pub mod pallet {
521537
Self::do_enlist_sell_offer(who, marketplace_id, collection_id, item_id, price)
522538
}
523539

540+
/// Accepts a sell order.
541+
///
542+
/// This extrinsic accepts a sell order in the selected marketplace.
543+
///
544+
/// ### Parameters:
545+
/// - `origin`: The user who performs the action.
546+
/// - `marketplace_id`: The id of the marketplace where we want to accept the sell order.
547+
/// - `collection_id`: The id of the collection.
548+
/// - `item_id`: The id of the item inside the collection.
549+
///
550+
/// ### Considerations:
551+
/// - You don't need to be the owner of the item to accept the sell order.
552+
/// - Once the sell order is accepted, the ownership of the item is transferred to the buyer.
553+
/// - If you don't have the enough balance to accept the sell order, it will throw an error.
524554
#[transactional]
525555
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
526556
pub fn take_sell_offer(origin: OriginFor<T>, offer_id: [u8;32], marketplace_id: [u8;32], collection_id: T::CollectionId, item_id: T::ItemId,) -> DispatchResult {
@@ -529,6 +559,20 @@ pub mod pallet {
529559
Self::do_take_sell_offer(who, offer_id, marketplace_id, collection_id, item_id)
530560
}
531561

562+
/// Allows a user to duplicate a sell order.
563+
///
564+
/// This extrinsic allows a user to duplicate a sell order in any marketplace.
565+
///
566+
/// ### Parameters:
567+
/// - `origin`: The user who performs the action.
568+
/// - `marketplace_id`: The id of the marketplace where we want to duplicate the sell order.
569+
/// - `collection_id`: The id of the collection.
570+
/// - `item_id`: The id of the item inside the collection.
571+
///
572+
/// ### Considerations:
573+
/// - You can only duplicate a sell order if you are the owner of the item.
574+
/// - The expiration date of the sell order is the same as the original sell order.
575+
/// - You can update the price of the sell order.
532576
#[transactional]
533577
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
534578
pub fn duplicate_offer(origin: OriginFor<T>, offer_id: [u8;32], marketplace_id: [u8;32], collection_id: T::CollectionId, item_id: T::ItemId, modified_price: BalanceOf<T>) -> DispatchResult {
@@ -537,6 +581,23 @@ pub mod pallet {
537581
Self::do_duplicate_offer(who, offer_id, marketplace_id, collection_id, item_id, modified_price)
538582
}
539583

584+
585+
/// Delete an offer.
586+
///
587+
/// This extrinsic deletes an offer in the selected marketplace.
588+
///
589+
/// ### Parameters:
590+
/// - `origin`: The user who performs the action.
591+
/// - `marketplace_id`: The id of the marketplace where we want to delete the offer.
592+
/// - `collection_id`: The id of the collection.
593+
/// - `item_id`: The id of the item inside the collection.
594+
///
595+
/// ### Considerations:
596+
/// - You can delete sell orders or buy orders.
597+
/// - You can only delete an offer if you are the creator of the offer.
598+
/// - Only open offers can be deleted.
599+
/// - If you need to delete multiple offers for the same item, you need to
600+
/// delete them one by one.
540601
#[transactional]
541602
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
542603
pub fn remove_offer(origin: OriginFor<T>, offer_id: [u8;32], marketplace_id: [u8;32], collection_id: T::CollectionId, item_id: T::ItemId,) -> DispatchResult {
@@ -547,7 +608,21 @@ pub mod pallet {
547608
Self::do_remove_offer(who, offer_id, marketplace_id, collection_id, item_id)
548609
}
549610

550-
611+
/// Enlist a buy order.
612+
///
613+
/// This extrinsic creates a buy order in the selected marketplace.
614+
///
615+
/// ### Parameters:
616+
/// - `origin`: The user who performs the action.
617+
/// - `marketplace_id`: The id of the marketplace where we want to create the buy order.
618+
/// - `collection_id`: The id of the collection.
619+
/// - `item_id`: The id of the item inside the collection.
620+
/// - `price`: The price of the item.
621+
///
622+
/// ### Considerations:
623+
/// - Any user can create a buy order in the marketplace.
624+
/// - An item can receive multiple buy orders at a time.
625+
/// - You need to have the enough balance to create the buy order.
551626
#[transactional]
552627
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
553628
pub fn enlist_buy_offer(origin: OriginFor<T>, marketplace_id: [u8;32], collection_id: T::CollectionId, item_id: T::ItemId, price: BalanceOf<T>,) -> DispatchResult {
@@ -556,6 +631,23 @@ pub mod pallet {
556631
Self::do_enlist_buy_offer(who, marketplace_id, collection_id, item_id, price)
557632
}
558633

634+
635+
/// Accepts a buy order.
636+
///
637+
/// This extrinsic accepts a buy order in the selected marketplace.
638+
///
639+
/// ### Parameters:
640+
/// - `origin`: The user who performs the action.
641+
/// - `marketplace_id`: The id of the marketplace where we accept the buy order.
642+
/// - `collection_id`: The id of the collection.
643+
/// - `item_id`: The id of the item inside the collection.
644+
///
645+
/// ### Considerations:
646+
/// - You need to be the owner of the item to accept a buy order.
647+
/// - Owner of the item can accept only one buy order at a time.
648+
/// - When an offer is accepted, all the other offers for this item are closed.
649+
/// - The buyer needs to have the enough balance to accept the buy order.
650+
/// - Once the buy order is accepted, the ownership of the item is transferred to the buyer.
559651
#[transactional]
560652
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
561653
pub fn take_buy_offer(origin: OriginFor<T>, offer_id: [u8;32], marketplace_id: [u8;32], collection_id: T::CollectionId, item_id: T::ItemId,) -> DispatchResult {

0 commit comments

Comments
 (0)