metaplex
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMetaplex 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标准
| Product | Description | Cost per Mint |
|---|---|---|
| Core | Next-gen single-account NFT standard | ~0.0029 SOL |
| Token Metadata | Original NFT standard with PDAs | ~0.022 SOL |
| Bubblegum v2 | Compressed 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
发行与分发
| Product | Description |
|---|---|
| Candy Machine | NFT collection minting with guards |
| Core Candy Machine | Candy Machine for Core assets |
| Genesis | Token Generation Event (TGE) platform |
| 产品 | 描述 |
|---|---|
| Candy Machine | 带防护机制的NFT藏品铸造系统 |
| Core Candy Machine | 针对Core资产的Candy Machine |
| Genesis | 代币生成事件(TGE)平台 |
Utilities
实用工具
| Product | Description |
|---|---|
| MPL-Hybrid | Swap between fungible and non-fungible |
| Inscriptions | On-chain data storage (up to 10MB) |
| DAS API | Unified API for fetching digital assets |
| Umi | JavaScript framework for Solana clients |
| 产品 | 描述 |
|---|---|
| MPL-Hybrid | 可在 fungible 与 non-fungible 资产间互换 |
| Inscriptions | 链上数据存储(最大支持10MB) |
| DAS API | 用于获取数字资产的统一API |
| Umi | 面向Solana客户端的JavaScript框架 |
Program IDs
程序ID
Core Programs (Mainnet & Devnet)
核心程序(主网与测试网)
| Program | Address |
|---|---|
| MPL Core | |
| Token Metadata | |
| Bubblegum | |
| Candy Machine V3 | |
| Candy Guard | |
| Core Candy Machine | |
| Core Candy Guard | |
| MPL Hybrid | |
| Inscription | |
| 程序 | 地址 |
|---|---|
| MPL Core | |
| Token Metadata | |
| Bubblegum | |
| Candy Machine V3 | |
| Candy Guard | |
| Core Candy Machine | |
| Core Candy Guard | |
| MPL Hybrid | |
| Inscription | |
SPL Programs (Required)
所需SPL程序
| Program | Address |
|---|---|
| SPL Token | |
| Token 2022 | |
| Associated Token | |
| Account Compression | |
| 程序 | 地址 |
|---|---|
| SPL Token | |
| Token 2022 | |
| Associated Token | |
| Account Compression | |
Quick Start
快速开始
Installation
安装
bash
undefinedbash
undefinedCore NFTs (Recommended for new projects)
Core NFTs(推荐用于新项目)
npm install @metaplex-foundation/mpl-core
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-core
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@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
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-token-metadata
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@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
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-bubblegum
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@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
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-candy-machine
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@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
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-core-candy-machine
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@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
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
npm install @metaplex-foundation/mpl-genesis
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
@metaplex-foundation/umi
@metaplex-foundation/umi-bundle-defaults
File uploads (Arweave via Irys)
文件上传(通过Irys上传至Arweave)
npm install @metaplex-foundation/umi-uploader-irys
undefinednpm install @metaplex-foundation/umi-uploader-irys
undefinedUmi 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?
| Feature | Core | Token Metadata |
|---|---|---|
| Accounts per NFT | 1 | 4+ |
| Mint Cost | ~0.0029 SOL | ~0.022 SOL |
| Compute Units | ~17,000 | ~205,000 |
| Enforced Royalties | Yes | No |
| Plugin System | Yes | No |
| 特性 | Core | Token Metadata |
|---|---|---|
| 每个NFT的账户数量 | 1 | 4+ |
| 铸造成本 | ~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 Size | Bubblegum Cost | Token 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+种)
| Guard | Description |
|---|---|
| Charge SOL for minting |
| Charge SPL tokens |
| Require NFT payment |
| Set mint start time |
| Set mint end time |
| Limit mints per wallet |
| Merkle tree allowlist |
| Require token ownership |
| Require NFT ownership |
| Penalize failed mints |
| Captcha verification |
| Freeze SOL until conditions met |
| Freeze tokens until conditions met |
| Restrict to specific addresses |
| Limit total mints per group |
| Stop after X mints |
| Require additional signature |
| Token-2022 payment |
| Burn NFT to mint |
| Burn tokens to mint |
| Restrict calling programs |
| 防护机制 | 描述 |
|---|---|
| 铸造时收取SOL |
| 收取SPL代币 |
| 要求支付NFT |
| 设置铸造开始时间 |
| 设置铸造结束时间 |
| 限制每个钱包的铸造次数 |
| 默克尔树白名单 |
| 要求持有特定代币 |
| 要求持有特定NFT |
| 对失败的铸造请求收取惩罚金 |
| 验证码验证 |
| 冻结SOL直到满足条件 |
| 冻结代币直到满足条件 |
| 限制特定地址铸造 |
| 限制每组的总铸造量 |
| 铸造X次后停止 |
| 要求额外签名 |
| 收取Token-2022代币 |
| 需销毁NFT才能铸造 |
| 需销毁代币才能铸造 |
| 限制可调用的程序 |
Genesis (Token Launches)
Genesis(代币发行)
Fair token generation events (TGEs) on Solana.
在Solana上实现公平的代币生成事件(TGE)。
Launch Types
发行类型
| Type | Description | Price Discovery |
|---|---|---|
| Presale | Fixed-price token sale | Predetermined |
| Launch Pool | Deposits determine price | At close |
| Uniform Price Auction | Bidding mechanism | Clearing 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
协议费用
| Program | Operation | Fee |
|---|---|---|
| Core | Create | 0.0015 SOL |
| Core | Execute | 0.00004872 SOL |
| Token Metadata | Create | 0.01 SOL |
| Bubblegum v2 | Create | 0.00009 SOL |
| Bubblegum v2 | Transfer | 0.000006 SOL |
| Bubblegum v1 | Create | Free |
| Genesis | Launch Pool | 2% deposit/withdraw, 5% graduation |
| Genesis | Presale | 2% deposit, 5% graduation |
| MPL-Hybrid | Swap | 0.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 Case | Recommended |
|---|---|
| New NFT collection | Core |
| Large collection (10K+) | Bubblegum |
| PFP with royalties | Core or pNFT |
| Gaming items | Core (plugins) |
| Existing ecosystem | Token Metadata |
| Token launch | Genesis |
| Hybrid token/NFT | MPL-Hybrid |
| 使用场景 | 推荐方案 |
|---|---|
| 新NFT藏品 | Core |
| 大规模藏品(1万+) | Bubblegum |
| 带版税的PFP | Core 或 pNFT |
| 游戏道具 | Core(支持插件) |
| 现有生态系统 | Token Metadata |
| 代币发行 | Genesis |
| 混合代币/NFT | MPL-Hybrid |
Security
安全
- Never share private keys - Use wallet adapters in browsers
- Verify transactions - Always review before signing
- Test on devnet - Use devnet before mainnet
- Audit smart contracts - If building custom guards
- 切勿分享私钥 - 在浏览器中使用钱包适配器
- 验证交易 - 签名前务必仔细查看
- 在测试网测试 - 上线主网前先在测试网验证
- 审计智能合约 - 若构建自定义防护机制,需进行审计
Performance
性能
- Batch operations - Use transaction builders
- Cache DAS responses - Reduce API calls
- Use compression - Bubblegum for large collections
- Priority fees - Add during congestion
- 批量操作 - 使用事务构建器
- 缓存DAS响应 - 减少API调用次数
- 使用压缩技术 - 大规模藏品选择Bubblegum
- 优先费用 - 网络拥堵时添加优先费用
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 issuesmetaplex/
├── 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 # 常见问题