Skip to main content

Solana Non-Fungible Tokens (NFTs)

Solana NFT details

Solana Non-Fungible Tokens

Avana Wallet displays and organizes NFTs that use standardized metadata protocols established by Metaplex and OpenSea. Most of the Solana ecosystem follows these common standards. The Solana metadata program address is metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s.

On Solana, non-fungible tokens use the same SPL Token Program as fungible tokens. Tokens are classified as non-fungible when they have a decimal value set to zero and a supply set to one. The Solana SPL Token program address is TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA.

Metadata is hosted both on-chain and off-chain. Avana Wallet uses both on-chain and off-chain data to display one consolidated view to the user.

On-Chain Vs Off-Chain Metadata

On-chain metadata is considered more secure and the source of truth for important data such as ownership. On-chain metadata is secured by blockchain cryptography, and only authorized entities can make changes.

On-chain data storage is typically more expensive than off-chain data storage, so on-chain metadata uses a uri as a reference to additional metadata stored off-chain.

On-Chain Metadata

On-chain metadata are data written to the blockchain. These data can be fetched from any Solana node, and only the updateAuthority of the metadata can make changes to it as long as isMutable is set to true. On-chain metadata serves as the source of truth for ownership, creator addresses and seller fees. On-chain metadata links to off-chain metadata by providing a uri in the Data struct.

On-chain metadata has a cost associated with creating and updating it. As a result, on-chain metadata tends to be limited to a set of common attributes and the remaining additional information is stored off-chain and referenced with a link.

Below are the Rust structs for metadata accounts. Reference Metaplex docs for more information

Solana Metadata Layout
pub struct Metadata {
pub key: Key,
pub update_authority: Pubkey,
pub mint: Pubkey,
pub data: Data, // DataV1 or DataV2
pub primary_sale_happened: bool,
pub is_mutable: bool,
pub edition_nonce: Option<u8>,
pub token_standard: Option<TokenStandard>,
pub collection: Option<Collection>,
pub uses: Option<Uses>,
}
Solana Metadata DataV2 Layout
pub struct DataV2 {
pub name: String,
pub symbol: String,
pub uri: String,
pub seller_fee_basis_points: u16,
pub creators: Option<Vec<Creator>>,
pub collection: Option<Collection>,
pub uses: Option<Uses>,
}

Off-Chain Metadata

Most of the information displayed to the user comes from off-chain metadata. Off-chain metadata is in JSON format and hosted by a third party such as arweave.org.

Example Off-Chain Metadata JSON
{
"name": "Avana NFT #500",
"symbol": "NFT1",
"description": "A typical NFT issued on Solana",
"seller_fee_basis_points": 300,
"external_url": "https://www.avanawallet.com",
"edition": "First Edition",
"image": "https://www.arweave.net/xxxxx?ext=png",
"attributes": [
{
"trait_type": "Base",
"value": "Ape"
},
{
"trait_type": "Eyes",
"value": "Big"
},
{
"trait_type": "Mouth",
"value": "Smiling"
},
{
"trait_type": "Level",
"value": 5
},
{
"trait_type": "Stamina",
"value": 5
},
{
"trait_type": "Personality",
"value": "Friendly"
},
{
"display_type": "number",
"trait_type": "Generation",
"value": 2
}
],
"collection": {
"name": "Avana Wallet NFT",
"family": "Avana Wallet"
},
"properties": {
"files": [
{
"uri": "https://www.arweave.net/xxxxx?ext=png",
"type": "image/png"
}
],
"category": "image",
"creators": [
{
"address": "2vMMvWQJ6ADzSPoUTHrK4PGBHeMwemCUD3ruo46N14am",
"share": 100
}
]
}
}

How Avana Displays Metadata

Avana Wallet checks both the on-chain and off-chain data and combines the information in to one aggregate set for the user.

Attributes Sources

AttributeSource
name

Off-Chain

symbol

Off-Chain

collection

On-Chain/Off-Chain*

attributes

Off-Chain

fileUrl(s)

Off-Chain

ownership

On-Chain

updateAuthority

On-Chain

creators

On-Chain

sellerFeeBasisPoints

On-Chain

isMutable

On-Chain

Collections

Early versions of Solana NFTs added collection information to the off-chain metadata (see example below). Newer versions (>v1.1.0) of NFTs store collection information on-chain, which enables more secure authentication and verification. On-chain collections have the same metadata layout as regular NFTs.

NFTs can specify a collection address in the metadata struct. The collection authority then verifies the NFT metadata to confirm that the NFT is part of the collection (verification sets the verified attribute to true). The newer on-chain collection method provides more security and certainty that the collection is authentic.

Reference Metaplex Docs for more information.

Collection On-Chain
pub struct Metadata {
...
pub collection: Option<Collection>,
...
}

pub struct Collection {
pub verified: bool, // Only collection authority can update this value
pub key: Pubkey, // The SPL token mint account of the collection NFT
}
Collection Off-Chain (old method)
{
...
"collection": {
"name": "Lunar Lander XV",
"family": "Lunar Lander"
}
...
}

Grouping

Avana Wallet groups NFTs by common symbols, which helps the user sort and filter their assets. NFTs without symbols are not grouped.