SolanaでNFTを作成する方法
Last updated June 18, 2024
これは、Metaplex Token Metadataプロトコルを使用してSolanaブロックチェーンでNFTを作成する方法の初期ガイドです。
前提条件
- お好みのコードエディタ(Visual Studio Codeを推奨)
- Node 18.x.x以上
初期セットアップ
このガイドでは、単一ファイルスクリプトに基づいたJavaScriptを使用してNFTを作成する方法を説明します。ニーズに合わせて関数を変更および移動する必要があるかもしれません。
初期化
お好みのパッケージマネージャー(npm、yarn、pnpm、bun)で新しいプロジェクトを初期化し(オプション)、プロンプトが表示されたら必要な詳細を入力することから始めます。
npm init
必要なパッケージ
このガイドに必要なパッケージをインストールします。
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);
1import {
2 appendTransactionMessageInstructions,
3 createSolanaRpc,
4 createSolanaRpcSubscriptions,
5 createTransactionMessage,
6 generateKeyPairSigner,
7 getSignatureFromTransaction,
8 type Instruction,
9 type TransactionSigner,
10 pipe,
11 sendAndConfirmTransactionFactory,
12 setTransactionMessageFeePayer,
13 setTransactionMessageLifetimeUsingBlockhash,
14 signTransactionMessageWithSigners,
15} from '@solana/kit';
16import {
17 createNft,
18 fetchDigitalAsset,
19} from '@metaplex-foundation/mpl-token-metadata-kit';
20
21// Create RPC connection
22const rpc = createSolanaRpc('https://api.devnet.solana.com');
23const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.devnet.solana.com');
24
25// Generate keypairs (or load from wallet)
26const authority = await generateKeyPairSigner();
27const mint = await generateKeyPairSigner();
28
29// Helper function to send and confirm transactions
30// Works with any signer type - signers are automatically extracted from instruction accounts
31async function sendAndConfirm(options: {
32 instructions: Instruction[];
33 payer: TransactionSigner;
34}) {
35 const { instructions, payer } = options;
36 const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
37
38 const transactionMessage = pipe(
39 createTransactionMessage({ version: 0 }),
40 (tx) => setTransactionMessageFeePayer(payer.address, tx),
41 (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
42 (tx) => appendTransactionMessageInstructions(instructions, tx),
43 );
44
45 // Sign with all signers attached to instruction accounts
46 const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
47
48 const sendAndConfirmTx = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
49 await sendAndConfirmTx(signedTransaction, { commitment: 'confirmed' });
50
51 return getSignatureFromTransaction(signedTransaction);
52}
53
54// Create and mint an NFT using the helper function
55const [createIx, mintIx] = await createNft({
56 mint,
57 authority,
58 payer: authority,
59 name: 'My NFT',
60 uri: 'https://example.com/my-nft.json',
61 sellerFeeBasisPoints: 550, // 5.5%
62 tokenOwner: authority.address,
63});
64
65// Send transaction
66const sx = await sendAndConfirm({
67 instructions: [createIx, mintIx],
68 payer: authority,
69});
70
71// Fetch the NFT data
72const asset = await fetchDigitalAsset(rpc, mint.address);
73
74console.log('NFT created successfully!');
75console.log('Mint address:', mint.address);
76console.log('Signature:', sx);
77console.log('Name:', asset.metadata.name);
78console.log('URI:', asset.metadata.uri);
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);
1import {
2 appendTransactionMessageInstructions,
3 createSolanaRpc,
4 createSolanaRpcSubscriptions,
5 createTransactionMessage,
6 generateKeyPairSigner,
7 getSignatureFromTransaction,
8 type Instruction,
9 type TransactionSigner,
10 pipe,
11 sendAndConfirmTransactionFactory,
12 setTransactionMessageFeePayer,
13 setTransactionMessageLifetimeUsingBlockhash,
14 signTransactionMessageWithSigners,
15} from '@solana/kit';
16import {
17 createNft,
18 fetchDigitalAsset,
19} from '@metaplex-foundation/mpl-token-metadata-kit';
20
21// Create RPC connection
22const rpc = createSolanaRpc('https://api.devnet.solana.com');
23const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.devnet.solana.com');
24
25// Generate keypairs (or load from wallet)
26const authority = await generateKeyPairSigner();
27const mint = await generateKeyPairSigner();
28
29// Helper function to send and confirm transactions
30// Works with any signer type - signers are automatically extracted from instruction accounts
31async function sendAndConfirm(options: {
32 instructions: Instruction[];
33 payer: TransactionSigner;
34}) {
35 const { instructions, payer } = options;
36 const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
37
38 const transactionMessage = pipe(
39 createTransactionMessage({ version: 0 }),
40 (tx) => setTransactionMessageFeePayer(payer.address, tx),
41 (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
42 (tx) => appendTransactionMessageInstructions(instructions, tx),
43 );
44
45 // Sign with all signers attached to instruction accounts
46 const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
47
48 const sendAndConfirmTx = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
49 await sendAndConfirmTx(signedTransaction, { commitment: 'confirmed' });
50
51 return getSignatureFromTransaction(signedTransaction);
52}
53
54// Create and mint an NFT using the helper function
55const [createIx, mintIx] = await createNft({
56 mint,
57 authority,
58 payer: authority,
59 name: 'My NFT',
60 uri: 'https://example.com/my-nft.json',
61 sellerFeeBasisPoints: 550, // 5.5%
62 tokenOwner: authority.address,
63});
64
65// Send transaction
66const sx = await sendAndConfirm({
67 instructions: [createIx, mintIx],
68 payer: authority,
69});
70
71// Fetch the NFT data
72const asset = await fetchDigitalAsset(rpc, mint.address);
73
74console.log('NFT created successfully!');
75console.log('Mint address:', mint.address);
76console.log('Signature:', sx);
77console.log('Name:', asset.metadata.name);
78console.log('URI:', asset.metadata.uri);
NFTの作成
画像のアップロード
最初に行う必要があるのは、NFTを表す画像をアップロードすることです。これはjpeg、png、またはgifの形式で行うことができます。
Umiには、Arweave、NftStorage、AWS、ShdwDriveなどのストレージソリューションにアップロードできるダウンロード可能なストレージプラグインが付属しています。このガイドの冒頭で、Arweaveブロックチェーンにコンテンツを保存するirysUploader()プラグインをインストールしました。
ローカルスクリプト/Node.js
この例では、Irysを使用してArweaveにアップロードするローカルスクリプト/node.jsアプローチを使用しています。別のストレージプロバイダーにファイルをアップロードしたい場合やブラウザからアップロードしたい場合は、別のアプローチを取る必要があります。ブラウザシナリオではfsのインポートと使用は機能しません。
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'
メタデータのアップロード
有効で動作する画像URIを取得したら、NFTのメタデータの作成を開始できます。
オフチェーンメタデータの標準は以下の通りです:
{
"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"
}
}
フィールドの説明:
name
トークンの名前。
symbol
トークンの略称。Solanaの略称はSOLです。
description
トークンの説明。
image
以前アップロードしたimageUri(または画像のオンラインロケーション)に設定されます。
NFT vs pNFT
Token Metadataプログラムは、通常のNFTとpNFT(プログラマブルNon-Fungible Asset)の2種類のNFTをミントできます。 2つのタイプのNFTの主な違いは、一方はロイヤリティが強制され(pNFT)、もう一方はされない(NFT)ことです。
NFT
- ロイヤリティ強制なし
- 初期セットアップがより簡単で、将来的に作業しやすい
pNFT
- 将来の開発に関してより多くのアカウントを扱う必要がある
- ロイヤリティ強制
- プログラマブル - プログラムが転送を行うことをブロックできるルールセットがある
NFTのミント
ここから、使用したいNFTミント命令のタイプ(NFTまたは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);
1import { generateKeyPairSigner } from '@solana/kit';
2import { createNft } from '@metaplex-foundation/mpl-token-metadata-kit';
3
4// Assuming rpc, rpcSubscriptions, and sendAndConfirmInstructions are set up
5// See getting-started for full setup
6
7const mint = await generateKeyPairSigner();
8const authority = await generateKeyPairSigner(); // Your wallet
9
10// Create and mint an NFT in one step
11const [createIx, mintIx] = await createNft({
12 mint,
13 authority,
14 payer: authority,
15 name: 'My NFT',
16 uri: 'https://example.com/my-nft.json',
17 sellerFeeBasisPoints: 550, // 5.5%
18 tokenOwner: authority.address,
19 // Optional: add to collection (must verify separately)
20 // collection: { key: collectionMint.address, verified: false },
21});
22
23// Send both instructions in one transaction
24await sendAndConfirm({
25 instructions: [createIx, mintIx],
26 payer: authority,
27});
28
29console.log('NFT created:', mint.address);
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);
1import { generateKeyPairSigner } from '@solana/kit';
2import { createProgrammableNft } from '@metaplex-foundation/mpl-token-metadata-kit';
3
4// Assuming rpc, rpcSubscriptions, and sendAndConfirmInstructions are set up
5
6const mint = await generateKeyPairSigner();
7const authority = await generateKeyPairSigner(); // Your wallet
8
9// Create and mint a Programmable NFT in one step
10const [createIx, mintIx] = await createProgrammableNft({
11 mint,
12 authority,
13 payer: authority,
14 name: 'My Programmable NFT',
15 uri: 'https://example.com/my-programmable-nft.json',
16 sellerFeeBasisPoints: 550, // 5.5%
17 tokenOwner: authority.address,
18 // Optional: add to collection (must verify separately)
19 // collection: { key: collectionMint.address, verified: false },
20});
21
22// Send both instructions in one transaction
23await sendAndConfirm({
24 instructions: [createIx, mintIx],
25 payer: authority,
26});
27
28console.log('Programmable NFT created:', mint.address);
次のステップ
このガイドでは、基本的なNFTの作成方法を学びました。ここからToken Metadataプログラムに進んで、コレクションの作成、新しいNFTをコレクションに追加すること、そしてNFTで実行できるさまざまな操作を確認できます。
