Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,22 @@ created: '06-16-2024'
updated: '06-18-2024'
---

This guide will demonstrate the use of the `@metaplex-foundation/mpl-core` Javascript SDK package to create a **Core NFT Asset** using the Metaplex Core onchain program.
This guide will demonstrate the use of the `@metaplex-foundation/mpl-core` Javascript SDK package to create a **Core NFT Asset** using the Metaplex Core onchain program.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Fix spelling: "onchain" should be "on-chain".

The standard convention uses a hyphen for the adjective form.

-This guide will demonstrate the use of the `@metaplex-foundation/mpl-core` Javascript SDK package to create a **Core NFT Asset** using the Metaplex Core onchain program.
+This guide will demonstrate the use of the `@metaplex-foundation/mpl-core` Javascript SDK package to create a **Core NFT Asset** using the Metaplex Core on-chain program.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
This guide will demonstrate the use of the `@metaplex-foundation/mpl-core` Javascript SDK package to create a **Core NFT Asset** using the Metaplex Core onchain program.
This guide will demonstrate the use of the `@metaplex-foundation/mpl-core` Javascript SDK package to create a **Core NFT Asset** using the Metaplex Core on-chain program.
🧰 Tools
🪛 LanguageTool

[grammar] ~10-~10: Ensure spelling is correct
Context: ...ore NFT Asset** using the Metaplex Core onchain program. {% callout title="What is Cor...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
In
src/pages/core/guides/javascript/how-to-create-a-core-nft-asset-with-javascript.md
around line 10, the phrase "onchain" should be corrected to the hyphenated
adjective form "on‑chain"; update the sentence to use "on-chain program" to
follow standard convention and consistency across the docs.


{% callout title="What is Core?" %}

**Core** uses a single account design, reducing minting costs and improving Solana network load compared to alternatives. It also has a flexible plugin system that allows for developers to modify the behavior and functionality of assets.

{% /callout %}

But before starting, let's talk about Assets:
But before starting, let's talk about Assets:

{% callout title="What is an Asset?" %}

Setting itself apart from existing Asset programs, like Solana’s Token program, Metaplex Core and Core NFT Assets (sometimes referred to as Core NFT Assets) do not rely on multiple accounts, like Associated Token Accounts. Instead, Core NFT Assets store the relationship between a wallet and the "mint" account within the asset itself.

{% /callout %}


## Prerequisite

- Code Editor of your choice (recommended **Visual Studio Code**)
Expand Down Expand Up @@ -96,7 +95,7 @@ createNft()

## Setting up Umi

While setting up Umi you can use or generate keypairs/wallets from different sources. You create a new wallet for testing, import an existing wallet from the filesystem, or use `walletAdapter` if you are creating a website/dApp.
While setting up Umi you can use or generate keypairs/wallets from different sources. You create a new wallet for testing, import an existing wallet from the filesystem, or use `walletAdapter` if you are creating a website/dApp.

**Note**: For this example we're going to set up Umi with a `generatedSigner()` but you can find all the possible setup down below!

Expand Down Expand Up @@ -131,27 +130,23 @@ await umi.rpc.airdrop(umi.identity.publickey)
```ts
const umi = createUmi('https://api.devnet.solana.com')
.use(mplCore())
.use(
.use(
irysUploader({
// mainnet address: "https://node1.irys.xyz"
// devnet address: "https://devnet.irys.xyz"
address: 'https://devnet.irys.xyz',
})
)

// Generate a new keypair signer.
const signer = generateSigner(umi)

// You will need to us fs and navigate the filesystem to
// load the wallet you wish to use via relative pathing.
const walletFile = fs.readFileSync('./keypair.json')


// Convert your walletFile onto a keypair.
let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile));
let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile))

// Load the keypair into umi.
umi.use(keypairIdentity(umiSigner));
umi.use(keypairIdentity(keypair))
```

{% /totem-accordion %}
Expand All @@ -165,9 +160,9 @@ import { useWallet } from '@solana/wallet-adapter-react'
const wallet = useWallet()

const umi = createUmi('https://api.devnet.solana.com')
.use(mplCore())
// Register Wallet Adapter to Umi
.use(walletAdapterIdentity(wallet))
.use(mplCore())
// Register Wallet Adapter to Umi
.use(walletAdapterIdentity(wallet))
```

{% /totem-accordion %}
Expand All @@ -182,7 +177,7 @@ To display a recognisable image for your Asset in the Wallets or on the Explorer

### Uploading the Image

Umi comes with downloadable storage plugins that allow you to upload to storage solutions such `Arweave`, `NftStorage`, `AWS`, and `ShdwDrive`. For this guide we're going to use the `irysUploader()` plugin which stores content on Arweave.
Umi comes with downloadable storage plugins that allow you to upload to storage solutions such `Arweave`, `NftStorage`, `AWS`, and `ShdwDrive`. For this guide we're going to use the `irysUploader()` plugin which stores content on Arweave.

In this example we're going to use a local 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.

Expand All @@ -193,8 +188,7 @@ import fs from 'fs'
import path from 'path'

// Create Umi and tell it to use Irys
const umi = createUmi('https://api.devnet.solana.com')
.use(irysUploader())
const umi = createUmi('https://api.devnet.solana.com').use(irysUploader())

// use `fs` to read file via a string path.
// You will need to understand the concept of pathing from a computing perspective.
Expand Down Expand Up @@ -298,16 +292,18 @@ const tx = await create(umi, {
const signature = base58.deserialize(tx.signature)[0]
```

And log out the detail as follow:
And log out the detail as follow:

```ts
// Log out the signature and the links to the transaction and the NFT.
console.log('\nNFT Created')
console.log('View Transaction on Solana Explorer')
console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`)
console.log('\n')
console.log('View NFT on Metaplex Explorer')
console.log(`https://core.metaplex.com/explorer/${nftSigner.publicKey}?env=devnet`)
// Log out the signature and the links to the transaction and the NFT.
console.log('\nNFT Created')
console.log('View Transaction on Solana Explorer')
console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`)
console.log('\n')
console.log('View NFT on Metaplex Explorer')
console.log(
`https://core.metaplex.com/explorer/${nftSigner.publicKey}?env=devnet`
)
```

### Additional Actions
Expand All @@ -327,22 +323,22 @@ const tx = await create(umi, {
uri: metadataUri,
plugins: [
{
type: "PermanentFreezeDelegate",
type: 'PermanentFreezeDelegate',
frozen: true,
authority: { type: "UpdateAuthority"}
authority: { type: 'UpdateAuthority' },
},
{
type: "AppData",
dataAuthority: { type: "UpdateAuthority"},
type: 'AppData',
dataAuthority: { type: 'UpdateAuthority' },
schema: ExternalPluginAdapterSchema.Binary,
}
]
},
],
}).sendAndConfirm(umi)

const signature = base58.deserialize(tx.signature)[0]
```

**Note**: Refer to the [documentation](/core/plugins) if you're not sure on what fields and plugin to use!
**Note**: Refer to the [documentation](/core/plugins) if you're not sure on what fields and plugin to use!

## Full Code Example

Expand Down Expand Up @@ -391,9 +387,7 @@ const createNft = async () => {
// use `fs` to read file via a string path.
// You will need to understand the concept of pathing from a computing perspective.

const imageFile = fs.readFileSync(
path.join('./image.png')
)
const imageFile = fs.readFileSync(path.join('./image.png'))

// Use `createGenericFile` to transform the file into a `GenericFile` type
// that umi can understand. Make sure you set the mimi tag type correctly
Expand Down Expand Up @@ -474,7 +468,9 @@ const createNft = async () => {
console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`)
console.log('\n')
console.log('View NFT on Metaplex Explorer')
console.log(`https://core.metaplex.com/explorer/${nftSigner.publicKey}?env=devnet`)
console.log(
`https://core.metaplex.com/explorer/${asset.publicKey}?env=devnet`
)
}

createNft()
Expand Down