Adding Items to the Marketplace

Market adding NFTs

The Decentraland Market is the cornerstone of Decentraland’s economy. It’s where buyers and sellers find each other and transact LAND, Estates, Wearables and Names.
NFTs are grouped together in DAR contracts. DAR contracts currently for sale in the marketplace include:

  • Wearables (about 6 different DARs)
  • LAND
  • Estates
  • Names

All have in common these two views: “Card” and “View”

![NFT Card View]
image

Similarities and differences between items

Every NFT has their own representation and style. There are a number of things that are common to any NFT; such as name, owner, and things related to the sale: price, expiration. Wearables have all the following properties:

  • Part of the body
  • Rarity (how many of these items have been emitted)
  • Edition number
  • Body shape (Male/Female compatible)

Names don’t have any special property. LAND has some tags based on proximity to other things; Estates have the number of LAND inside them. Both LAND, Estates, and Wearables have a description. Users can set the description and name of LAND and Estates. LAND and Estates have a link to their position.

Managing similarities and differences

Every NFT has to have their own representation in React to display the relevant information. Right now, all the NFTs are pretty tight together:

const NFTCard = (props: Props) => {
  const { nft, order } = props

  const title = getNFTName(nft)

  return (
    <Card
      className="NFTCard"
      link
      as={Link}
      to={locations.ntf(nft.contractAddress, nft.tokenId)}
    >
      <NFTImage nft={nft} showMonospace />
      <Card.Content>
        <Card.Header>
          <div className="title">{title}</div>{' '}
          {order ? <Mana inline>{formatMANA(order.price)}</Mana> : null}
        </Card.Header>
        {order ? (
          <Card.Meta>
            {t('nft_card.expires_at', { date: getExpiresAt(order) })}
          </Card.Meta>
        ) : null}
        {nft.parcel ? <ParcelTags nft={nft} /> : null}
        {nft.estate ? <EstateTags nft={nft} /> : null}
        {nft.wearable ? <WearableTags nft={nft} /> : null}
        {nft.ens ? <ENSTags nft={nft} /> : null}
      </Card.Content>
    </Card>
  )
}

This implementation is also very much tight together because the information comes from one single TheGraph endpoint:

{
  nfts (first: 1, skip: 20014) {
    tokenId
    searchIsLand
    image
    activeOrder {
      price
      expiresAt
    }
    contractAddress
    category
  }
}

This query throws the result:

{
  "data": {
    "nfts": [
      {
        "activeOrder": {
          "expiresAt": "1616284800000",
          "price": "49000000000000000000000"
        },
        "category": "parcel",
        "contractAddress": "0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d",
        "image": "https://api.decentraland.org/v1/parcels/33/-58/map.png",
        "searchIsLand": true,
        "tokenId": "11569600475311907757754736652680119189446"
      }
    ]
  }
}

Because of the way items are processed in the marketplace, they have to be indexed. This means that any particular NFT could be placed for sell on the Marketplace; it’s only a front-end decision to include them or not.

So, issuing a new Wearable collection that can be traded on the marketplace necessarily means that the marketplace needs to include code to index that token. The good news is that this is relatively simple to add; because all Wearables are pretty much similar. See this example of adding a new collection:

That seems like a lot of code; but the backend is mostly auto-generated from the API that serves the explorer client: wearables-api.

The Wearables API

Based loosely on the Picture Frames Schema API; the Wearables API looks like this:

async function main() {
  const data = await (await fetch('https://wearable-api.decentraland.org/v2/collections/xmas_2019/')).json()
  data[10].representations[1] = '...'
  data[10].representations[0].contents = data[10].representations[0].contents.slice(0, 1).concat('...')
  data[10].tags = ['...']
  return [data[10], '...']
}
main()

In-world GLTF Representation

In order to see more about the GLTF representation, see “How to create Wearables for DCL