Authorizing a Picture Frame

What is a Picture Frame? What does it allow me to do?

A picture frame in Decentraland is a special way to display something on your scene, validating the ownership of the NFT is linked to the user that has deployed the scene (see this document for information on who can deploy to a scene).

For example, I could have a gallery in my scene showcasing a collection of NFTs that make up a private collection, and host them for an auction or in permanent exposition like in a real world museum.

MakersPlace does this already with their website:

What is the key value proposition here?

NFT Art and Collectibles:

  • Have verifiable and indisputable cryptographic ownership
  • Can be traced through time, allowing you to know the history of the item
  • May be traded with zero risk through a trust-free marketplace contract

How can NFTs in a Contract become Picture Frames?

There’s a global registry for NFTs sitting on a blockchain contract owned by the Decentraland DAO. This contract (mainnet, ropsten, source code) can be modified by an Aragon Vote.

This is its interface:

contract DARRegistry is Ownable {
  function registerDAR(darAddress, darURL) public;
  function getDARUrl(darAddress) public;
  function unregisterDAR(darAddress) public;
}

Pinging the DAR

Currently, all picture frames are being served from schema.decentraland.org :

Hitting the API should give:

Example:

DAR Example

(async function() { return await (await fetch(
  'https://schema.decentraland.org/dar/hyper-dragons/'
)).json()})()

NFT example

(async function() { const d = await (await fetch(
  'https://schema.decentraland.org/dar/hyper-dragons/asset/123'
)).json()
  d.files = d.files.filter(_ => _.role && _.role.startsWith('dcl-picture-frame-image'))
  return d
})()

The Vote of a New Picture Frame

1. Definition of the DAR

Before proposing a vote on the DAR, one must make sure the endpoint being proposed as a DAR is available. It’s recommended to deploy it under some High Availability schema, to be accessible across the world with low latency.

  • The submitted endpoint should be the main endpoint for the collection. For example,
    • https://schema.decentraland.org/dar/axie-infinity
    • A trailing slash at the end of the URL is discouraged
    • The following fields are mandatory:
      • common_name must coincide with the last part of the URL (axie-infinity in this example)
      • name a human-readable name, Axie Infinity in this example
      • contract_uri the URI for the token. Only ethereum is currently supported as a blockchian. Example: ethereum://0xf5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d
      • description a human-readable description of the token
      • schema_url the same URL as submitted to the DAO (https://schema.decentraland.org/dar/axie-infinity in this example)
        • image_url a PNG or ICO image to recognize this token. https://axieinfinity.com/team/favicon.ico in this example.

2. Required fields per each NFT

  • description
  • owner
  • name
  • registry
  • token_id
  • uri
  • files
    • name
    • url
    • role
    • roles

3. Automatically verifying every NFT

async function fetchNFT(collection, id) {
  return await (await fetch(
    `https://schema.decentraland.org/dar/${collection}/asset/${id}`
  )).json()
}
async function verifyNFT(nft, validationError) {
  if (validationError(nft)) {
    return validationError(nft)
  }
}
const needsField = field => _ => _[field] === undefined ? `missing field ${field}` : undefined
const validations = [
  needsField('name'),
  needsField('description'),
  needsField('owner'),
  needsField('registry'),
  needsField('uri'),
  needsField('token_id'),
  _ => _.files.filter($ => $.role === 'dcl-picture-frame-image')[0] ? undefined : 'no file with "dcl-picture-frame" found'
]
async function main(collection, id) {
  const nft = await fetchNFT(collection, id)
  const errors = validations.map($ => $(nft)).filter(_ => _)
  if (errors.length) {
    return `error: ${errors.join(',')}`
  }
  return `all ok`
}
main('hyper-dragons', 123)

4. Voting

When voting, the UI should run a number of these tests – ideally all the NFTs; but random sampling might be applied. The images should also be checked that they are of the correct format and size (512x512 pixels).

Interaction in the world

Verifiable Frame

Picture frames in the world have a glowing border that makes it distinguishable from any single image. It’s unfortunate that this effect impacts on the image being verified; but it is necessary to avoid one picture in front of an actual image.

Pop up display

Upon clicking; a display screen should be shown with more information about the picture. See the image above:

  • Name of the collection
  • Name of the NFT
  • Description of the NFT
  • ID of the NFT
  • Information about the issuance of the item
  • Link to the collection on the marketplace
  • Author information
  • Owner information

Connection with the Marketplace

In case the NFT is for sale; the price should be shown on the Pop up display.

Author information

In future versions; the NFT associated with the picture might have information regarding who was the original creator of the image (the artist that created the collectible).
In this case; and if the artist has created a profile, they should have their name and profile associated with the picture frame.