Metadata

Overview

On-chain metadata is a powerful feature of the Cardano blockchain that enables storing data within transactions (CIP-25) or datum in UTXOs (CIP-68). The Anvil API provides flexible options for including metadata in your transactions through a streamlined interface.

Metadata serves several key purposes in the Cardano ecosystem:

  • NFT Information (CIP-25, CIP-68): Store details about tokens like name, description, and image links

  • Transaction Messages (CIP-20): Include human-readable messages or technical information such as:

    • Payment references or receipt identifiers

    • Invoice numbers for business transactions

    • Short notes explaining the purpose of transfers

    • DEX transaction identifiers for tracking operations

  • Protocol-specific Data: Support for custom protocols through specialized metadata formats

How Anvil Handles Metadata

The Anvil API processes metadata through the meta array in your transaction payload. Each entry in this array can contain a label and data.

Supported Label Mappings

Anvil supports the following predefined friendly labels that map to Cardano metadata specifications:

Friendly Label
Numeric Label
Purpose

"message"

674

Transaction messages (CIP-20)

"token"

721

NFT metadata (CIP-25, CIP-68)

If you use a friendly label, Anvil will automatically convert it to the corresponding numeric value.

Metadata Structure

Note: You can use the predefined friendly labels above, any numeric label, or no label at all.

You can use the following structure to define metadata in your transaction payload:

// Complete transaction payload with metadata
const transactionPayload = {
  // Other transaction fields like utxos, changeAddress, etc.
  
  // Metadata array - this is where you define your metadata entries
  meta: [
    // Option 1: Using a predefined friendly string label
    {
      label: "message", // Must be one of: "message" or "token"
      data: { 
        msg: ["This is a transaction message"] 
      }
    },
    
    // Option 2: Using a numeric label
    {
      label: 674, // Can be any number (674, 721, or custom numeric value)
      data: { 
        msg: ["This is another transaction message"] 
      }
    },
    
    // Option 3: No label, direct structure
    {
      data: {
        674: { 
          msg: ["This is a message with direct structure"] 
        }
      }
    }
  ]
};

Behind the scenes, Anvil employs sophisticated metadata handling with these features:

  • Friendly Labels: Convert human-readable labels to their numeric counterparts (e.g., "token" → 721)

  • Structure Merging: Similar metadata entries are intelligently combined

  • Automatic String Chunking: Long strings exceeding Cardano's 64-byte limit are split into arrays

  • Format Validation: Ensures compliance with Cardano transaction specifications

Example: How Anvil API does Structure Merging

When multiple metadata entries use the same label, Anvil merges them instead of overwriting or duplicating:

// Your input: Two separate metadata entries
const data = {
  meta: [
    {
      label: "token",
      data: { 
        "policyId_placeholder": { 
          asset1: { name: "Asset1", description: "First asset" } 
        } 
      }
    },
    {
      label: "token",
      data: { 
        "policyId_placeholder": { 
          asset2: { name: "Asset2", description: "Second asset" } 
        } 
      }
    }
  ]
};

// Transformed by Anvil for on-chain storage: Combined into a single structure
{
  "721": {
    "policyId_placeholder": {
      "asset1": { "name": "Asset1", "description": "First asset" },
      "asset2": { "name": "Asset2", "description": "Second asset" }
    }
  }
}

This allows you to build complex metadata incrementally from different parts of your application.

Example: How Anvil API does Automatic String Chunking

When a string exceeds Cardano's 64-byte limit, Anvil automatically converts it to an array of shorter strings:

// Your input
{
  data: {
    description: "This is a very long description that exceeds the 64-byte limit imposed by Cardano transaction metadata specifications..."
  }
}

// Transformed by Anvil for on-chain storage
{
  data: {
    description: [
      "This is a very long description that exceeds the 64-byte limit ",
      "imposed by Cardano transaction metadata specifications..."
    ]
  }
}

Working with CIP-25 and CIP-68 Metadata (Label 721)

IMPORTANT WARNING: Metadata is only one part of the NFT minting process. For proper CIP-25 and CIP-68 implementation, you should follow the complete minting documentation. Attempting to implement NFT minting by manually constructing transactions with just the metadata structure below will lead to complexity and likely errors. Please refer to the CIP-25 NFT Minting Guide or CIP-68 NFT Minting Guide for the complete implementation.

CIP-25 established the original NFT metadata standard for Cardano, while CIP-68 expanded on this with additional capabilities for evolving NFTs. Most applications support both standards with the following characteristics:

  • Hierarchical Structure: Organized by policy ID and asset name

  • Rich Content Support: Name, description, image, and other media attributes

  • Extensibility: Support for custom attributes beyond the core specification

Note on CIP-68 Implementation: While both CIP-25 and CIP-68 use the same metadata structure under label 721, CIP-68 requires additional implementation steps beyond metadata definition. CIP-68 uses a two-token model (reference NFT label 100 + user token label 222) with the metadata stored in a datum. For complete CIP-68 implementation, see the CIP-68 NFT Minting Guide.

CIP-25 Specification | CIP-68 Specification

Anvil provides three equivalent ways to define CIP-25/CIP-68 metadata:

  1. Using the friendly "token" label

  2. Using the numeric 721 label directly or any other numeric label

  3. Using no label with direct structure

All three approaches result in identical on-chain metadata.

Example

const asset = {
  metadata: {
    name: "Placeholder",
    image: [
      "https://ada-anvil.s3.ca-central-1.amazonaws.com/",
      "logo_pres_V2_3.png",
    ],
    mediaType: "image/png",
    description: "Testing CIP-25 using anvil API",
  },
};

const data = {
  meta: [
    // Option 1: Using friendly "token" label
    {
      label: "token",
      data: {
        "policyId_placeholder": {
          "Placeholder label token": {
            ...asset.metadata,
            name: "Placeholder label token",
          },
        },
      },
    },
    // Option 2: Using numeric 721 label
    {
      label: 721,
      data: {
        "policyId_placeholder": {
          "Placeholder label 721": {
            ...asset.metadata,
            name: "Placeholder label 721",
          },
        },
      },
    },
    // Option 3: No label with direct structure
    {
      data: {
        721: {
          "policyId_placeholder": {
            "Placeholder no label": {
              ...asset.metadata,
              name: "Placeholder no label",
            },
          },
        },
      },
    },
  ],
  changeAddress: "CHANGE_ADDRESS", // Replace with your wallet address
  utxos: "UTXOS", // Replace with your UTXOs
};

Working with CIP-20 Transaction Messages (Label 674)

CIP-20 defines a standard for including human-readable messages in transactions using label 674. These messages are ideal for providing context, receipts, or references within transactions.

Anvil provides four equivalent ways to define CIP-20 transaction messages:

  1. Using the friendly "message" label - Simplest approach that automatically converts to label 674 on-chain

  2. Using the numeric 674 label directly - Same outcome as the friendly label approach

  3. Using no label with direct structure - Maximum control over the final structure

  4. Using the simplified message property - A special Anvil shorthand that handles all the formatting

All approaches result in correctly formatted message metadata on-chain, with each message appearing as an entry in the msg array under label 674.

Example

// Transaction build payload with all four message approaches
const data = {
  meta: [
    // Option 1: Using friendly "message" label
    {
      label: "message",
      data: {
        msg: ["This is the first approach with the friendly label"]
      }
    },
    // Option 2: Using numeric 674 label
    {
      label: 674,
      data: {
        msg: ["This is the second approach with the numeric label"]
      }
    },
    // Option 3: No label with direct structure
    {
      data: {
        674: {
          msg: ["This is the third approach with direct structure"]
        }
      }
    },
  ],
  // Option 4: Using the simplified message property
  message: ["This is the fourth approach with the message property"],
  changeAddress: "CHANGE_ADDRESS", // Replace with your wallet address
  utxos: "UTXOS", // Replace with your UTXOs
};

Conclusion

The Anvil API provides a flexible system for incorporating metadata in your Cardano transactions:

  • Use the CIP-25/CIP-68 format (label 721) for NFT metadata

  • Use the CIP-20 format (label 674) for transaction messages

  • Choose the definition approach that best fits your workflow - friendly labels or direct numeric labels

In all cases, the resulting on-chain metadata follows the respective CIP standards, ensuring compatibility with wallets, explorers, and applications that interact with the Cardano blockchain.

Further Resources

Mint a Simple NFT (CIP-25)Mint a Simple NFT (CIP-68)

Last updated

Was this helpful?