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]
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:
- This commit adds the wearables to the Frontend (oops! two things were missing)
- These two commits add the information to the Indexer Backend
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”