Laugharne / Token-Metadata-with-Token-Extensions-on-Solana

The Token Extensions Program directly implements the SPL Token Metadata Interface, made accessible through the Token Metadata extension. With the Token Metadata extension, the Mint Account itself can now store the metadata directly on the Solana blockchain.

Home Page:https://www.youtube.com/watch?v=l7EyQUlNAdw

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

This is a transcription of a YouTube video. Among the relevant resources for learning to code, I found this video particularly interesting.

This content presents the opinions and perspectives of industry experts or other individuals.   The opinions expressed in this content do not necessarily reflect my opinion.

Readers are encouraged to verify the information on their own and seek professional advice before making any decisions based on this content.

Token Metadata with Token Extensions on Solana



Full written guide on the Token Metadata token extension: How to use the Metadata Pointer extension | Solana. The Token Extensions Program directly implements the SPL Token Metadata Interface, made accessible through the Token Metadata extension. With the Token Metadata extension, the Mint Account itself can now store the metadata directly on the Solana blockchain.

00:15

Introduction to Using the Metadata Token Extension

In this video, Nick from the Solana Foundation Developer Team explains how to use the metadata token extension on the new SPL token extension program. He demonstrates the process using VS Code and provides step-by-step instructions.

Initializing the Project and Installing Dependencies

  • 00:38 Use yarn init -y to initialize a project JSON file.
  • Install TypeScript support, Solana Web3JS, SPL token package, token metadata, and Solana Developers Helper package as dependencies.

Loading Key Pair and Creating Connection

  • 02:00 Load a key pair with devnet sol.
  • Create a connection to the cluster using devnet.
  • Use the helper library to load the key pair from the file system.

Generating a New Random Mint Address

  • 02:29 Generate a new random mint address using Keypair.generate().
  • Log out the mint address and payer addresses for verification.

Filling in Metadata Information

  • 03:04 Create a new object called "metadata" of type TokenMetadata format.
  • 03:24 Fill in required fields such as mint address, name, symbol, and URI (JSON file located off-chain).
  • 04:58 Add additional metadata information as key-value pairs within an array.

Calculating Mint Space

  • 05:18 Use getMintLength() function from SPL token packages to calculate mint space needed for extensions.
  • Pass in an array of extensions being used (in this case, only metadata extension).

05:52

The tutorial covers initializing a project, installing dependencies, loading key pairs, creating connections, generating random mint addresses, filling in metadata information including additional metadata fields stored on-chain. It also explains how to calculate mint space needed for extensions.

06:19

Token Metadata Extension

In this section, the speaker discusses the token metadata extension and its variable extension type. The length and space required on-chain for the metadata depend on the buffer length of the metadata. The URI, name, and symbol are all variable lengths.

Token Metadata Extension

  • The token metadata extension is a variable extension type.
  • The length and space needed on-chain depend on the buffer length of the metadata.
  • The URI, name, and symbol are all variable lengths.

06:36

Calculating Space for Token Extensions

This section explains how to calculate space for token extensions. It mentions that certain constant values come from the SPL token package and act as discriminators. Two bytes each are allocated for type size and length size.

Calculating Space for Token Extensions

import { ExtensionType, TYPE_SIZE, LENGTH_SIZE, getMinLen } from "@solan/spl-token";

...

const metadataSpace = TYPE_SIZE + LENGTH_SIZE + ...
  • 06:42 Space calculation for token extensions differs from other token extensions.
  • 07:08 Constant values from the SPL token package act as discriminators.
  • 07:23 Two bytes each are allocated for TYPE_SIZE and LENGTH_SIZE.

06:53

Determining Length of Metadata

Here, it is explained how to determine the actual length of metadata. The pack() function from within the SPL token metadata package can be used to obtain this information.

Determining Length of Metadata

const metadataSpace = TYPE_SIZE + LENGTH_SIZE + pack(metadata).length
  • @@07:37 Use the pack function from within the SPL token metadata package.
  • Pass in your metadata object to get the actual on-chain space needed.

07:28

Allocating Lamp Ports for Mint

This section discusses allocating lampports (minimum balance for rent exemption) for mint creation. By adding together mint space and metadata space, you can determine how many lamp ports are needed.

Allocating Lamp Ports for Mint

const metadataSpace = TYPE_SIZE + LENGTH_SIZE + pack(metadata).length

const lamports = await connection.getMinimumBalanceForRentExemption(
    mintspace + metadatSpace
)
  • 08:10 Add mint space and metadata space to determine the total lamp ports needed.
  • This determines the minimum balance for rent exemption.

08:04

Building Instructions for Token Creation

Here, the speaker explains how to build instructions for token creation. The first step is to create the account on-chain by initializing it using the system program class.

Building Instructions for Token Creation

const createAccountIx = systemProgram.createAccount({
    fromPubKey      : payer.publicKey,
    newAccountPubkey: mint.publicKey,
    lamport         : lamports,
    programId       : TOKEN_2022_PROGRAM_ID  // from `spl-token` package
})
  • 08:27 Create the account on-chain by initializing it using the system program class.
  • 08:40 Use the createAccount() instruction from the system program class.
  • 10:05 Pass in necessary information such as payer pubkey, new account pubkey, mint space, and program ID.

10:16

Initializing Metadata and Mint

This section covers initializing metadata and mint. The metadata initialization uses a helper function from the spl-token package. The mint initialization uses another helper function called "create initialize mint."

Initializing Metadata and Mint

const initializeMetadataPointerIx = createInitializeMetadataPointerInstruction({
    mint.publicKey,
    payer.publicKey,
    mint.publicKey,
    TOKEN_2022_PROGRAM_ID
})

const initializeMintIx = createInitializeMintInstruction({
    mint.publicKey,
    2, // decimals
    payer.publicKey,
    null,
})
  • 10:30 Initialize metadata using a helper function from the spl-token package.
  • 11:25 Pass in parameters such as mint pubkey, update authority, metadata pointer (which can be set as the mint itself), and token program ID.
  • 11:35 Initialize mint using a helper function called createInitializeMintInstruction.
  • 12:19 Pass in parameters such as mint pubkey, number of decimals, mint authority (can be same as payer), and freeze authority if needed.

12:28

Initializing the Metadata Account

12:44 In this section, we learn about initializing the metadata account using the SPL token metadata package. The instruction for initialization is called "create initialize" and it takes similar parameters to other instructions. We pass in the mint key, metadata account key (which is also the mint key in this case), and optionally, the mint authority.

import { TokenMetadata, createInitializeInstruction } from from "@solana/spl-token-metadata";

...

const initializeMetadataIx = createInitializeInstruction({
    mint           : mint.publicKey,
    metadata       : mint.publicKey,
    mintAuthority  : payer.publicKey,
    name           : metadata.name,
    symbol         : metadata.symbol,
    uri            : metadata.uri,
    programId      : TOKEN_2022_PROGRAM_ID,
    updateAuthority: payer.publicKey
});
  • The create initialize instruction is used to initialize the metadata account.
  • Parameters include the mint key, metadata account key (same as mint key), and optionally, the mint authority.
  • We can provide additional metadata information such as name, symbol, URI, program ID, and update authority.

14:20

Initializing Onchain Metadata Fields

14:40 Here we discuss how to initialize individual onchain metadata fields using separate instructions. We demonstrate how to create an instruction for updating a single field.

const updateMetadataField = createUpdateFieldInstruction({
    metadata       : mint.publicKey,
    programId      : TOKEN_2022_PROGRAM_ID,
    updateAuthority: payer.publicKey,
    field          : metadata.additionalMetadata[0][0],
    value          : metadata.additionalMetadata[0][1]
});
  • To update individual onchain metadata fields, we use separate instructions.
  • 15:00 We can create an instruction for updating a specific field using createUpdateFieldInstruction() from SPL token metadata package.
  • Parameters include the metadata account key (mint key), program ID (token 22), update authority (same as metadata pointer's payer dot key).
  • 16:42 Each field has its own index in the additional fields array. We can extract values from our existing additional fields array by specifying their respective indices.

17:06

Building Transaction with Instructions

In this section, we learn how to build a transaction with all the necessary instructions and send it to be confirmed on the blockchain.

const transaction = Transaction().add({
    createAccountIx,
    initializeMetadataPointerIx,
    initializeMintIx,
    initializeMetadataIx,
    updateMetadataField
  });
  • We use web3.js library to create a new transaction object.
  • 17:39 All previously created instructions are added to this transaction object using add() method.
  • 17:45 The order of adding instructions is important; some token extensions need to be initialized before the mint.
  • Once the transaction is built, we can send and confirm it using the sendAndConfirmTransaction function.
  • The function requires a connection object, the transaction itself, and an array of signers (in this case, payer and mint keys).

18:43

Sending and Confirming Transaction

Here we discuss how to send and confirm the transaction on the blockchain.

const sig = await sendAndConfirmRawTransaction(
    connection,
    transaction,
    [payer, mint]
);

console.log("sig:", sig);
  • We use the sendAndConfirmRawTransaction() function to send and confirm our transaction.
  • 18:51 The function requires a connection object, the transaction itself, and an array of signers (payer and mint keys).
  • 19:11 After confirmation, we can display the confirmed transaction details.

Logging Out the Signature

19:16 In this section, the speaker discusses logging out just the signature.

const chainMetada = await getTokenMetadata(
    connection,
    mint.publicKey,
    [payer, mint]
);

console.log(chainMetada);
  • The transaction needs to be confirmed by the blockchain before using helper functions in the SPL token metadata program.
  • To retrieve metadata, you need your connection to the same cluster and the mint address where the metadata is stored.
  • 19:46 Use the getTokenMetadata() helper function from spl-token'metadata package, passing in your connection and mint public key.
  • 20:06 Open up the terminal and run esrun ./mint.ts (or npx esrun if not installed globally) with your script to display the metadata once it's confirmed by the blockchain.

20:42

Conclusion

This section concludes how to use the token metadata extension on the token extension program.


Transcription

  • 00:00:05 ➜ hello everyone gmgm I'm Nick from the
  • 00:00:07 ➜ Solana foundation deell team and in this
  • 00:00:09 ➜ video I'm going to go over how to use
  • 00:00:10 ➜ the metadata token extension on the new
  • 00:00:12 ➜ SPL token extension program so you can
  • 00:00:15 ➜ see here I have vs code open I have a
  • 00:00:17 ➜ blank directory there's nothing in here
  • 00:00:19 ➜ and I can go ahead and LS this directory
  • 00:00:21 ➜ nothing comes out so we know it's blank
  • 00:00:24 ➜ so the first thing we're going to do is
  • 00:00:25 ➜ we're going to go ahead and initialize a
  • 00:00:26 ➜ project Json so we're going to use yarn
  • 00:00:28 ➜ knit Dy just to give us the defaults we
  • 00:00:31 ➜ can see our package Json comes open and
  • 00:00:33 ➜ then we're going to go ahead and install
  • 00:00:36 ➜ all of our dependencies so specifically
  • 00:00:38 ➜ I'm going to be adding typescript
  • 00:00:40 ➜ support and Solana web3js the SPL token
  • 00:00:43 ➜ package token metadata and the salon
  • 00:00:46 ➜ developers helper package in order to
  • 00:00:47 ➜ load some key pairs for my file system
  • 00:00:50 ➜ now that all of these have cleared out
  • 00:00:52 ➜ have actually installed we'll go ahead
  • 00:00:53 ➜ and create a new file and we'll just
  • 00:00:55 ➜ name this mint. TS and let's go ahead
  • 00:00:58 ➜ and get to some coding so the first
  • 00:01:00 ➜ thing we're going to need to do is we're
  • 00:01:01 ➜ going to need to load in a key pair that
  • 00:01:03 ➜ has some devnet sol create a connection
  • 00:01:04 ➜ to the cluster itself create our mint
  • 00:01:06 ➜ and then we can actually fill in all the
  • 00:01:08 ➜ metadata we want so the first thing we
  • 00:01:09 ➜ going to do is go ahead and create that
  • 00:01:14 ➜ connection and like I said for this
  • 00:01:17 ➜ connection we're going to connect to
  • 00:01:18 ➜ devnet so we can go ahead and load in the
  • 00:01:20 ➜ cluster URL for devnet and then I'm going
  • 00:01:23 ➜ to load in a payer key pairer that's
  • 00:01:24 ➜ going to actually pay for all the
  • 00:01:26 ➜ transactions and the cost of storage on
  • 00:01:28 ➜ the Solana Network and I'm actually
  • 00:01:30 ➜ going to use the helper library for this
  • 00:01:32 ➜ and I'm going to load in the key pair
  • 00:01:35 ➜ from the file system get key pair from
  • 00:01:38 ➜ file again from the Solana developers
  • 00:01:40 ➜ helper package and I just have to pass
  • 00:01:42 ➜ in a file path here and this is relative
  • 00:01:44 ➜ on my file system now I have the Solana
  • 00:01:47 ➜ CLI installed on my system so I can run
  • 00:01:49 ➜ Solana address and you can see there's
  • 00:01:51 ➜ this Nick b1d address and that's the
  • 00:01:52 ➜ devnet address I'm going use to fund
  • 00:01:54 ➜ everything and I'm just going to load in
  • 00:01:56 ➜ that particular key pair uh using
  • 00:01:59 ➜ JavaScript using the helper and on Linux
  • 00:02:02 ➜ that's located in your home directory so
  • 00:02:04 ➜ tilta sl. config Solana id.
  • 00:02:09 ➜ Json now that we have our payer and
  • 00:02:12 ➜ again this actual address has um some
  • 00:02:15 ➜ devnet sol on it so you can see that I
  • 00:02:17 ➜ don't need to do any aird drops in order
  • 00:02:18 ➜ to do this because I already have devnet
  • 00:02:20 ➜ sol if you don't already have devnet
  • 00:02:21 ➜ sol you can go ahead and do an airdrop
  • 00:02:23 ➜ easy day so next we're going to actually
  • 00:02:25 ➜ generate a new random mint this is going
  • 00:02:27 ➜ to be the mint address that our uh new
  • 00:02:30 ➜ mint that we're going to create our new
  • 00:02:31 ➜ token mint is going to actually hold so
  • 00:02:34 ➜ new key payer or key.
  • 00:02:36 ➜ generate and just for the sake of
  • 00:02:38 ➜ logging this out we'll go ahead and log
  • 00:02:40 ➜ it to the console just to show that the
  • 00:02:42 ➜ we have addresses here so mint dot key.
  • 00:02:45 ➜ 2 base
  • 00:02:50 ➜ 58 and then we'll go ahead and do the
  • 00:02:52 ➜ same thing for our payer just to log out
  • 00:02:54 ➜ those addresses so the next thing we're
  • 00:02:55 ➜ going to want is we're going to actually
  • 00:02:56 ➜ start filling in all the metadata we're
  • 00:02:58 ➜ going to want to put in into our
  • 00:03:00 ➜ metadata token extension so we'll go
  • 00:03:02 ➜ ahead and create a new object call it
  • 00:03:04 ➜ metadata and we're actually going to
  • 00:03:06 ➜ type this to the Token metadata format
  • 00:03:10 ➜ the interface that comes with the SPL
  • 00:03:12 ➜ token metadata package and you can see
  • 00:03:14 ➜ we already have our type error because
  • 00:03:15 ➜ we don't have all the required
  • 00:03:16 ➜ information filled in and you can see
  • 00:03:18 ➜ here with uh vs code I can see all of
  • 00:03:21 ➜ the required fields that we need so we
  • 00:03:22 ➜ have our mint address our name symbol
  • 00:03:24 ➜ URI and then some additional information
  • 00:03:26 ➜ here so we'll start with the basics
  • 00:03:28 ➜ we'll put in our mint here and
  • 00:03:29 ➜ specifically this is looking for the
  • 00:03:31 ➜ mint key pair or sorry the public key
  • 00:03:34 ➜ and then we'll give it a name and in
  • 00:03:35 ➜ this case I'm just going to call this token
  • 00:03:38 ➜ opos and give it a symbol also
  • 00:03:43 ➜ oppos in fact I'll go ahead and update
  • 00:03:45 ➜ this to uh only possible on
  • 00:03:49 ➜ solada and the last required piece of
  • 00:03:51 ➜ information that we actually need is our
  • 00:03:53 ➜ Ur now this URI is typical Json file
  • 00:03:57 ➜ that's going to be located offchain so
  • 00:03:59 ➜ in our case I'm just going to load in
  • 00:04:01 ➜ this uh metadata Json file that's stored
  • 00:04:04 ➜ within the salon developers oost assets
  • 00:04:07 ➜ it's just a generic Json file has some
  • 00:04:09 ➜ information in it that way the Explorers
  • 00:04:11 ➜ will actually be able to display some
  • 00:04:12 ➜ information now the last thing that
  • 00:04:14 ➜ we're going to need within here is we
  • 00:04:17 ➜ need this additional metadata field now
  • 00:04:21 ➜ this is required to be an array by
  • 00:04:22 ➜ default and we have to initialize it as
  • 00:04:24 ➜ a blank array but this is actually one
  • 00:04:27 ➜ of the really cool things about token
  • 00:04:28 ➜ metadata and specifically the token
  • 00:04:30 ➜ metadata extension on the token
  • 00:04:33 ➜ extension program is that this
  • 00:04:35 ➜ additional metadata is actually stored
  • 00:04:37 ➜ on chain it's an account State on The
  • 00:04:38 ➜ Solana Ledger so that way you can
  • 00:04:40 ➜ actually use the blockchain to access
  • 00:04:42 ➜ any and all of this metadata you have in
  • 00:04:44 ➜ here so it's pretty cool so we'll fill
  • 00:04:46 ➜ in a couple of bits of information and
  • 00:04:48 ➜ this takes a each of these uh data
  • 00:04:51 ➜ pieces of data within this additional
  • 00:04:53 ➜ metadata attribute here it's just a key
  • 00:04:56 ➜ value uh key value pair so we need our
  • 00:04:59 ➜ key here and our value here you could
  • 00:05:02 ➜ put any number of bits of information in
  • 00:05:04 ➜ here you want you are going to have to
  • 00:05:06 ➜ pay for that rent when you actually
  • 00:05:07 ➜ create your mint but uh you know with a
  • 00:05:09 ➜ script like this super easy to do so now
  • 00:05:12 ➜ that we have our metadata actually set
  • 00:05:13 ➜ up we can go ahead and start doing all
  • 00:05:15 ➜ of the token extension magic here so
  • 00:05:17 ➜ we're going to need to get a couple of
  • 00:05:18 ➜ bits of information and specifically we
  • 00:05:20 ➜ need to know how much space we need to
  • 00:05:22 ➜ allocate on the Solana blockchain in
  • 00:05:23 ➜ order to actually use this extension so
  • 00:05:26 ➜ we're going to go ahead and figure out
  • 00:05:29 ➜ what are mint space is going to be so
  • 00:05:32 ➜ let's get our mint space and we actually
  • 00:05:35 ➜ can use some of the helper functions
  • 00:05:36 ➜ within the token extension packages or
  • 00:05:38 ➜ sorry the SPL token packages and this
  • 00:05:41 ➜ helper function is called get min length
  • 00:05:44 ➜ uh sorry get mint length and this
  • 00:05:46 ➜ actually passes in an array of all the
  • 00:05:49 ➜ extensions that we're going to be using
  • 00:05:51 ➜ on this particular mint that we're
  • 00:05:53 ➜ creating in this particular case we're
  • 00:05:55 ➜ actually only going to be using the
  • 00:05:56 ➜ metadata extension so when we have to so
  • 00:06:00 ➜ when we are calculating our mint space
  • 00:06:02 ➜ we just need the metadata pointer
  • 00:06:04 ➜ because this bit of information is going
  • 00:06:05 ➜ to be stored on chain it's stored on the
  • 00:06:07 ➜ mint itself so the next bit of
  • 00:06:09 ➜ information is we actually need to
  • 00:06:10 ➜ figure out how much space our metadata
  • 00:06:13 ➜ is going to take so let's go ahead and
  • 00:06:15 ➜ calculate that
  • 00:06:18 ➜ now and with the token metadata
  • 00:06:21 ➜ extension it's what's known as a
  • 00:06:23 ➜ variable extension type so the actual
  • 00:06:25 ➜ length and the actual space that you
  • 00:06:27 ➜ need to allocate on chain is going to
  • 00:06:29 ➜ differ depending on the actual buffer
  • 00:06:32 ➜ the buffer length of your all the
  • 00:06:34 ➜ metadata you want to you want to put on
  • 00:06:35 ➜ chain so your URI is a variable this
  • 00:06:38 ➜ name is a variable length this symbol is
  • 00:06:40 ➜ a variable length so we actually have to
  • 00:06:42 ➜ calculate it slightly different than we
  • 00:06:44 ➜ would uh calculate the space slightly
  • 00:06:46 ➜ different than we normally would for all
  • 00:06:47 ➜ of the other token extensions and
  • 00:06:50 ➜ specifically we're going to need a few
  • 00:06:51 ➜ bits of information here we need the
  • 00:06:53 ➜ type size and then we need the size for
  • 00:06:56 ➜ the length and these two pieces of
  • 00:06:58 ➜ information these are constant values
  • 00:07:01 ➜ that actually come from the SPL token
  • 00:07:03 ➜ package and these effectively think of
  • 00:07:05 ➜ these like a discriminator uh so that
  • 00:07:08 ➜ way the onchain program is actually
  • 00:07:10 ➜ keeping a a really big buffer of all of
  • 00:07:12 ➜ the data you kind of think of it like
  • 00:07:14 ➜ that that you're actually putting on
  • 00:07:15 ➜ chain and this makes it so it can be
  • 00:07:17 ➜ properly deserialized so these are
  • 00:07:20 ➜ constants they're actually two bytes
  • 00:07:21 ➜ each so two bytes for the type length
  • 00:07:23 ➜ and two byes for the length size so the
  • 00:07:25 ➜ next thing we need is we need to
  • 00:07:26 ➜ actually figure out the actual length of
  • 00:07:28 ➜ our metadata itself s to this metadata
  • 00:07:30 ➜ object so from within the SPL token
  • 00:07:34 ➜ metadata package we can load the pack
  • 00:07:36 ➜ function this is the helper function
  • 00:07:38 ➜ built in and specifically we can pass
  • 00:07:40 ➜ this our metadata object and it's just
  • 00:07:42 ➜ going to tell us the actual onchain
  • 00:07:45 ➜ space that is going to be needed for
  • 00:07:46 ➜ this metadata now that we have these two
  • 00:07:49 ➜ separate pieces of information and note
  • 00:07:50 ➜ that they are separate for a reason and
  • 00:07:52 ➜ I'll touch on that in a second uh we can
  • 00:07:54 ➜ actually ask the blockchain to tell us
  • 00:07:56 ➜ how many lamp ports we need in order to
  • 00:07:58 ➜ allocate our mint
  • 00:08:04 ➜ so we can get our minimum balance for
  • 00:08:05 ➜ rent exemption and we need to use our
  • 00:08:08 ➜ mint space and our metadata space so we
  • 00:08:11 ➜ can just add both of these together here
  • 00:08:13 ➜ and now we'll get our total lamp ports
  • 00:08:15 ➜ that we need so now that we know how
  • 00:08:16 ➜ many lamp ports we need we can actually
  • 00:08:18 ➜ start building our all the instructions
  • 00:08:20 ➜ that we're going to need in order to
  • 00:08:22 ➜ create our token with our metadata so
  • 00:08:24 ➜ the first thing we'll need to do is we
  • 00:08:26 ➜ need to actually create the account on
  • 00:08:27 ➜ chain so we need to initialize the account
  • 00:08:29 ➜ so let's call this the create account
  • 00:08:33 ➜ instruction and we're going to open the
  • 00:08:35 ➜ system program class and we're going to
  • 00:08:38 ➜ get the create account um function and
  • 00:08:42 ➜ we can pass in all the required
  • 00:08:43 ➜ information here our from Pub Key is
  • 00:08:45 ➜ going to be our
  • 00:08:47 ➜ payer pubkey because this is going to be
  • 00:08:49 ➜ the account that's going to pay for all
  • 00:08:51 ➜ of the transaction costs and the the
  • 00:08:53 ➜ actual rent that we're actually going to
  • 00:08:54 ➜ need to store on chain we're going to
  • 00:08:55 ➜ need our new account Pub Key and this is
  • 00:08:57 ➜ going to be our mint itself
  • 00:08:59 ➜ we need to know the exact space that we
  • 00:09:01 ➜ need and this specifically is going to
  • 00:09:03 ➜ be our mint
  • 00:09:05 ➜ space and the reason why this is
  • 00:09:08 ➜ different it's not our total space our
  • 00:09:10 ➜ mint and our metadata space is because
  • 00:09:12 ➜ with token extensions certain token
  • 00:09:14 ➜ extensions are required to be
  • 00:09:17 ➜ implemented directly on the mint itself
  • 00:09:19 ➜ like having a pointer um such as the
  • 00:09:21 ➜ metadata pointer these are required to
  • 00:09:23 ➜ be initialized before the mint is
  • 00:09:26 ➜ actually initialized and then after the
  • 00:09:28 ➜ mint is initialized Iz and we'll go
  • 00:09:29 ➜ through that instruction here in a
  • 00:09:30 ➜ moment then we can actually uh deal with
  • 00:09:34 ➜ all of our actual metadata so when
  • 00:09:36 ➜ you're creating when you're working with
  • 00:09:37 ➜ token extensions you actually have to
  • 00:09:39 ➜ make sure that you have the exact amount
  • 00:09:41 ➜ of space required for the mint itself
  • 00:09:44 ➜ when you are creating the initial
  • 00:09:47 ➜ account we need to tell it this
  • 00:09:49 ➜ instruction how many lamp orts we need
  • 00:09:51 ➜ and then finally we need to tell it the
  • 00:09:53 ➜ program ID specifically this is going to
  • 00:09:55 ➜ be the owner program for this account
  • 00:09:57 ➜ since we're using the token extension
  • 00:09:59 ➜ program also known as token 22 we can
  • 00:10:02 ➜ pass in the token
  • 00:10:04 ➜ 22 uh program ID that also gets pulled
  • 00:10:08 ➜ in from the um from the SPL token
  • 00:10:11 ➜ package so now that we've created our
  • 00:10:14 ➜ account initialization uh instruction we
  • 00:10:16 ➜ need to actually start initializing the
  • 00:10:18 ➜ different other the creating the other
  • 00:10:20 ➜ instructions that we're going to need to
  • 00:10:22 ➜ actually initialize our token the next
  • 00:10:23 ➜ thing we're going to need is to
  • 00:10:25 ➜ initialize our metadata
  • 00:10:30 ➜ and we're going to use this helper
  • 00:10:31 ➜ function that gets pulled in from the
  • 00:10:33 ➜ Tok the SPL token package and we can go
  • 00:10:35 ➜ ahead and start passing in all the bits
  • 00:10:38 ➜ of information we need the first
  • 00:10:40 ➜ parameter that we need for this
  • 00:10:41 ➜ instruction is our mint itself so that's
  • 00:10:43 ➜ our mint dot key the next one is our
  • 00:10:45 ➜ update Authority and this can be
  • 00:10:48 ➜ whatever uh address you want in my case
  • 00:10:51 ➜ I'm going to set this just to the payer
  • 00:10:53 ➜ account since I'm loading that in from
  • 00:10:54 ➜ my file system the next one is going to
  • 00:10:56 ➜ be the actual address that's going to
  • 00:10:58 ➜ hold the metadata itself the pointer to
  • 00:11:00 ➜ the metadata now one of the cool things
  • 00:11:02 ➜ about token extensions and the token 22
  • 00:11:05 ➜ program is that the mint itself can be
  • 00:11:08 ➜ your metadata program so we're actually
  • 00:11:10 ➜ just going to do that here we're going
  • 00:11:11 ➜ to tell it that our mint. public key is
  • 00:11:14 ➜ our metadata program and then we need to
  • 00:11:16 ➜ need we need to tell it our um whatever
  • 00:11:20 ➜ Pro token program we want to use in this
  • 00:11:22 ➜ case we're going to use token 22 now
  • 00:11:24 ➜ that we've initialized our metadata we
  • 00:11:25 ➜ can we need to initialize the mint
  • 00:11:30 ➜ and again we're going to use the helper
  • 00:11:32 ➜ function for this create initialize mint
  • 00:11:39 ➜ instruction and with the create
  • 00:11:41 ➜ initialized mint instruction helper
  • 00:11:44 ➜ function and with the create initialize
  • 00:11:46 ➜ mint instruction helper we're going to
  • 00:11:47 ➜ pass in very similar parameters we did
  • 00:11:49 ➜ on the previous one except for this time
  • 00:11:52 ➜ we're going to pass in our public key
  • 00:11:53 ➜ first for our mint the next one is the
  • 00:11:55 ➜ number of decimals we want so I'm going
  • 00:11:56 ➜ to put this at two decimals
  • 00:12:00 ➜ and then the next parameter is the
  • 00:12:02 ➜ actual mint Authority itself in this
  • 00:12:04 ➜ case I'm going to use my payer again
  • 00:12:06 ➜ since I already have that account set up
  • 00:12:08 ➜ and ready to
  • 00:12:10 ➜ go and then the next parameter is the
  • 00:12:13 ➜ freeze Authority if we really want one
  • 00:12:14 ➜ in this case we don't need one and the
  • 00:12:16 ➜ last parameter is the token program
  • 00:12:18 ➜ we're going to use so now that we have
  • 00:12:20 ➜ these instructions set up we can move on
  • 00:12:21 ➜ to the next one and we actually need to
  • 00:12:23 ➜ initialize our metadata itself and I'm
  • 00:12:25 ➜ actually going to change this to
  • 00:12:26 ➜ metadata pointer instruction because
  • 00:12:27 ➜ that's more IIT of what we're doing so
  • 00:12:30 ➜ we'll go ahead and initialize our our
  • 00:12:32 ➜ metadata account
  • 00:12:37 ➜ itself and this particular instruction
  • 00:12:39 ➜ for initializing the metadata is
  • 00:12:41 ➜ actually going to come from the SPL
  • 00:12:43 ➜ token metadata package and this
  • 00:12:45 ➜ instruction is called create initialize
  • 00:12:52 ➜ instruction and again you can see right
  • 00:12:54 ➜ here it's coming from SPL token
  • 00:12:57 ➜ metadata but it takes very similar
  • 00:12:59 ➜ parameters to all the other instructions
  • 00:13:00 ➜ we've already dealt with except for this
  • 00:13:02 ➜ one is in an object notation so we can
  • 00:13:05 ➜ pass in all the details that we need the
  • 00:13:07 ➜ first thing is our mint itself which
  • 00:13:09 ➜ like you guessed it is our mint dot key
  • 00:13:12 ➜ now we need our metadata account itself
  • 00:13:14 ➜ and like I mentioned earlier because
  • 00:13:16 ➜ we're initializing our mint to be our
  • 00:13:18 ➜ metadata account this is also going to
  • 00:13:21 ➜ be our mint dot key and then if we need
  • 00:13:24 ➜ to provide a mint a mint Authority in
  • 00:13:26 ➜ this case we're using our payer dot key
  • 00:13:29 ➜ since we already have that and now we
  • 00:13:30 ➜ can actually pass in the metadata
  • 00:13:32 ➜ information that we want so since we
  • 00:13:34 ➜ already have uh set up our metadata
  • 00:13:37 ➜ object up here I'm just going to use
  • 00:13:38 ➜ these same exact values so this name is
  • 00:13:41 ➜ going to be metadata. name and then we
  • 00:13:44 ➜ can get our symbol which is you guessed
  • 00:13:46 ➜ it metadata.
  • 00:13:51 ➜ symbol and again our URI metadata.
  • 00:13:57 ➜ urri
  • 00:14:00 ➜ and then finally we need our program ID
  • 00:14:02 ➜ which is going to be our token 22
  • 00:14:04 ➜ program ID
  • 00:14:05 ➜ constant and the update Authority which
  • 00:14:08 ➜ is our payer dot key so now you can see
  • 00:14:11 ➜ our type errors have gone away we have
  • 00:14:12 ➜ all of our required information in here
  • 00:14:15 ➜ and notice here on creating this
  • 00:14:17 ➜ initialization for the metadata itself
  • 00:14:19 ➜ we're just using the name symbol and URI
  • 00:14:23 ➜ from our metadata object up here we're
  • 00:14:26 ➜ not actually utilizing any of these
  • 00:14:28 ➜ addition metadata Fields the onchain
  • 00:14:30 ➜ metadata because the way that the SPL
  • 00:14:33 ➜ token metadata program and interface
  • 00:14:35 ➜ works is you actually have to initialize
  • 00:14:37 ➜ each of these in a separate instruction
  • 00:14:40 ➜ so we can go ahead and demonstrate how
  • 00:14:41 ➜ to do that with just one of these fields
  • 00:14:43 ➜ so we'll call this um say update
  • 00:14:46 ➜ metadata
  • 00:14:50 ➜ field and we're going to pull in the
  • 00:14:53 ➜ create update field
  • 00:14:57 ➜ instruction and this uh instruction
  • 00:15:00 ➜ helper actually comes from the SPL token
  • 00:15:02 ➜ metadata package as well and we can pass
  • 00:15:04 ➜ in all the information we need like our
  • 00:15:07 ➜ metadata account which is our mint dot
  • 00:15:10 ➜ key we need our program ID which is
  • 00:15:13 ➜ token 22 the token extension program the
  • 00:15:17 ➜ update Authority and this one is super
  • 00:15:18 ➜ important this needs to be the exact
  • 00:15:20 ➜ same update Authority that you have on
  • 00:15:22 ➜ your
  • 00:15:23 ➜ Mint or sorry on your metadata pointer
  • 00:15:27 ➜ so when we initialize our met data
  • 00:15:28 ➜ pointer we're saying our payer dot key
  • 00:15:31 ➜ is our actual metadata update Authority
  • 00:15:35 ➜ same thing right here when we're
  • 00:15:36 ➜ actually initializing the metadata
  • 00:15:37 ➜ account itself is the update Authority
  • 00:15:39 ➜ this is the authority that must sign
  • 00:15:41 ➜ every single time you want to manipulate
  • 00:15:44 ➜ any of these onchain metadata Fields
  • 00:15:47 ➜ speaking of the fields we can actually
  • 00:15:48 ➜ pass in the information that we want so
  • 00:15:51 ➜ like I mentioned each of these fields
  • 00:15:52 ➜ you have to update them individually so
  • 00:15:55 ➜ we can pull them directly from our
  • 00:15:56 ➜ metadata. additional fields this case
  • 00:15:59 ➜ we're just going to grab the first item
  • 00:16:01 ➜ and the first item at index
  • 00:16:04 ➜ zero and do the same thing for the value
  • 00:16:07 ➜ Pull It in from the metadata. additional
  • 00:16:09 ➜ Fields this is the first item in the
  • 00:16:11 ➜ array and our first our second item in
  • 00:16:14 ➜ the array here so if you look at our
  • 00:16:16 ➜ additional metadata the way that this is
  • 00:16:18 ➜ kind of being structured here is we're
  • 00:16:20 ➜ pulling in the entire array since this
  • 00:16:22 ➜ is an array every single item inside of
  • 00:16:25 ➜ the array is again a nested array so we
  • 00:16:28 ➜ have our index zero is our key and our
  • 00:16:30 ➜ index one is our value and you could do
  • 00:16:32 ➜ the same thing and for multiple pieces
  • 00:16:34 ➜ of onchain metadata if you want you
  • 00:16:36 ➜ could do the same exact thing you'll
  • 00:16:37 ➜ just have to create a separate
  • 00:16:38 ➜ instruction and actually include this
  • 00:16:40 ➜ instruction every time you want to
  • 00:16:41 ➜ manipulate it so if you wanted to have
  • 00:16:43 ➜ two onchain metadata Fields key value
  • 00:16:45 ➜ Fields then you could have a second
  • 00:16:47 ➜ instruction do this as index one index
  • 00:16:50 ➜ one and so on so forth and with that we
  • 00:16:53 ➜ actually have built the very last
  • 00:16:54 ➜ instruction that we need so we can
  • 00:16:56 ➜ actually put all these instructions
  • 00:16:57 ➜ together in a transaction
  • 00:16:59 ➜ and send it to the blockchain and
  • 00:17:00 ➜ actually get it confirmed so let's
  • 00:17:02 ➜ create a new
  • 00:17:05 ➜ transaction loading in from web3.js and
  • 00:17:09 ➜ we'll use the add function the ad method
  • 00:17:11 ➜ in here so we'll pass in every single
  • 00:17:13 ➜ one of the instructions that we built
  • 00:17:14 ➜ out we'll just go ahead and copy and
  • 00:17:15 ➜ paste them so create account
  • 00:17:19 ➜ instruction initialize our metadata
  • 00:17:21 ➜ pointer
  • 00:17:25 ➜ instruction initialize our mint
  • 00:17:34 ➜ initialize our
  • 00:17:36 ➜ metadata and update our metadata
  • 00:17:39 ➜ field now the important thing to note
  • 00:17:41 ➜ here is that the order of your
  • 00:17:43 ➜ initialized mint instruction is very
  • 00:17:45 ➜ very important when you're working with
  • 00:17:47 ➜ token extensions some token extensions
  • 00:17:49 ➜ need to be initialized and set up before
  • 00:17:53 ➜ you initialize the mint so for example
  • 00:17:55 ➜ this metadata pointer instruction this
  • 00:17:57 ➜ has to be ordered before your
  • 00:17:59 ➜ initialized mint instruction if the
  • 00:18:01 ➜ order was changed here this transaction
  • 00:18:04 ➜ will fail it'll kick an error by the SPL
  • 00:18:06 ➜ token 22 program so it's very very
  • 00:18:09 ➜ important that it's in the correct order
  • 00:18:11 ➜ after you have initialized the mint
  • 00:18:12 ➜ within the instruction uh you can see
  • 00:18:15 ➜ here we're initializing the metadata
  • 00:18:16 ➜ account the metadata data itself and
  • 00:18:18 ➜ then we're updating those fields these
  • 00:18:20 ➜ can be after you've initialized The Mint
  • 00:18:22 ➜ in fact they're required to be after
  • 00:18:23 ➜ because the mint hasn't been initialized
  • 00:18:26 ➜ um if you switch that order this is is
  • 00:18:28 ➜ very very important to do so now that we
  • 00:18:30 ➜ have our transaction built we can go
  • 00:18:31 ➜ ahead and send it to the blockchain and
  • 00:18:33 ➜ get it confirmed display it back
  • 00:18:37 ➜ out we'll do a send and confirm
  • 00:18:42 ➜ transaction and this function takes in
  • 00:18:45 ➜ our connection object first and then our
  • 00:18:47 ➜ transaction itself and then it's going
  • 00:18:48 ➜ to take in an array of all of our
  • 00:18:50 ➜ signers in this particular case we need
  • 00:18:52 ➜ to sign with our payer that we loaded
  • 00:18:55 ➜ and the mint itself so we have these two
  • 00:18:57 ➜ key payers are passing in it'll sign it
  • 00:18:59 ➜ and then once this is completed we'll go
  • 00:19:01 ➜ ahead and console.log
  • 00:19:05 ➜ it and we'll go ahead and log out just
  • 00:19:07 ➜ the signature
  • 00:19:11 ➜ itself now that once this transaction
  • 00:19:14 ➜ has actually been confirmed by the
  • 00:19:15 ➜ blockchain we can actually use uh some
  • 00:19:18 ➜ of the helper functions inside of the
  • 00:19:21 ➜ SPL token metadata program to actually
  • 00:19:23 ➜ get that metadata back and to in order
  • 00:19:26 ➜ to do this you need a bit a couple of
  • 00:19:27 ➜ bits of information
  • 00:19:28 ➜ specifically you need your connection to
  • 00:19:30 ➜ the exact same cluster in this case
  • 00:19:31 ➜ devnet that we connected to and then you
  • 00:19:34 ➜ just need the mint address because
  • 00:19:35 ➜ that's the address that we actually put
  • 00:19:37 ➜ our metadata on our metadata lives on
  • 00:19:39 ➜ our token mint so we'll go ahead and log
  • 00:19:42 ➜ out this um call it chain
  • 00:19:46 ➜ metadata and we're going to use the get
  • 00:19:49 ➜ token metadata
  • 00:19:52 ➜ Helper and we pass in our connection and
  • 00:19:55 ➜ then our mint. public
  • 00:19:57 ➜ key and then we can go ahead and log
  • 00:19:59 ➜ this out now that we have this entire script
  • 00:20:04 ➜ written we can go ahead and open up our
  • 00:20:06 ➜ terminal and I'm going to use es run to
  • 00:20:08 ➜ actually run the script so if I run es
  • 00:20:10 ➜ run since I have it installed globally
  • 00:20:12 ➜ and if you don't have it installed
  • 00:20:13 ➜ globally you can do npxs run and we're
  • 00:20:16 ➜ going to tell it to use our mint script
  • 00:20:18 ➜ it's going to go through you can see the
  • 00:20:19 ➜ same payer address we have this randomly
  • 00:20:21 ➜ generated mint address called day JK
  • 00:20:24 ➜ it's a great address that's been
  • 00:20:25 ➜ randomly generated for us and then it
  • 00:20:28 ➜ looks like it's kind of hung right here
  • 00:20:29 ➜ because it's actually sending all the
  • 00:20:30 ➜ information to the blockchain but as
  • 00:20:32 ➜ soon as that's done you actually have
  • 00:20:34 ➜ the metadata displayed out right here so
  • 00:20:36 ➜ we have our name our symbol and our URI
  • 00:20:38 ➜ it's the same information that we put on
  • 00:20:40 ➜ chain and then we have our additional
  • 00:20:42 ➜ metadata that was actually stored on
  • 00:20:44 ➜ chain so there you go there you have it
  • 00:20:46 ➜ that's how to actually use the token
  • 00:20:48 ➜ metadata extension on the token
  • 00:20:50 ➜ extension program hope this video was
  • 00:20:52 ➜ helpful and check out the rest of the
  • 00:20:54 ➜ token extension videos on the Solana
  • 00:20:56 ➜ foundation YouTube channel thanks have a
  • 00:20:57 ➜ good one

About

The Token Extensions Program directly implements the SPL Token Metadata Interface, made accessible through the Token Metadata extension. With the Token Metadata extension, the Mint Account itself can now store the metadata directly on the Solana blockchain.

https://www.youtube.com/watch?v=l7EyQUlNAdw