Open Market Protocol, the Market Model, & RPC API Functions

I thought this week I’d show off some of the backend work that is completed for the Particl Marketplace. Some of this might be high-level stuff — I admit I felt a bunch of it fly right over my head even as I was writing about it :)

Nevertheless, here is some of the stellar work the Particl Development Team has been doing on the Particl Marketplace.

Precursor: Open Market Protocol (OMP)

I’ve mentioned the OMP before and the author, Ido Kaiser, gave a presentation about how to begin building a decentralized marketplace focused on privacy at this year’s Hackers Congress Paralelní Polis

Hackers Congress Paralelní Polis 2017
Hackers Congress Paralelní Polis is one of the premier events for hackers, artists, activists, libertarians, and…liberate.hcpp.cz

The intent of this specification is to create a standardized and open format that can encompass all the economic interactions of an online marketplace. It is a good reference for the functions the team is building into Particl Marketplace.

Market Protocol · GitBook
protocol:www.gitbook.com


The Market Model

The diagram above gives an overview of the market model. While not complete, it is a good foundation with which the team is building functionality into.

What you are visualizing is basically the creation, discovery, agreement and fulfillment vendors and buyers make on the marketplace — as well as the progression of ownership of digital and physical goods (cryptocurrency & products) during and after the contract.

Bid Status(s)

The basic item listing only contains rudimentary elements, if these are not available then the listing is rejected.

  • NEW
{  
  "version":"0.0.1.0",
  "mpaction": {
    "action": "MPA_BID", 
    "item": "f08f3d6e",
    "objects":[
      {
        "id": "colour",
        "value": "black"
      }
    ]
  }
}
biddata can contain some values related to the item that its a bid for. size, colour, etc.
  • ACCEPTED
{
  "version":"0.0.1.0",
  "mpaction": {
    "action": "MPA_ACCEPT", 
    "item": "f08f3d6e"
  }
}
  • REJECTED
{
  "version":"0.0.1.0",
  "mpaction": {
    "action": "MPA_REJECT", 
    "item": "f08f3d6e"
  }
}
  • CANCELLED
{
  "version":"0.0.1.0",
  "mpaction": {
    "action": "MPA_CANCEL", 
    "item": "f08f3d6e"
  }
}

Functions (RPC API)

If the market model above is a map, these functions are waypoints along the journey.

finditems

Route from RpcController to RpcListingItemService.search

- data.params[]:
[0]: page, number

[1]: pageLimit, number

[2]: order, SearchOrder

[3]: category, number|string, if string, try to find using key, can be null

[4]: searchString, string, can be null

call ListingItemService.search with ListingItemSearchParams, validate params

support for paging

support for sorting and filtering by different fields, which are:

- categories

return Collection of ListingItem

getitem

Route to rpcListingItemService.findOne

- data.params[]:
[0]: id or hash

findOne is implemented (ListingItemService/Repository), but it uses the item id, need to add findOneByHash

- returns ListingItem with relations

findownitems

“ownitem” is a ListingItem which is related to a ListingItemTemplate which is related to profile. The relation is created when new incoming ListingItem is matched with a ListingItemTemplate.

- route from RpcController to RpcListingItemService.search

- data.params[]: similar to findItems

- add possibility to search by profile_id to the search function

- needs sorting, filtering and paging Service/Repository layer as implemented in finditems

- returns a List of ListingItems

createitemtemplate

data.params[]:

- create RpcListingItemTemplateService

- route from RpcController to RpcListingItemTemplateService.create

- create Service/Repository layer for crud actions

- saves ItemTemplate

- later: if there are images, remove metadata

updatepaymentinformation

Updates PaymentInformation related to ListingItemTemplate

- update the createitemtemplate command to also create the initial PaymentInformation after creating the ListingItemTemplate

- create RpcPaymentInformationService

- route from RpcController to RpcPaymentInformationService.update

findbids

Returns bids based on search parameters.

It should:

- get latest bids for our own items.

- return bids for list of items or single item

- return bids for all items of given profile

Bid model needs to be implemented
ListingItem can have 0 or more Bids

- route from RpcController to RpcBidService.search

- data.params[]: 
[0]:

- returns Collection of Bids

createescrow

Creates an Escrow related to PaymentInformation related to ListingItemTemplate

- create RpcEscrowService

- route from RpcController to RpcEscrowService.create

- data.params[]:
[0]: ListingItemTemplate.id
[1]: escrowtype
[2]: buyer ratio
[3]: seller ratio

- escrow cannot be created if there’s a ListingItem related to ListingItemTemplate.

updateescrow

Updates an Escrow related to PaymentInformation

- route from RpcController to RpcEscrowService.update

- data.params[]:
[0]: ListingItemTemplate.id
[1]: escrowtype
[2]: buyer ratio
[3]: seller ratio

- escrow cannot be updated if there’s a ListingItem related to ListingItemTemplate. (the item has allready been posted)

finditemtemplates

- route to rpcListingItemTemplateService.search

- data.params[]:
[0]: page, number
[1]: pageLimit, number
[2]: order, SearchOrder

getitemtemplate

- route from RpcController to RpcItemTemplateService.findOne

- data.params[]:
[0]: id

- findOne is implemented (ItemTemplateService/Repository)

- returns ListingItemTemplate with relations

createprofile

Profile is used to store users personal information. For now it’ll contain Address so that we can store the users addresses and it can be later added to the order.

- create resource Profile, which contains a List of Addresses

- create resource Address, which belongs to a Profile

- route saveprofile rpc method from RpcController to ProfileService.rpcSaveProfile

- store in db

- in ProfileService save the profile and call addressService.saveAddress to save the address

Address fields (in db):

- title: string

- address_line1: string

- address_line2: string

- city: string

- country: string (CountryEnum)

- profile_id

ProfileController.getList should return a profile containing a list of Addresses.

‘npm run test:black-box’ should run tests against the rest endpoint and test that the models get stored correctly.

getprofile

- returns the users profile, which currently is used to store his shipping addresses

- route from RpcController to RpcProfileService.findOne

- return Profile with related Addresses

addfavorite, removefavorite

“As a user I want to be able to favorite items, so that I can later easily find my favorite items.”

- link favorited items with a profile.

create FavoriteItem, with fields:

- profile_id

updateiteminformation

ItemInformation is created when ListingItemTemplate is created.
* Make sure the ItemInformation being updated is related ListingItemTemplate (and profile), because we shouldn’t be editing ItemInformation from item’s that aren’t ours.

- data.params[]:
[0]: id
[1]: title
[2]: short description
[3]: long description
[4]: category

- updates ItemInformation

createitemtemplate changes

ItemTemplate is created when user wants to create an item.
* When createitemtemplate is called, create also the related ItemInformation and return the ItemTemplate with relations. The UI can then use the ItemTemplate.ItemInformation.id to call updateiteminformation to update the item’s information if needed.

- data.params[]:
[0]: title
[1]: short description
[2]: long description
[3]: category

- creates ItemTemplate and ItemInformation

- returns ItemTemplate with relations

removeescrow

Removes an Escrow related to PaymentInformation

“As a merchant I want to remove the escrow for the item that I’m going to sell”

- route from RpcController to RpcEscrowService.destroy

- data.params[]:
[0]: ListingItemTemplate.id

- escrow cannot be removed if there’s a ListingItem related to ListingItemTemplate. (the item has allready been posted)

updatemessaginginformation

Updates MessagingInformation related to ListingItemTemplate

“As a merchant I want to update the way I wish to exchange messages with buyers.”

- update the createitemtemplate command to also create the initial MessagingInformation after creating the ListingItemTemplate

- create RpcMessagingInformationService

- route from RpcController to RpcMessagingInformationService.update

- make sure the ItemInformation being updated is related ListingItemTemplate, because we shouldn’t be able to edit ItemInformations for item’s that aren’t ours.

- data.params[]:
[0]: ListingItemTemplate.id
[1]: protocol (MessagingProtocolType)
[2]: public key

- messaging information cannot be updated if there’s a ListingItem related to ListingItemTemplate. (the item has already been posted)

createcategory

Creates a custom ItemCategory

“As a merchant I want to create a custom category for the item that I’m going to sell”

- route from RpcController to RpcItemCategoryService.create

- data.params[]:
[0]: name
[1]: description
[2]: parent category id/key, default: cat_ROOT

- custom user created categories don’t have keys

updatecategory

Updates a custom ItemCategory

“As a merchant I want to create a custom category for the item that I’m going to sell”

- route from RpcController to RpcItemCategoryService.update

- data.params[]:
[0]: id
[1]: name
[2]: description
[3]: parent category id/key, default: cat_ROOT

- category cannot be updated if there’s a ListingItem related to ItemCategory.

- category cannot be removed if it has a key (is a default category)

removecategory

Removes a custom ItemCategory

“As a merchant I want to create a custom category for the item that I’m going to sell”

- route from RpcController to RpcItemCategoryService.destroy

- data.params[]:
[0]: id

- category cannot be removed if there’s a ListingItem related to ItemCategory.

- category cannot be removed if there’s a ListingItemTemplate related to ItemCategory.

- category cannot be removed if it has a key (is a default category)

getcategories

Returns a list of all the categories

- route from RpcController to RpcItemCategoryService.findRoot

- data.params[]:
[0]: none

- return the root category with all it’s relations

findcategory

Search for a category

updateitemlocation

Updates ItemLocation related to ItemInformation

“As a merchant I want to update the location of the item that I’m going to sell”

- route from RpcController to RpcItemLocationService.update

- data.params[]:
[0]: ListingItemTemplate.id

removeitemlocation

Removes ItemLocation from ItemInformation

“As a merchant I want to remove location from the item that I’m going to sell”

- route from RpcController to RpcItemLocationService.destroy

- data.params[]:
[0]: ListingItemTemplate.id

addshippingdestination

Adds a ShippingDestination to ItemInformation

“As a merchant I want to add a shipping destinations to the item that I’m going to sell”

- route from RpcController to RpcShippingDestinationService.create

- data.params[]:

removeshippingdestination

Removes a ShippingDestination from ItemInformation

“As a merchant I want to remove a shipping destination from the item that I’m going to sell”

- route from RpcController to RpcShippingDestinationService.destroy

- data.params[]:

additemimage

Adds ItemImage to ItemInformation

“As a merchant I want to add a images to the item that I’m going to sell”

- route from RpcController to RpcItemImageService.create

- data.params[]:
[0]: ListingItemTemplate.id

removeitemimage

Removes ItemImage from ItemInformation

“As a merchant I want to remove image from the item that I’m going to sell”

- route from RpcController to RpcItemImageService.destroy

- data.params[]:
[0]: ItemImage.Id

Summary

Wow! That’s a bunch of functions that have been built in to the code thus far. You can track the team’s daily progress in the dapp-shell repo on Github.

particl/dapp-shell
dapp-shell - DApp Shellgithub.com

There are more functions I’ll hit on in another update on Particl Marketplace. They’ll include but not be limited to:

postitem   updateitem   cancelitem   acceptbid   rejectbid   sendbid cancelbid   setaddress   getaddress   setautoaddress   lockescrow refundescrow   releaseescrow   additemlocation

Thank You

Particl Team