Proposal: New Solana NFT Spec

Current Issues

The current NFT spec is pretty bad for a few reasons:

  • every NFT requires multiple accounts (3+)

  • the token account address can change (and the token account is not always the associated token account of the current NFT owner)

  • the NFT holder can transfer the NFT to a diff token account which can make any existing escrow / marketplace accounts invalid

  • it’s hard to get all of the NFTs for a given wallet

  • the editions part of the spec is very confusing

  • it’s hard to group collections — not built into the original version of the spec and slow to query

  • it’s really hard to get all of the activity (transfers / etc) for one NFT since one tx may include the mint while another tx includes the token account

This all stems from the first problem — an NFT is a bunch of different accounts but it should really be just one account.

A Path Forwards

NFToken + One Account

In this new spec, we will have an NFToken program that we will use instead of the Tokenkeg program.

An NFT will be represented by an account that is a PDA of the NFToken program and it will have the following fields:

  • address — the ID of the NFT will be it’s address on the Solana blockchain

  • data — the rest of the fields will be stored in the data

    • holder — address (notice how I didn’t call this owner)

    • delegate — has ability to transfer the NFT to someone else

    • metadata_url — max 128 characters, you will want to use short URLs. the URL will store offchain metadata‚ spec https://docs.opensea.io/docs/metadata-standards

    • name — max 32 utf-8 characters

    • image_url — max 128 characters, name and image_url are nice to have on chain since this is the basics of what’s required for most NFTs

    • collection — points to the address of the collection (explained below)

    • creator / update_authority — the account used to sign the message to mint this NFT

Common Queries

Get All NFTs for a Wallet

  • getProgramAccounts

    • program = NftToken

    • memcmp: holder = wallet

Transfer NFT

NFToken will have a transfer instruction that can be signed by either the holder or the delegate. After the transfer ix, the delegate is zero’d out.

Set Delegate

The holder can sign an instruction to set the delegate of the NFT.

Mint New NFT as Creator

To create a new NFT, you will call the mint instruction on the NFToken program and you pass in all of the data for the newly created NFT.

Update NFT

The update_authority has permissions to update the following fields:

  • name

  • image_url

  • metadata_url

Marketplace Actions

List NFT

To list an NFT, you will:

  • update the NFT delegate to the marketplace custody account

  • create a listing account that represents the sale information

An NFT will still show up in your wallet while it is listed on the NFT marketplace.

Update Listing

To update a listing, you update the listing account on the NFT marketplace. You don’t need to interact with NFToken

Cancel Listing

You can delete the listing account which should zero out the delegate field.

You can also zero out the delegate field yourself without getting permission from the NFT marketplace. They would have to update the listing account on their side and delete it.

Execute Sale

The delegate which is controlled by the marketplace can transfer the holder field after which the delegate field is zerod out.

So the NFT marketplace will make the transfer after seeing that a sale is executable.

Collections

We want to support collections from the inception of this protocol. While we support collections, not every NFT needs to be on a collection.

The NFToken program will also create PDAs that represent collections:

  • address — this is the ID of the collection

  • data

    • name — 32 characters

    • image_url — 32 characters

    • metadata_url — 128 characters

    • update_authority

Update Collection

The update_authority can update the name and metadata_url for the collection

Add NFT to Collection

To add an NFT, we will need signatures from the NFT update_authority and the collection update_authority.

Remove NFT from Collection

The collection update_authority can remove an NFT from its collection. This does not require permission from the NFT update_authority.

Further Work

If you're interested in pushing this spec forwards, @-me on Twitter.