Before the Token Extensions Program and the Token Metadata Interface, the process of adding extra data to a Mint Account required creating a Metadata Account through the Metaplex Metadata Program.
The MetadataPointer
extension now enables a Mint Account to specify the
address of its corresponding Metadata Account. This flexibility allows the Mint
Account to point to any account owned by a program that implements the Token
Metadata Interface.
The Token Extensions Program directly implements the Token Metadata Interface,
made accessible through the TokenMetadata
extension. With the TokenMetadata
extension, the Mint Account itself can now store the metadata.
In this guide, we will demonstrate how to create a Mint Account that enables
both the MetadataPointer
and TokenMetadata
extensions. This setup simplifies
the process of adding metadata to a Mint Account by storing all the data on a
single account. Here is the
final script.
Token Metadata Interface Overview
The Token Metadata Interface is designed to standardize and simplify the process of adding metadata to tokens by defining the data structure and set of instructions for handling metadata.
The Token Metadata Interface can be implemented by any program. This allows developers the flexibility to create custom Metadata Programs while reducing the challenges related to ecosystem integration for their program.
With this common interface, wallets, dApps, and onchain programs can universally access token metadata, and tools for creating or modifying metadata become universally compatible.
Metadata Interface Fields
The Token Metadata Interface defines a standard set of data fields for
TokenMetadata
,
as outlined below. Additionally, it allows for the inclusion of custom data
fields within the additional_metadata
section, formatted as key-value pairs.
Metadata Interface Instructions
The Metadata Interface specifies the following instructions:
-
Initialize: Initialize the basic token metadata fields (name, symbol, URI).
-
UpdateField: Updates an existing token metadata field or adds to the
additional_metadata
if it does not already exist. Requires resizing the account to accommodate for addition space. -
RemoveKey: Deletes a key-value pair from the
additional_metadata
. This instruction does not apply to the required name, symbol, and URI fields. -
UpdateAuthority: Updates the authority allowed to change the token metadata.
-
Emit: Emits the token metadata in the format of the
TokenMetadata
struct. This allows account data to be stored in a different format while maintaining compatibility with the Interface standards.
Getting Started
Start by opening this Solana Playground link with the following starter code.
If it is your first time using Solana Playground, you'll first need to create a Playground Wallet and fund the wallet with devnet SOL.
If you do not have a Playground wallet, you may see a type error within the
editor on all declarations of pg.wallet.publicKey
. This type error will clear
after you create a Playground wallet.
To get devnet SOL, run the solana airdrop
command in the Playground's
terminal, or visit this devnet faucet.
Once you've created and funded the Playground wallet, click the "Run" button to run the starter code.
Add Dependencies
Let's start by setting up our script. We'll be using the @solana/web3.js
,
@solana/spl-token
, and @solana/spl-token-metadata
libraries.
Replace the starter code with the following:
Mint Setup
Next, define the properties of the Mint Account we'll be creating in the following step.
Next, determine the size of the new Mint Account and calculate the minimum lamports needed for rent exemption.
In the code snippet below, we allocate 4 bytes for the TokenMetadata
extension
and then calculate the space required by the metadata.
With Token Extensions, the size of the Mint Account will vary based on the extensions enabled.
Build Instructions
Next, let's build the set of instructions to:
- Create a new account
- Initialize the
MetadataPointer
extension - Initialize the remaining Mint Account data
- Initialize the
TokenMetadata
extension and token metadata - Update the token metadata with a custom field
First, build the instruction to invoke the System Program to create an account and assign ownership to the Token Extensions Program.
Next, build the instruction to initialize the MetadataPointer
extension for
the Mint Account. In this example, the metadata pointer will point to the Mint
address, indicating that the metadata will be stored directly on the Mint
Account.
Next, build the instruction to initialize the rest of the Mint Account data. This is the same as with the original Token Program.
Next, build the instruction to initialize the TokenMetadata
extension and the
required metadata fields (name, symbol, URI).
For this instruction, use the Token Extensions Program as the programId
, which
functions as the "Metadata Program". Additionally, the Mint Account's address is
used as the metadata
to indicate that the Mint itself is the "Metadata
Account".
Next, build the instruction to update the metadata with a custom field using the
UpdateField
instruction from the Token Metadata Interface.
This instruction will either update the value of an existing field or add it to
additional_metadata
if it does not already exist. Note that you may need to
reallocate more space to the account to accommodate the additional data. In this
example, we allocated all the lamports required for rent up front when creating
the account.
Send Transaction
Next, add the instructions to a new transaction and send it to the network. This
will create a Mint Account with the MetadataPointer
and TokenMetadata
extensions enabled and store the metadata on the Mint Account.
Some token extension instructions are required to be atomically ordered before initializing the mint. While others must be after. Having these instructions "out of order" may result in your transaction failing.
Read Metadata from Mint Account
Next, check that the metadata has been stored on the Mint Account.
Start by fetching the Mint Account and reading the MetadataPointer
extension
portion of the account data:
Next, read the Metadata portion of the account data:
Run the script by clicking the Run
button. You can then inspect the
transaction details on SolanaFM.
You should also see console output similar to the following:
Remove Custom Field
To delete a custom field from the metadata, use the RemoveKey
instruction from
the Token Metadata Interface.
The idempotent
flag is used to specify whether the transaction should fail if
the key does not exist on the account. If the idempotent flag is set to true
,
then the instruction will not error if the key does not exist.
Run the script by clicking the Run
button. You can then inspect the
transaction details and Mint Account on SolanaFM.
You should also see console output similar to the following:
Conclusion
By enabling both the MetadataPointer
and TokenMetadata
extensions, the Mint
Account can now directly store token metadata. This feature simplifies the
process of adding metadata to a Mint Account.