metaplex

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Metaplex Protocol Development Guide

Metaplex Protocol 开发指南

A comprehensive guide for building NFTs, digital assets, and token launches on Solana using the Metaplex Protocol - the industry standard powering 99% of Solana NFTs and tokens.
这是一份使用Metaplex Protocol在Solana上构建NFT、数字资产和代币发行的综合指南——Metaplex是支撑99% Solana NFT与代币的行业标准。

What is Metaplex?

什么是Metaplex?

Metaplex is the leading tokenization protocol on Solana, providing smart contracts and tools for creating, selling, and managing digital assets. From simple NFTs to compressed collections of billions, from fair token launches to hybrid token/NFT systems, Metaplex provides the infrastructure.
Metaplex是Solana上领先的代币化协议,提供用于创建、销售和管理数字资产的智能合约与工具。从简单NFT到数十亿规模的压缩藏品,从公平代币发行到混合代币/NFT系统,Metaplex都能提供相应基础设施。

Key Statistics

关键数据

  • 99% of Solana NFTs use Metaplex standards
  • $10B+ in transaction value facilitated
  • 78% of Solana NFTs minted via Candy Machine (as of 2022)
  • Billions of compressed NFTs possible at minimal cost
  • **99%**的Solana NFT采用Metaplex标准
  • 促成了**100亿美元+**的交易价值
  • 截至2022年,**78%**的Solana NFT通过Candy Machine铸造
  • 可以极低成本创建数十亿个压缩NFT

Overview

概览

Metaplex provides multiple products for different use cases:
Metaplex针对不同使用场景提供多款产品:

NFT Standards

NFT标准

ProductDescriptionCost per Mint
CoreNext-gen single-account NFT standard~0.0029 SOL
Token MetadataOriginal NFT standard with PDAs~0.022 SOL
Bubblegum v2Compressed NFTs (cNFTs)~0.00009 SOL
产品描述单枚铸造成本
Core下一代单账户NFT标准~0.0029 SOL
Token Metadata采用PDA的初代NFT标准~0.022 SOL
Bubblegum v2压缩NFT(cNFT)~0.00009 SOL

Launch & Distribution

发行与分发

ProductDescription
Candy MachineNFT collection minting with guards
Core Candy MachineCandy Machine for Core assets
GenesisToken Generation Event (TGE) platform
产品描述
Candy Machine带防护机制的NFT藏品铸造系统
Core Candy Machine针对Core资产的Candy Machine
Genesis代币生成事件(TGE)平台

Utilities

实用工具

ProductDescription
MPL-HybridSwap between fungible and non-fungible
InscriptionsOn-chain data storage (up to 10MB)
DAS APIUnified API for fetching digital assets
UmiJavaScript framework for Solana clients

产品描述
MPL-Hybrid可在 fungible 与 non-fungible 资产间互换
Inscriptions链上数据存储(最大支持10MB)
DAS API用于获取数字资产的统一API
Umi面向Solana客户端的JavaScript框架

Program IDs

程序ID

Core Programs (Mainnet & Devnet)

核心程序(主网与测试网)

ProgramAddress
MPL Core
CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d
Token Metadata
metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s
Bubblegum
BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY
Candy Machine V3
CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR
Candy Guard
Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g
Core Candy Machine
CMACYFENjoBMHzapRXyo1JZkVS6EtaDDzkjMrmQLvr4J
Core Candy Guard
CMAGAKJ67e9hRZgfC5SFTbZH8MgEmtqazKXjmkaJjWTJ
MPL Hybrid
MPL4o4wMzndgh8T1NVDxELQCj5UQfYTYEkabX3wNKtb
Inscription
1NSCRfGeyo7wPUazGbaPBUsTM49e1k2aXewHGARfzSo
程序地址
MPL Core
CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d
Token Metadata
metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s
Bubblegum
BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY
Candy Machine V3
CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR
Candy Guard
Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g
Core Candy Machine
CMACYFENjoBMHzapRXyo1JZkVS6EtaDDzkjMrmQLvr4J
Core Candy Guard
CMAGAKJ67e9hRZgfC5SFTbZH8MgEmtqazKXjmkaJjWTJ
MPL Hybrid
MPL4o4wMzndgh8T1NVDxELQCj5UQfYTYEkabX3wNKtb
Inscription
1NSCRfGeyo7wPUazGbaPBUsTM49e1k2aXewHGARfzSo

SPL Programs (Required)

所需SPL程序

ProgramAddress
SPL Token
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Token 2022
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
Associated Token
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL
Account Compression
cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK

程序地址
SPL Token
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Token 2022
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
Associated Token
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL
Account Compression
cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK

Quick Start

快速开始

Installation

安装

bash
undefined
bash
undefined

Core NFTs (Recommended for new projects)

Core NFTs(推荐用于新项目)

npm install @metaplex-foundation/mpl-core
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-core
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults

Token Metadata NFTs

Token Metadata NFTs

npm install @metaplex-foundation/mpl-token-metadata
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-token-metadata
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults

Compressed NFTs (Bubblegum)

压缩NFT(Bubblegum)

npm install @metaplex-foundation/mpl-bubblegum
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-bubblegum
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults

Candy Machine

Candy Machine

npm install @metaplex-foundation/mpl-candy-machine
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-candy-machine
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults

Core Candy Machine

Core Candy Machine

npm install @metaplex-foundation/mpl-core-candy-machine
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-core-candy-machine
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults

Genesis (Token Launches)

Genesis(代币发行)

npm install @metaplex-foundation/mpl-genesis
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-genesis
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults

File uploads (Arweave via Irys)

文件上传(通过Irys上传至Arweave)

npm install @metaplex-foundation/umi-uploader-irys
undefined
npm install @metaplex-foundation/umi-uploader-irys
undefined

Umi Setup

Umi 配置

All Metaplex SDKs use Umi, a modular Solana framework:
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCore } from '@metaplex-foundation/mpl-core';
import {
  keypairIdentity,
  generateSigner
} from '@metaplex-foundation/umi';

// Create Umi instance
const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplCore());

// Option 1: Use generated keypair
const signer = generateSigner(umi);
umi.use(keypairIdentity(signer));

// Option 2: Use existing keypair
import { createSignerFromKeypair } from '@metaplex-foundation/umi';
const keypair = umi.eddsa.createKeypairFromSecretKey(secretKeyBytes);
const signer = createSignerFromKeypair(umi, keypair);
umi.use(keypairIdentity(signer));

// Option 3: Use wallet adapter (browser)
import { walletAdapterIdentity } from '@metaplex-foundation/umi-signer-wallet-adapters';
umi.use(walletAdapterIdentity(wallet));

所有Metaplex SDK均使用Umi,这是一个模块化的Solana框架:
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCore } from '@metaplex-foundation/mpl-core';
import {
  keypairIdentity,
  generateSigner
} from '@metaplex-foundation/umi';

// 创建Umi实例
const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplCore());

// 选项1:使用生成的密钥对
const signer = generateSigner(umi);
umi.use(keypairIdentity(signer));

// 选项2:使用现有密钥对
import { createSignerFromKeypair } from '@metaplex-foundation/umi';
const keypair = umi.eddsa.createKeypairFromSecretKey(secretKeyBytes);
const signer = createSignerFromKeypair(umi, keypair);
umi.use(keypairIdentity(signer));

// 选项3:使用钱包适配器(浏览器环境)
import { walletAdapterIdentity } from '@metaplex-foundation/umi-signer-wallet-adapters';
umi.use(walletAdapterIdentity(wallet));

MPL Core (Recommended)

MPL Core(推荐)

The next-generation NFT standard with single-account design, lower costs, and built-in plugins.
采用单账户设计的下一代NFT标准,成本更低且内置插件系统。

Why Core?

为什么选择Core?

FeatureCoreToken Metadata
Accounts per NFT14+
Mint Cost~0.0029 SOL~0.022 SOL
Compute Units~17,000~205,000
Enforced RoyaltiesYesNo
Plugin SystemYesNo
特性CoreToken Metadata
每个NFT的账户数量14+
铸造成本~0.0029 SOL~0.022 SOL
计算单元~17,000~205,000
版税强制执行
插件系统

Create a Core NFT

创建Core NFT

typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplCore,
  create,
  fetchAsset
} from '@metaplex-foundation/mpl-core';
import {
  generateSigner,
  keypairIdentity
} from '@metaplex-foundation/umi';
import { irysUploader } from '@metaplex-foundation/umi-uploader-irys';

// Setup
const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplCore())
  .use(irysUploader());

// Upload metadata
const metadata = {
  name: 'My Core NFT',
  description: 'A next-gen NFT on Solana',
  image: 'https://arweave.net/your-image',
  attributes: [
    { trait_type: 'Background', value: 'Blue' },
    { trait_type: 'Rarity', value: 'Legendary' }
  ]
};
const metadataUri = await umi.uploader.uploadJson(metadata);

// Create NFT
const asset = generateSigner(umi);
await create(umi, {
  asset,
  name: 'My Core NFT',
  uri: metadataUri,
}).sendAndConfirm(umi);

console.log('Asset created:', asset.publicKey);

// Fetch the asset
const fetchedAsset = await fetchAsset(umi, asset.publicKey);
console.log('Asset data:', fetchedAsset);
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplCore,
  create,
  fetchAsset
} from '@metaplex-foundation/mpl-core';
import {
  generateSigner,
  keypairIdentity
} from '@metaplex-foundation/umi';
import { irysUploader } from '@metaplex-foundation/umi-uploader-irys';

// 配置
const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplCore())
  .use(irysUploader());

// 上传元数据
const metadata = {
  name: 'My Core NFT',
  description: 'A next-gen NFT on Solana',
  image: 'https://arweave.net/your-image',
  attributes: [
    { trait_type: 'Background', value: 'Blue' },
    { trait_type: 'Rarity', value: 'Legendary' }
  ]
};
const metadataUri = await umi.uploader.uploadJson(metadata);

// 创建NFT
const asset = generateSigner(umi);
await create(umi, {
  asset,
  name: 'My Core NFT',
  uri: metadataUri,
}).sendAndConfirm(umi);

console.log('Asset created:', asset.publicKey);

// 获取资产
const fetchedAsset = await fetchAsset(umi, asset.publicKey);
console.log('Asset data:', fetchedAsset);

Core with Plugins

带插件的Core

typescript
import {
  create,
  ruleSet,
  plugin,
} from '@metaplex-foundation/mpl-core';

// Create with royalty enforcement
await create(umi, {
  asset,
  name: 'Royalty Enforced NFT',
  uri: metadataUri,
  plugins: [
    {
      type: 'Royalties',
      basisPoints: 500, // 5%
      creators: [
        { address: creatorAddress, percentage: 100 }
      ],
      ruleSet: ruleSet('None'), // or 'ProgramAllowList', 'ProgramDenyList'
    },
    {
      type: 'FreezeDelegate',
      frozen: false,
      authority: { type: 'Owner' },
    },
    {
      type: 'TransferDelegate',
      authority: { type: 'Owner' },
    },
  ],
}).sendAndConfirm(umi);
typescript
import {
  create,
  ruleSet,
  plugin,
} from '@metaplex-foundation/mpl-core';

// 创建带版税强制执行的NFT
await create(umi, {
  asset,
  name: 'Royalty Enforced NFT',
  uri: metadataUri,
  plugins: [
    {
      type: 'Royalties',
      basisPoints: 500, // 5%
      creators: [
        { address: creatorAddress, percentage: 100 }
      ],
      ruleSet: ruleSet('None'), // 或 'ProgramAllowList', 'ProgramDenyList'
    },
    {
      type: 'FreezeDelegate',
      frozen: false,
      authority: { type: 'Owner' },
    },
    {
      type: 'TransferDelegate',
      authority: { type: 'Owner' },
    },
  ],
}).sendAndConfirm(umi);

Core Collections

Core 藏品

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

// Create collection
const collection = generateSigner(umi);
await createCollection(umi, {
  collection,
  name: 'My Collection',
  uri: collectionUri,
}).sendAndConfirm(umi);

// Create asset in collection
const asset = generateSigner(umi);
await create(umi, {
  asset,
  name: 'Collection Item #1',
  uri: assetUri,
  collection: collection.publicKey,
}).sendAndConfirm(umi);
typescript
import {
  createCollection,
  create,
  fetchCollection,
} from '@metaplex-foundation/mpl-core';

// 创建藏品
const collection = generateSigner(umi);
await createCollection(umi, {
  collection,
  name: 'My Collection',
  uri: collectionUri,
}).sendAndConfirm(umi);

// 在藏品中创建资产
const asset = generateSigner(umi);
await create(umi, {
  asset,
  name: 'Collection Item #1',
  uri: assetUri,
  collection: collection.publicKey,
}).sendAndConfirm(umi);

Transfer & Burn

转移与销毁

typescript
import { transfer, burn } from '@metaplex-foundation/mpl-core';

// Transfer
await transfer(umi, {
  asset: assetPublicKey,
  newOwner: recipientPublicKey,
}).sendAndConfirm(umi);

// Burn
await burn(umi, {
  asset: assetPublicKey,
}).sendAndConfirm(umi);

typescript
import { transfer, burn } from '@metaplex-foundation/mpl-core';

// 转移
await transfer(umi, {
  asset: assetPublicKey,
  newOwner: recipientPublicKey,
}).sendAndConfirm(umi);

// 销毁
await burn(umi, {
  asset: assetPublicKey,
}).sendAndConfirm(umi);

Token Metadata

Token Metadata

The original Solana NFT standard using Program Derived Addresses (PDAs).
采用程序派生地址(PDA)的初代Solana NFT标准。

Create NFT with Token Metadata

使用Token Metadata创建NFT

typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplTokenMetadata,
  createNft,
  fetchDigitalAsset,
} from '@metaplex-foundation/mpl-token-metadata';
import { generateSigner, percentAmount } from '@metaplex-foundation/umi';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplTokenMetadata());

// Create NFT
const mint = generateSigner(umi);
await createNft(umi, {
  mint,
  name: 'My NFT',
  symbol: 'MNFT',
  uri: 'https://arweave.net/metadata.json',
  sellerFeeBasisPoints: percentAmount(5.5), // 5.5% royalty
  creators: [
    { address: umi.identity.publicKey, share: 100, verified: true }
  ],
}).sendAndConfirm(umi);

// Fetch NFT
const asset = await fetchDigitalAsset(umi, mint.publicKey);
console.log(asset);
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplTokenMetadata,
  createNft,
  fetchDigitalAsset,
} from '@metaplex-foundation/mpl-token-metadata';
import { generateSigner, percentAmount } from '@metaplex-foundation/umi';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplTokenMetadata());

// 创建NFT
const mint = generateSigner(umi);
await createNft(umi, {
  mint,
  name: 'My NFT',
  symbol: 'MNFT',
  uri: 'https://arweave.net/metadata.json',
  sellerFeeBasisPoints: percentAmount(5.5), // 5.5%版税
  creators: [
    { address: umi.identity.publicKey, share: 100, verified: true }
  ],
}).sendAndConfirm(umi);

// 获取NFT
const asset = await fetchDigitalAsset(umi, mint.publicKey);
console.log(asset);

Create Programmable NFT (pNFT)

创建可编程NFT(pNFT)

typescript
import {
  createProgrammableNft,
  TokenStandard,
} from '@metaplex-foundation/mpl-token-metadata';

// pNFTs have enforced royalties
const mint = generateSigner(umi);
await createProgrammableNft(umi, {
  mint,
  name: 'My pNFT',
  uri: metadataUri,
  sellerFeeBasisPoints: percentAmount(10), // 10% royalty
  ruleSet: ruleSetPublicKey, // Optional: custom rules
}).sendAndConfirm(umi);
typescript
import {
  createProgrammableNft,
  TokenStandard,
} from '@metaplex-foundation/mpl-token-metadata';

// pNFT支持版税强制执行
const mint = generateSigner(umi);
await createProgrammableNft(umi, {
  mint,
  name: 'My pNFT',
  uri: metadataUri,
  sellerFeeBasisPoints: percentAmount(10), // 10%版税
  ruleSet: ruleSetPublicKey, // 可选:自定义规则
}).sendAndConfirm(umi);

Create Fungible Token with Metadata

创建带元数据的 fungible 代币

typescript
import {
  createFungible,
  mintV1,
  TokenStandard,
} from '@metaplex-foundation/mpl-token-metadata';

// Create fungible token
const mint = generateSigner(umi);
await createFungible(umi, {
  mint,
  name: 'My Token',
  symbol: 'MTK',
  uri: 'https://arweave.net/token-metadata.json',
  sellerFeeBasisPoints: percentAmount(0),
  decimals: 9,
}).sendAndConfirm(umi);

// Mint tokens
await mintV1(umi, {
  mint: mint.publicKey,
  amount: 1_000_000_000n, // 1 token with 9 decimals
  tokenOwner: recipientPublicKey,
  tokenStandard: TokenStandard.Fungible,
}).sendAndConfirm(umi);
typescript
import {
  createFungible,
  mintV1,
  TokenStandard,
} from '@metaplex-foundation/mpl-token-metadata';

// 创建fungible代币
const mint = generateSigner(umi);
await createFungible(umi, {
  mint,
  name: 'My Token',
  symbol: 'MTK',
  uri: 'https://arweave.net/token-metadata.json',
  sellerFeeBasisPoints: percentAmount(0),
  decimals: 9,
}).sendAndConfirm(umi);

// 铸造代币
await mintV1(umi, {
  mint: mint.publicKey,
  amount: 1_000_000_000n, // 1枚代币(含9位小数)
  tokenOwner: recipientPublicKey,
  tokenStandard: TokenStandard.Fungible,
}).sendAndConfirm(umi);

Update Metadata

更新元数据

typescript
import { updateV1 } from '@metaplex-foundation/mpl-token-metadata';

await updateV1(umi, {
  mint: mintPublicKey,
  data: {
    name: 'Updated Name',
    symbol: 'UPDT',
    uri: 'https://arweave.net/new-metadata.json',
    sellerFeeBasisPoints: 500,
    creators: null, // Keep existing
  },
}).sendAndConfirm(umi);

typescript
import { updateV1 } from '@metaplex-foundation/mpl-token-metadata';

await updateV1(umi, {
  mint: mintPublicKey,
  data: {
    name: 'Updated Name',
    symbol: 'UPDT',
    uri: 'https://arweave.net/new-metadata.json',
    sellerFeeBasisPoints: 500,
    creators: null, // 保留现有创作者
  },
}).sendAndConfirm(umi);

Bubblegum (Compressed NFTs)

Bubblegum(压缩NFT)

Create billions of NFTs at minimal cost using Merkle tree compression.
使用默克尔树压缩技术,以极低成本创建数十亿个NFT。

Cost Comparison

成本对比

Collection SizeBubblegum CostToken Metadata Cost
10,000~0.27 SOL~220 SOL
1,000,000~50 SOL~22,000 SOL
1,000,000,000~5,007 SOL~22,000,000 SOL
藏品规模Bubblegum 成本Token Metadata 成本
10,000~0.27 SOL~220 SOL
1,000,000~50 SOL~22,000 SOL
1,000,000,000~5,007 SOL~22,000,000 SOL

Create Merkle Tree

创建默克尔树

typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplBubblegum,
  createTree,
} from '@metaplex-foundation/mpl-bubblegum';
import { generateSigner } from '@metaplex-foundation/umi';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplBubblegum());

// Create tree (max depth determines capacity)
// maxDepth 14 = 16,384 NFTs, maxDepth 20 = 1,048,576 NFTs
const merkleTree = generateSigner(umi);
await createTree(umi, {
  merkleTree,
  maxDepth: 14,
  maxBufferSize: 64,
}).sendAndConfirm(umi);

console.log('Tree created:', merkleTree.publicKey);
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplBubblegum,
  createTree,
} from '@metaplex-foundation/mpl-bubblegum';
import { generateSigner } from '@metaplex-foundation/umi';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplBubblegum());

// 创建树(最大深度决定容量)
// maxDepth 14 = 16,384个NFT,maxDepth 20 = 1,048,576个NFT
const merkleTree = generateSigner(umi);
await createTree(umi, {
  merkleTree,
  maxDepth: 14,
  maxBufferSize: 64,
}).sendAndConfirm(umi);

console.log('Tree created:', merkleTree.publicKey);

Mint Compressed NFT

铸造压缩NFT

typescript
import { mintV1 } from '@metaplex-foundation/mpl-bubblegum';

await mintV1(umi, {
  leafOwner: recipientPublicKey,
  merkleTree: merkleTreePublicKey,
  metadata: {
    name: 'Compressed NFT #1',
    symbol: 'CNFT',
    uri: 'https://arweave.net/metadata.json',
    sellerFeeBasisPoints: 500,
    collection: { key: collectionMint, verified: false },
    creators: [
      { address: umi.identity.publicKey, share: 100, verified: true }
    ],
  },
}).sendAndConfirm(umi);
typescript
import { mintV1 } from '@metaplex-foundation/mpl-bubblegum';

await mintV1(umi, {
  leafOwner: recipientPublicKey,
  merkleTree: merkleTreePublicKey,
  metadata: {
    name: 'Compressed NFT #1',
    symbol: 'CNFT',
    uri: 'https://arweave.net/metadata.json',
    sellerFeeBasisPoints: 500,
    collection: { key: collectionMint, verified: false },
    creators: [
      { address: umi.identity.publicKey, share: 100, verified: true }
    ],
  },
}).sendAndConfirm(umi);

Mint to Collection

铸造到藏品中

typescript
import { mintToCollectionV1 } from '@metaplex-foundation/mpl-bubblegum';

await mintToCollectionV1(umi, {
  leafOwner: recipientPublicKey,
  merkleTree: merkleTreePublicKey,
  collectionMint: collectionMintPublicKey,
  metadata: {
    name: 'Collection cNFT #1',
    symbol: 'CCNFT',
    uri: metadataUri,
    sellerFeeBasisPoints: 500,
    creators: [
      { address: umi.identity.publicKey, share: 100, verified: true }
    ],
  },
}).sendAndConfirm(umi);
typescript
import { mintToCollectionV1 } from '@metaplex-foundation/mpl-bubblegum';

await mintToCollectionV1(umi, {
  leafOwner: recipientPublicKey,
  merkleTree: merkleTreePublicKey,
  collectionMint: collectionMintPublicKey,
  metadata: {
    name: 'Collection cNFT #1',
    symbol: 'CCNFT',
    uri: metadataUri,
    sellerFeeBasisPoints: 500,
    creators: [
      { address: umi.identity.publicKey, share: 100, verified: true }
    ],
  },
}).sendAndConfirm(umi);

Transfer Compressed NFT

转移压缩NFT

typescript
import { transfer } from '@metaplex-foundation/mpl-bubblegum';
import { getAssetWithProof } from '@metaplex-foundation/mpl-bubblegum';

// Get asset with proof from DAS API
const assetWithProof = await getAssetWithProof(umi, assetId);

await transfer(umi, {
  ...assetWithProof,
  leafOwner: currentOwner,
  newLeafOwner: newOwner,
}).sendAndConfirm(umi);
typescript
import { transfer } from '@metaplex-foundation/mpl-bubblegum';
import { getAssetWithProof } from '@metaplex-foundation/mpl-bubblegum';

// 从DAS API获取带证明的资产
const assetWithProof = await getAssetWithProof(umi, assetId);

await transfer(umi, {
  ...assetWithProof,
  leafOwner: currentOwner,
  newLeafOwner: newOwner,
}).sendAndConfirm(umi);

Decompress to Regular NFT

解压缩为常规NFT

typescript
import { decompressV1 } from '@metaplex-foundation/mpl-bubblegum';

// Decompress creates on-chain Token Metadata NFT
await decompressV1(umi, {
  ...assetWithProof,
  mint: mintSigner,
}).sendAndConfirm(umi);

typescript
import { decompressV1 } from '@metaplex-foundation/mpl-bubblegum';

// 解压缩会创建链上的Token Metadata NFT
await decompressV1(umi, {
  ...assetWithProof,
  mint: mintSigner,
}).sendAndConfirm(umi);

Candy Machine

Candy Machine

The leading NFT minting system for fair collection launches.
用于公平发行藏品的领先NFT铸造系统。

Create Candy Machine

创建Candy Machine

typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplCandyMachine,
  create,
  addConfigLines,
} from '@metaplex-foundation/mpl-candy-machine';
import { generateSigner, some, sol, dateTime } from '@metaplex-foundation/umi';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplCandyMachine());

// Create candy machine
const candyMachine = generateSigner(umi);
const collection = generateSigner(umi);

await create(umi, {
  candyMachine,
  collection: collection.publicKey,
  collectionUpdateAuthority: umi.identity,
  itemsAvailable: 1000,
  sellerFeeBasisPoints: percentAmount(5),
  creators: [
    { address: umi.identity.publicKey, percentageShare: 100, verified: true }
  ],
  configLineSettings: some({
    prefixName: 'My NFT #',
    nameLength: 4,
    prefixUri: 'https://arweave.net/',
    uriLength: 43,
    isSequential: false,
  }),
  guards: {
    botTax: some({ lamports: sol(0.01), lastInstruction: true }),
    solPayment: some({ lamports: sol(0.5), destination: treasury }),
    startDate: some({ date: dateTime('2024-01-01T00:00:00Z') }),
    mintLimit: some({ id: 1, limit: 3 }),
  },
}).sendAndConfirm(umi);
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplCandyMachine,
  create,
  addConfigLines,
} from '@metaplex-foundation/mpl-candy-machine';
import { generateSigner, some, sol, dateTime } from '@metaplex-foundation/umi';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplCandyMachine());

// 创建Candy Machine
const candyMachine = generateSigner(umi);
const collection = generateSigner(umi);

await create(umi, {
  candyMachine,
  collection: collection.publicKey,
  collectionUpdateAuthority: umi.identity,
  itemsAvailable: 1000,
  sellerFeeBasisPoints: percentAmount(5),
  creators: [
    { address: umi.identity.publicKey, percentageShare: 100, verified: true }
  ],
  configLineSettings: some({
    prefixName: 'My NFT #',
    nameLength: 4,
    prefixUri: 'https://arweave.net/',
    uriLength: 43,
    isSequential: false,
  }),
  guards: {
    botTax: some({ lamports: sol(0.01), lastInstruction: true }),
    solPayment: some({ lamports: sol(0.5), destination: treasury }),
    startDate: some({ date: dateTime('2024-01-01T00:00:00Z') }),
    mintLimit: some({ id: 1, limit: 3 }),
  },
}).sendAndConfirm(umi);

Add Items to Candy Machine

向Candy Machine添加物品

typescript
await addConfigLines(umi, {
  candyMachine: candyMachine.publicKey,
  index: 0,
  configLines: [
    { name: '0001', uri: 'abc123...' },
    { name: '0002', uri: 'def456...' },
    { name: '0003', uri: 'ghi789...' },
  ],
}).sendAndConfirm(umi);
typescript
await addConfigLines(umi, {
  candyMachine: candyMachine.publicKey,
  index: 0,
  configLines: [
    { name: '0001', uri: 'abc123...' },
    { name: '0002', uri: 'def456...' },
    { name: '0003', uri: 'ghi789...' },
  ],
}).sendAndConfirm(umi);

Mint from Candy Machine

从Candy Machine铸造

typescript
import {
  mintV1,
  fetchCandyMachine,
  fetchCandyGuard,
} from '@metaplex-foundation/mpl-candy-machine';

const candyMachine = await fetchCandyMachine(umi, candyMachinePublicKey);
const candyGuard = await fetchCandyGuard(umi, candyMachine.mintAuthority);

const nftMint = generateSigner(umi);

await mintV1(umi, {
  candyMachine: candyMachine.publicKey,
  candyGuard: candyGuard.publicKey,
  nftMint,
  collectionMint: candyMachine.collectionMint,
  collectionUpdateAuthority: candyMachine.authority,
  mintArgs: {
    solPayment: some({ destination: treasury }),
    mintLimit: some({ id: 1 }),
  },
}).sendAndConfirm(umi);
typescript
import {
  mintV1,
  fetchCandyMachine,
  fetchCandyGuard,
} from '@metaplex-foundation/mpl-candy-machine';

const candyMachine = await fetchCandyMachine(umi, candyMachinePublicKey);
const candyGuard = await fetchCandyGuard(umi, candyMachine.mintAuthority);

const nftMint = generateSigner(umi);

await mintV1(umi, {
  candyMachine: candyMachine.publicKey,
  candyGuard: candyGuard.publicKey,
  nftMint,
  collectionMint: candyMachine.collectionMint,
  collectionUpdateAuthority: candyMachine.authority,
  mintArgs: {
    solPayment: some({ destination: treasury }),
    mintLimit: some({ id: 1 }),
  },
}).sendAndConfirm(umi);

Available Guards (21+)

可用防护机制(21+种)

GuardDescription
solPayment
Charge SOL for minting
tokenPayment
Charge SPL tokens
nftPayment
Require NFT payment
startDate
Set mint start time
endDate
Set mint end time
mintLimit
Limit mints per wallet
allowList
Merkle tree allowlist
tokenGate
Require token ownership
nftGate
Require NFT ownership
botTax
Penalize failed mints
gatekeeper
Captcha verification
freezeSolPayment
Freeze SOL until conditions met
freezeTokenPayment
Freeze tokens until conditions met
addressGate
Restrict to specific addresses
allocation
Limit total mints per group
redeemedAmount
Stop after X mints
thirdPartySigner
Require additional signature
token2022Payment
Token-2022 payment
nftBurn
Burn NFT to mint
tokenBurn
Burn tokens to mint
programGate
Restrict calling programs

防护机制描述
solPayment
铸造时收取SOL
tokenPayment
收取SPL代币
nftPayment
要求支付NFT
startDate
设置铸造开始时间
endDate
设置铸造结束时间
mintLimit
限制每个钱包的铸造次数
allowList
默克尔树白名单
tokenGate
要求持有特定代币
nftGate
要求持有特定NFT
botTax
对失败的铸造请求收取惩罚金
gatekeeper
验证码验证
freezeSolPayment
冻结SOL直到满足条件
freezeTokenPayment
冻结代币直到满足条件
addressGate
限制特定地址铸造
allocation
限制每组的总铸造量
redeemedAmount
铸造X次后停止
thirdPartySigner
要求额外签名
token2022Payment
收取Token-2022代币
nftBurn
需销毁NFT才能铸造
tokenBurn
需销毁代币才能铸造
programGate
限制可调用的程序

Genesis (Token Launches)

Genesis(代币发行)

Fair token generation events (TGEs) on Solana.
在Solana上实现公平的代币生成事件(TGE)。

Launch Types

发行类型

TypeDescriptionPrice Discovery
PresaleFixed-price token salePredetermined
Launch PoolDeposits determine priceAt close
Uniform Price AuctionBidding mechanismClearing price
类型描述价格发现方式
Presale固定价格代币销售预先确定
Launch Pool存款决定价格发行结束时确定
Uniform Price Auction竞价机制清算价格

Create Presale

创建预售

typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplGenesis,
  createGenesis,
  addBucket,
  finalize,
} from '@metaplex-foundation/mpl-genesis';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplGenesis());

// Create genesis account
const genesis = generateSigner(umi);
await createGenesis(umi, {
  genesis,
  name: 'My Token',
  symbol: 'MTK',
  uri: 'https://arweave.net/token-metadata.json',
  decimals: 9,
  totalSupply: 1_000_000_000n * 10n ** 9n, // 1 billion tokens
}).sendAndConfirm(umi);

// Add presale bucket
await addBucket(umi, {
  genesis: genesis.publicKey,
  bucket: {
    type: 'Presale',
    price: sol(0.001), // 0.001 SOL per token
    maxTokens: 100_000_000n * 10n ** 9n, // 100M tokens
    startTime: dateTime('2024-06-01T00:00:00Z'),
    endTime: dateTime('2024-06-07T00:00:00Z'),
  },
}).sendAndConfirm(umi);

// Finalize (locks configuration)
await finalize(umi, {
  genesis: genesis.publicKey,
}).sendAndConfirm(umi);
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplGenesis,
  createGenesis,
  addBucket,
  finalize,
} from '@metaplex-foundation/mpl-genesis';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplGenesis());

// 创建Genesis账户
const genesis = generateSigner(umi);
await createGenesis(umi, {
  genesis,
  name: 'My Token',
  symbol: 'MTK',
  uri: 'https://arweave.net/token-metadata.json',
  decimals: 9,
  totalSupply: 1_000_000_00n * 10n ** 9n, // 10亿枚代币
}).sendAndConfirm(umi);

// 添加预售桶
await addBucket(umi, {
  genesis: genesis.publicKey,
  bucket: {
    type: 'Presale',
    price: sol(0.001), // 每枚代币0.001 SOL
    maxTokens: 100_000_000n * 10n ** 9n, // 1亿枚代币
    startTime: dateTime('2024-06-01T00:00:00Z'),
    endTime: dateTime('2024-06-07T00:00:00Z'),
  },
}).sendAndConfirm(umi);

// 最终确定(锁定配置)
await finalize(umi, {
  genesis: genesis.publicKey,
}).sendAndConfirm(umi);

Participate in Launch

参与发行

typescript
import { deposit, claim } from '@metaplex-foundation/mpl-genesis';

// Deposit SOL
await deposit(umi, {
  genesis: genesisPublicKey,
  amount: sol(10), // 10 SOL
}).sendAndConfirm(umi);

// After launch ends, claim tokens
await claim(umi, {
  genesis: genesisPublicKey,
}).sendAndConfirm(umi);

typescript
import { deposit, claim } from '@metaplex-foundation/mpl-genesis';

// 存入SOL
await deposit(umi, {
  genesis: genesisPublicKey,
  amount: sol(10), // 10 SOL
}).sendAndConfirm(umi);

// 发行结束后,领取代币
await claim(umi, {
  genesis: genesisPublicKey,
}).sendAndConfirm(umi);

MPL-Hybrid (MPL-404)

MPL-Hybrid(MPL-404)

Swap between fungible tokens and NFTs.
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplHybrid,
  createEscrow,
  swapNftToToken,
  swapTokenToNft,
} from '@metaplex-foundation/mpl-hybrid';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplHybrid());

// Create escrow for swapping
await createEscrow(umi, {
  escrow: escrowSigner,
  collection: collectionPublicKey,
  token: tokenMint,
  feeWallet: feeWallet,
  name: 'My Hybrid Collection',
  uri: 'https://arweave.net/escrow-metadata.json',
  max: 10000n,
  min: 0n,
  amount: 1000n, // Tokens per NFT
  feeAmount: sol(0.005),
  path: 0,
}).sendAndConfirm(umi);

// Swap NFT for tokens
await swapNftToToken(umi, {
  escrow: escrowPublicKey,
  asset: nftPublicKey,
}).sendAndConfirm(umi);

// Swap tokens for NFT
await swapTokenToNft(umi, {
  escrow: escrowPublicKey,
}).sendAndConfirm(umi);

在fungible代币与NFT之间进行互换。
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplHybrid,
  createEscrow,
  swapNftToToken,
  swapTokenToNft,
} from '@metaplex-foundation/mpl-hybrid';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplHybrid());

// 创建用于互换的托管账户
await createEscrow(umi, {
  escrow: escrowSigner,
  collection: collectionPublicKey,
  token: tokenMint,
  feeWallet: feeWallet,
  name: 'My Hybrid Collection',
  uri: 'https://arweave.net/escrow-metadata.json',
  max: 10000n,
  min: 0n,
  amount: 1000n, // 每个NFT可兑换的代币数量
  feeAmount: sol(0.005),
  path: 0,
}).sendAndConfirm(umi);

// 将NFT兑换为代币
await swapNftToToken(umi, {
  escrow: escrowPublicKey,
  asset: nftPublicKey,
}).sendAndConfirm(umi);

// 将代币兑换为NFT
await swapTokenToNft(umi, {
  escrow: escrowPublicKey,
}).sendAndConfirm(umi);

Inscriptions

Inscriptions

Store data directly on-chain (up to 10MB).
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplInscription,
  initializeFromMint,
  writeData,
  fetchInscription,
} from '@metaplex-foundation/mpl-inscription';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplInscription());

// Initialize inscription for existing NFT
const inscriptionAccount = findInscriptionPda(umi, { mint: nftMint });
await initializeFromMint(umi, {
  mintAccount: nftMint,
}).sendAndConfirm(umi);

// Write JSON metadata
await writeData(umi, {
  inscriptionAccount: inscriptionAccount[0],
  value: Buffer.from(JSON.stringify({
    name: 'On-chain NFT',
    description: 'Fully on-chain!',
  })),
  offset: 0,
}).sendAndConfirm(umi);

// Write image in chunks
const imageBytes = fs.readFileSync('./image.png');
const chunkSize = 800;
for (let i = 0; i < imageBytes.length; i += chunkSize) {
  const chunk = imageBytes.slice(i, i + chunkSize);
  await writeData(umi, {
    inscriptionAccount: associatedInscriptionAccount,
    value: Buffer.from(chunk),
    offset: i,
  }).sendAndConfirm(umi);
}

// Access via Inscription Gateway
const gatewayUrl = `https://igw.metaplex.com/mainnet/${inscriptionAccount[0]}`;

直接在链上存储数据(最大支持10MB)。
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import {
  mplInscription,
  initializeFromMint,
  writeData,
  fetchInscription,
} from '@metaplex-foundation/mpl-inscription';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(mplInscription());

// 为现有NFT初始化Inscription
const inscriptionAccount = findInscriptionPda(umi, { mint: nftMint });
await initializeFromMint(umi, {
  mintAccount: nftMint,
}).sendAndConfirm(umi);

// 写入JSON元数据
await writeData(umi, {
  inscriptionAccount: inscriptionAccount[0],
  value: Buffer.from(JSON.stringify({
    name: 'On-chain NFT',
    description: 'Fully on-chain!',
  })),
  offset: 0,
}).sendAndConfirm(umi);

// 分块写入图片
const imageBytes = fs.readFileSync('./image.png');
const chunkSize = 800;
for (let i = 0; i < imageBytes.length; i += chunkSize) {
  const chunk = imageBytes.slice(i, i + chunkSize);
  await writeData(umi, {
    inscriptionAccount: associatedInscriptionAccount,
    value: Buffer.from(chunk),
    offset: i,
  }).sendAndConfirm(umi);
}

// 通过Inscription网关访问
const gatewayUrl = `https://igw.metaplex.com/mainnet/${inscriptionAccount[0]}`;

DAS API

DAS API

Unified API for fetching digital assets across all Metaplex standards.
用于跨所有Metaplex标准获取数字资产的统一API。

Using DAS API

使用DAS API

typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { dasApi } from '@metaplex-foundation/digital-asset-standard-api';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(dasApi());

// Get single asset
const asset = await umi.rpc.getAsset(assetId);

// Get assets by owner
const assets = await umi.rpc.getAssetsByOwner({
  owner: ownerPublicKey,
  limit: 100,
});

// Get assets by collection
const collectionAssets = await umi.rpc.getAssetsByGroup({
  groupKey: 'collection',
  groupValue: collectionPublicKey,
  limit: 1000,
});

// Search assets
const searchResults = await umi.rpc.searchAssets({
  owner: ownerPublicKey,
  burnt: false,
  compressed: true,
});

// Get asset proof (for compressed NFTs)
const proof = await umi.rpc.getAssetProof(assetId);
typescript
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { dasApi } from '@metaplex-foundation/digital-asset-standard-api';

const umi = createUmi('https://api.mainnet-beta.solana.com')
  .use(dasApi());

// 获取单个资产
const asset = await umi.rpc.getAsset(assetId);

// 获取某所有者的资产
const assets = await umi.rpc.getAssetsByOwner({
  owner: ownerPublicKey,
  limit: 100,
});

// 获取某藏品下的资产
const collectionAssets = await umi.rpc.getAssetsByGroup({
  groupKey: 'collection',
  groupValue: collectionPublicKey,
  limit: 1000,
});

// 搜索资产
const searchResults = await umi.rpc.searchAssets({
  owner: ownerPublicKey,
  burnt: false,
  compressed: true,
});

// 获取资产证明(针对压缩NFT)
const proof = await umi.rpc.getAssetProof(assetId);

DAS-Compatible RPC Providers

兼容DAS的RPC提供商

  • Helius
  • Triton
  • Shyft
  • QuickNode
  • Alchemy (with DAS)

  • Helius
  • Triton
  • Shyft
  • QuickNode
  • Alchemy(需开启DAS功能)

Protocol Fees

协议费用

ProgramOperationFee
CoreCreate0.0015 SOL
CoreExecute0.00004872 SOL
Token MetadataCreate0.01 SOL
Bubblegum v2Create0.00009 SOL
Bubblegum v2Transfer0.000006 SOL
Bubblegum v1CreateFree
GenesisLaunch Pool2% deposit/withdraw, 5% graduation
GenesisPresale2% deposit, 5% graduation
MPL-HybridSwap0.005 SOL

程序操作费用
Core创建0.0015 SOL
Core执行0.00004872 SOL
Token Metadata创建0.01 SOL
Bubblegum v2创建0.00009 SOL
Bubblegum v2转移0.000006 SOL
Bubblegum v1创建免费
Genesis发行池存入/取出收取2%,毕业收取5%
Genesis预售存入收取2%,毕业收取5%
MPL-Hybrid互换0.005 SOL

Best Practices

最佳实践

Choosing the Right Standard

选择合适的标准

Use CaseRecommended
New NFT collectionCore
Large collection (10K+)Bubblegum
PFP with royaltiesCore or pNFT
Gaming itemsCore (plugins)
Existing ecosystemToken Metadata
Token launchGenesis
Hybrid token/NFTMPL-Hybrid
使用场景推荐方案
新NFT藏品Core
大规模藏品(1万+)Bubblegum
带版税的PFPCorepNFT
游戏道具Core(支持插件)
现有生态系统Token Metadata
代币发行Genesis
混合代币/NFTMPL-Hybrid

Security

安全

  1. Never share private keys - Use wallet adapters in browsers
  2. Verify transactions - Always review before signing
  3. Test on devnet - Use devnet before mainnet
  4. Audit smart contracts - If building custom guards
  1. 切勿分享私钥 - 在浏览器中使用钱包适配器
  2. 验证交易 - 签名前务必仔细查看
  3. 在测试网测试 - 上线主网前先在测试网验证
  4. 审计智能合约 - 若构建自定义防护机制,需进行审计

Performance

性能

  1. Batch operations - Use transaction builders
  2. Cache DAS responses - Reduce API calls
  3. Use compression - Bubblegum for large collections
  4. Priority fees - Add during congestion

  1. 批量操作 - 使用事务构建器
  2. 缓存DAS响应 - 减少API调用次数
  3. 使用压缩技术 - 大规模藏品选择Bubblegum
  4. 优先费用 - 网络拥堵时添加优先费用

Resources

资源

Documentation

文档

GitHub Repositories

GitHub仓库

API References

API参考

Community

社区

Skill Structure

技能结构

metaplex/
├── SKILL.md                           # This file
├── resources/
│   ├── program-ids.md                 # All program addresses
│   ├── sdk-packages.md                # NPM packages reference
│   └── protocol-fees.md               # Fee schedule
├── examples/
│   ├── core/
│   │   └── create-nft.ts              # Core NFT examples
│   ├── token-metadata/
│   │   └── create-nft.ts              # Token Metadata examples
│   ├── bubblegum/
│   │   └── compressed-nfts.ts         # cNFT examples
│   ├── candy-machine/
│   │   └── launch-collection.ts       # Candy Machine examples
│   └── genesis/
│       └── token-launch.ts            # Genesis TGE examples
├── templates/
│   └── metaplex-client.ts             # Ready-to-use client
└── docs/
    └── troubleshooting.md             # Common issues
metaplex/
├── SKILL.md                           # 本文档
├── resources/
│   ├── program-ids.md                 # 所有程序地址
│   ├── sdk-packages.md                # NPM包参考
│   └── protocol-fees.md               # 费用表
├── examples/
│   ├── core/
│   │   └── create-nft.ts              # Core NFT示例
│   ├── token-metadata/
│   │   └── create-nft.ts              # Token Metadata示例
│   ├── bubblegum/
│   │   └── compressed-nfts.ts         # cNFT示例
│   ├── candy-machine/
│   │   └── launch-collection.ts       # Candy Machine示例
│   └── genesis/
│       └── token-launch.ts            # Genesis TGE示例
├── templates/
│   └── metaplex-client.ts             # 即用型客户端
└── docs/
    └── troubleshooting.md             # 常见问题