Javascript

How to Create a NFT On Solana

Last updated June 18, 2024

This is an intial guide on how to create an NFT on the Solana blockchain with the Metaplex Token Metadata protocol.

Prerequisite

  • Code Editor of your choice (recommended Visual Studio Code)
  • Node 18.x.x or above.

Initial Setup

This guide will run through creation of an NFT with Javascript based on a single file script. You may need to modify and move functions around to suit your needs.

Initializing

Start by initializing a new project (optional) with the package manager of your choice (npm, yarn, pnpm, bun) and fill in required details when prompted.

npm init

Required Packages

Install the required packages for this guide.

1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
2import { generateSigner, percentAmount } from '@metaplex-foundation/umi';
3import {
4 mplTokenMetadata,
5 createNft,
6 fetchDigitalAsset,
7} from '@metaplex-foundation/mpl-token-metadata';
8
9// Create Umi instance with the Token Metadata plugin
10const umi = createUmi('https://api.devnet.solana.com')
11 .use(mplTokenMetadata());
12
13// Connect your wallet (keypair or wallet adapter)
14// For keypair: umi.use(keypairIdentity(keypair))
15// For wallet adapter: umi.use(walletAdapterIdentity(wallet))
16
17// Generate a new mint keypair
18const mint = generateSigner(umi);
19
20// Create an NFT
21await createNft(umi, {
22 mint,
23 name: 'My NFT',
24 uri: 'https://example.com/my-nft.json',
25 sellerFeeBasisPoints: percentAmount(5.5),
26}).sendAndConfirm(umi);
27
28// Fetch the NFT data
29const asset = await fetchDigitalAsset(umi, mint.publicKey);
30
31console.log('NFT created successfully!');
32console.log('Mint address:', mint.publicKey);
33console.log('Name:', asset.metadata.name);
34console.log('URI:', asset.metadata.uri);

Setting up the SDK

1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
2import { generateSigner, percentAmount } from '@metaplex-foundation/umi';
3import {
4 mplTokenMetadata,
5 createNft,
6 fetchDigitalAsset,
7} from '@metaplex-foundation/mpl-token-metadata';
8
9// Create Umi instance with the Token Metadata plugin
10const umi = createUmi('https://api.devnet.solana.com')
11 .use(mplTokenMetadata());
12
13// Connect your wallet (keypair or wallet adapter)
14// For keypair: umi.use(keypairIdentity(keypair))
15// For wallet adapter: umi.use(walletAdapterIdentity(wallet))
16
17// Generate a new mint keypair
18const mint = generateSigner(umi);
19
20// Create an NFT
21await createNft(umi, {
22 mint,
23 name: 'My NFT',
24 uri: 'https://example.com/my-nft.json',
25 sellerFeeBasisPoints: percentAmount(5.5),
26}).sendAndConfirm(umi);
27
28// Fetch the NFT data
29const asset = await fetchDigitalAsset(umi, mint.publicKey);
30
31console.log('NFT created successfully!');
32console.log('Mint address:', mint.publicKey);
33console.log('Name:', asset.metadata.name);
34console.log('URI:', asset.metadata.uri);

Creating the NFT

Uploading the Image

The first thing we need to do is to an image that represents the NFT and makes it recognisable. This can be in the form of jpeg, png or gif.

Umi comes with downloadable storage plugins that allow you to upload to storage solutions such Arweave, NftStorage, AWS, and ShdwDrive. At start of this guide we had installed the irsyUploader() plugin which stores content on the Arweave blockchain so we'll stick with using that.

Local script/Node.js

This example is using a localscript/node.js approach using Irys to upload to Arweave. If you wish to upload files to a different storage provider or from the browser you will need to take a different approach. Importing and using fs won't work in a browser scenario.

Error: Could not load example "token-metadata/upload-assets"

Make sure the file exists at: src/examples/token-metadata/upload-assets/index.js

Cannot find module './token-metadata/upload-assets/index.js'

Uploading the Metadata

Once we have a valid and working image URI we can start working on the metadata for our NFT.

The standard for offchain metadata for a fungilbe token is as follows;

{
"name": "My NFT",
"description": "This is an NFT on Solana",
"image": "https://arweave.net/my-image",
"external_url": "https://example.com/my-nft.json",
"attributes": [
{
"trait_type": "trait1",
"value": "value1"
},
{
"trait_type": "trait2",
"value": "value2"
}
],
"properties": {
"files": [
{
"uri": "https://arweave.net/my-image",
"type": "image/png"
}
],
"category": "image"
}
}

The fields here include

name

The name of your token.

symbol

The short hand of your token. Where Solana's shorthand would be SOL.

description

The description of your token.

image

This will be set to the imageUri (or any online location of the image) that we uploaded previously.

NFT vs pNFT

The Token Metadata program can mint 2 kinds of NFTs, a normal NFT, and a pNFT (programmable Non-Fungible Asset). The main difference between the two types of NFTs here are one is royalty enforced (pNFT) and the other is not (NFT).

NFT

  • No royatly enforcement
  • Simpler in initial setup and to work with in future.

pNFT

  • More accounts to deal with when it comes to future development.
  • Royalty enforcement
  • Programable in which we have rulesets which can block programs from making a transfer.

Minting the Nft

From here you can pick the type of NFT mint instruction you wish to use, either NFT or pNFT.

NFT

1import { percentAmount, generateSigner } from '@metaplex-foundation/umi';
2import { createNft } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi is set up with mplTokenMetadata plugin
5// See getting-started for full setup
6
7const mint = generateSigner(umi);
8
9// Create and mint an NFT in one step
10await createNft(umi, {
11 mint,
12 name: 'My NFT',
13 uri: 'https://example.com/my-nft.json',
14 sellerFeeBasisPoints: percentAmount(5.5),
15 // Optional: add to collection (must verify separately)
16 // collection: some({ key: collectionMint.publicKey, verified: false }),
17}).sendAndConfirm(umi);
18
19console.log('NFT created:', mint.publicKey);

pNFT

1import { percentAmount, generateSigner } from '@metaplex-foundation/umi';
2import { createProgrammableNft } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi is set up with mplTokenMetadata plugin
5
6const mint = generateSigner(umi);
7
8// Create and mint a Programmable NFT in one step
9await createProgrammableNft(umi, {
10 mint,
11 name: 'My Programmable NFT',
12 uri: 'https://example.com/my-programmable-nft.json',
13 sellerFeeBasisPoints: percentAmount(5.5),
14 // Optional: add to collection (must verify separately)
15 // collection: some({ key: collectionMint.publicKey, verified: false }),
16}).sendAndConfirm(umi);
17
18console.log('Programmable NFT created:', mint.publicKey);

What's Next?

This guide helped you to create a basic NFT, from here you can head over to the Token Metadata Program and check out things like creating a collection and adding your new NFT into a collection and the various other interactions you can perform with your NFT.