Features

Creating Assets

As discussed in the Core overview, digital assets on Core are composed of exactly one onchain account and off-chain data describing the token. On this page, we'll go over the process of minting these assets.

The Creation Process

  1. Upload off-chain data. First, we must ensure our off-chain data is ready. This means we must have a JSON file stored somewhere that describes our asset. It doesn't matter how or where that JSON file is stored, as long as it's accessible via a URI. The off chain metadata can look similar to the old token metadata standard.
  2. Create onchain Asset account. Then, we must create the onchain Asset account that will hold our asset's data.

Let's dig into these steps in more detail, whilst providing concrete code examples.

Uploading off-chain data

You may use any storage service (Arweave, IPFS, AWS etc...) to upload your off-chain data or simply store it on your own server. To make some of these easier for the user Umi has some dedicated plugins including the likes of Irys (uploads to Arweave) and nftStorage (uploads to IPFS). Once a plugin is selected this grants the user a unified interface for you to upload your data.

Upload assets and JSON data

const [imageUri] = await umi.uploader.upload([imageFile])
const uri = await umi.uploader.uploadJson({
  name: 'My NFT',
  description: 'This is my NFT',
  image: imageUri,
  // ...
})

Now that we have our URI, we can move on to the next step.

Create an Asset

To create an Asset use the createV1 instruction. The createV1 instruction, in addition to setting the basic metadata of the Asset, encompasses the likes of adding your Asset to a collection and assigning plugins which is described a bit later.

Below is a simple example:

Create Asset

import { generateSigner } from '@metaplex-foundation/umi'
import { create } from '@metaplex-foundation/mpl-core'

const assetSigner = generateSigner(umi)

const result = await create(umi, {
  asset: assetSigner,
  name: 'My Asset',
  uri: 'https://example.com/my-asset.json',
}).sendAndConfirm(umi)

Create an Asset into a Collection

MPL Core Assets can be created straight into a collection if your MPL Core Collection already exists. To create a Collection Asset visit here.

Create Asset into Collection

import { generateSigner } from '@metaplex-foundation/umi'
import {
  createCollection,
  create,
  fetchCollection,
} from '@metaplex-foundation/mpl-core'

const collectionSigner = generateSigner(umi)

// create collection
// if you are doing this in a single script you may have
// to use a sleep function or commitment level of 'finalized'
// so the collection is fully written to change before fetching it.
await createCollection(umi, {
  collection: collectionSigner,
  name: 'My Collection',
  uri: 'https://example.com/my-collection.json',
}).sendAndConfirm(umi)

// fetch the collection
const collection = fetchCollection(umi, collection.publicKey)


// generate assetSigner and then create the asset.
const asset = generateSigner(umi)

await create(umi, {
  asset: assetSigner,
  collection: collection,
  name: 'My Asset',
  uri: 'https://example.com/my-asset.json',
}).sendAndConfirm(umi)

Create an Asset with Plugins

MPL Core Assets support the use of plugins at both the Collection and Asset levels. To create a Core Asset with a plugin you pass in the plugin type and its parameters into the plugins array arg during creation. The below example creates a mint with the Freeze plugin.

Create Asset with Plugin

import { generateSigner } from '@metaplex-foundation/umi'
import { create, ruleSet } from '@metaplex-foundation/mpl-core'

const creator1 = publicKey('11111111111111111111111111111111')
const creator2 = publicKey('22222222222222222222222222222222')

const assetSigner = generateSigner(umi)

await create(umi, {
  asset: assetSigner,
  name: 'My Asset',
  uri: 'https://example.com/my-asset.json',
  plugins: [
    {
      type: 'Royalties',
      basisPoints: 500,
      creators: [
        {
          address: creator1,
          percentage: 20,
        },
        {
          address: creator2,
          percentage: 80,
        },
      ],
      ruleSet: ruleSet('None'), // Compatibility rule set
    },
  ],
}).sendAndConfirm(umi)

The list of plugins includes but is not limited to:

Previous
FAQ