本指南介绍如何使用 Metaplex 的新版本 JS SDK 在 Solana 上创建 NFT 收藏。尽管此指南使用了较旧的 SDK 版本,内容涵盖了创建 Candy Machine、添加项目、实施 Candy Guard、铸造 NFT 等重要步骤,并包含必要的代码示例和详细说明,适合希望在 Solana 上进行 NFT 开发的开发者。
本指南使用了不再维护的旧版 Metaplex JS SDK。虽然我们会将此指南保留作为参考,但我们建议你参考我们的更新指南来使用 Candy Machines:
如果你有任何问题或反馈,请通过 Discord 或 Twitter 联系我们。
你准备好在 Solana 上启动 NFT 收藏吗?如果是,那么你来对地方了!我们将探索 Metaplex 的新 JS SDK,它将 Candy Machine 的强大功能引入到你的 JavaScript 和 TypeScript 应用程序中,以实现快速和简单的铸造。Metaplex 添加了几项新功能,特别是 Candy Guards(用于限制或限制 NFT 铸造访问的工具),我们将在本指南中实现。
在本指南中,你将通过自己的 TypeScript 应用程序创建一个新的 V3 Candy Machine。具体来说,你将:
在终端中创建一个新的项目目录,使用以下命令:
mkdir cm-v3-demo
cd cm-v3-demo
为你的应用程序创建一个文件,app.ts:
echo > app.ts
使用 "yes" 标志初始化你的项目,以便使用默认值创建新包:
yarn init --yes
#或
npm init --yes
创建一个启用 .json 导入的 tsconfig.json 文件:
tsc -init --resolveJsonModule true
我们将需要添加 Solana Web3 和 SPL Token 库以进行此次练习。此外,我们将使用 Metaplex的 JS SDK。在终端中输入:
yarn add @solana/web3.js@1 @metaplex-foundation/js
#或
npm install @solana/web3.js@1 @metaplex-foundation/js
在你选择的代码编辑器中打开 cm-v3-demo 目录(我们使用的是 VSCode)。为遵循本指南,你需要与你的 NFT 相关联的相同 Solana 文件系统钱包。你需要将此钱包存储在项目目录中的一个文件 guideSecret.json 中。
如果你没有纸钱包,你可以使用 这个脚本 创建一个新的。确保将你的钱包保存到项目目录中的 guideSecret.json。
对于现有钱包,你可以使用下面的空投小部件向其发送一些 Devnet SOL:
🪂请求 Devnet SOL
空投 1 SOL(Devnet)
设置完成后,你的环境应如下所示:
打开 app.ts,在 第 1 行 粘贴以下导入内容:
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import { Metaplex, keypairIdentity, bundlrStorage, toMetaplexFile, toBigNumber, CreateCandyMachineInput, DefaultCandyGuardSettings, CandyMachineItem, toDateTime, sol, TransactionBuilder, CreateCandyMachineBuilderContext } from "@metaplex-foundation/js";
import secret from './guideSecret.json';
除了我们在上一步中创建的钱包外,我们还导入了一些来自 Solana Web3 和 Metaplex JS 库的必要方法和类。
要在 Solana 上构建,你需要一个 API 端点来连接到网络。你可以使用公共节点或部署和管理自己的基础设施;然而,如果你希望获得 8 倍更快的响应时间,可以将繁重的工作交给我们。
了解为什么超过 50% 的 Solana 项目选择 QuickNode,并在 这里 注册一个免费账户。我们将使用 Solana Devnet 节点。
复制 HTTP 提供程序链接:
在 app.ts 的导入语句下方,声明你的 RPC 并建立与 Solana 的 Connection 连接:
const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/'; // 👈 将其替换为你的 QuickNode Solana Devnet HTTP 端点
const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC, { commitment: 'finalized' });
你需要声明几个变量来运行你的脚本:
在 SOLANA_CONNECTION 下添加以下声明,以建立我们将使用的钱包、NFT 元数据和 Candy Machine ID 的占位符:
const WALLET = Keypair.fromSecretKey(new Uint8Array(secret));
const NFT_METADATA = 'https://mfp2m2qzszjbowdjl2vofmto5aq6rtlfilkcqdtx2nskls2gnnsa.arweave.net/YV-mahmWUhdYaV6q4rJu6CHozWVC1CgOd9NkpctGa2Q';
const COLLECTION_NFT_MINT = '';
const CANDY_MACHINE_ID = '';
通过调用我们在 Metaplex.make() 中书写的 SOLANA_CONNECTION 来建立新的 Metaplex 实例。我们的实例将使用我们刚创建的密钥对:
const METAPLEX = Metaplex.make(SOLANA_CONNECTION)
.use(keypairIdentity(WALLET));
通过包含我们的网络连接和钱包,API 将使我们能够轻松提交交易到 Solana 网络。
注意:如果你打算上传自己的图像和元数据,则需要在此处加入额外的 .use() 调用来设置存储路线(本示例中没有必要):
.use(bundlrStorage({
address: 'https://devnet.bundlr.network',
providerUrl: QUICKNODE_RPC,
timeout: 60000,
}))
Candy Machine 利用一项功能,Metaplex 认证收藏,以验证链上的收藏。验证使第三方(例如交易所)能够对 NFT 集合进行分组和跟踪,并防止假冒。要创建我们的 Candy Machine,我们必须首先创建一个集合 NFT。这将作为你在交易所或钱包(如 Magic Eden 或 Phantom)中可能看到的“封面图像”。
我们所需做的就是使用 nfts().create() 创建一个新的 NFT。创建一个新函数 createCollectionNft:
async function createCollectionNft() {
const { nft: collectionNft } = await METAPLEX.nfts().create({
name: "QuickNode Demo NFT Collection",
uri: NFT_METADATA,
sellerFeeBasisPoints: 0,
isCollection: true,
updateAuthority: WALLET,
});
console.log(`✅ - Minted Collection NFT: ${collectionNft.address.toString()}`);
console.log(` https://explorer.solana.com/address/${collectionNft.address.toString()}?cluster=devnet`);
}
确保将 isCollection 设置为 true,因为这将指明该 NFT 用于定义一个集合。
铸造你的 NFT。在应用末尾调用 createCollectionNft():
createCollectionNft();
然后,在终端中运行:
ts-node app
复制铸造 ID 并更新你的 COLLECTION_NFT_MINT 变量(对我们而言在第 11 行):
const COLLECTION_NFT_MINT = 'GWWhaWp7kJ3WKLkQTKyy5DEEGGF4TnCfHXXKxsBSbcwg';
在继续之前,请删除或注释掉你对 createCollectionNft() 的调用,因为我们将不再需要它。
Metaplex SDK 允许你仅通过一行代码启动 Candy Machine 🤯:
const { candyMachine } = await METAPLEX.candyMachines().create(candyMachineSettings);
然而,正如你所看到的,我们必须先为我们的 Candy Machine 设置一些设置。创建一个新函数 generateCandyMachine,在其中定义我们的 Candy Machine 设置,然后调用 candyMachines().create():
async function generateCandyMachine() {
const candyMachineSettings: CreateCandyMachineInput<DefaultCandyGuardSettings> =
{
itemsAvailable: toBigNumber(3), // 收藏数量: 3
sellerFeeBasisPoints: 1000, // 收藏的 10% 版权费
symbol: "DEMO",
maxEditionSupply: toBigNumber(0), // 不允许每个 NFT 的复制次数
isMutable: true,
creators: [\
{ address: WALLET.publicKey, share: 100 },\
],
collection: {
address: new PublicKey(COLLECTION_NFT_MINT), // 可以替换为你自己的 NFT 或上传一个新的
updateAuthority: WALLET,
},
};
const { candyMachine } = await METAPLEX.candyMachines().create(candyMachineSettings);
console.log(`✅ - Created Candy Machine: ${candyMachine.address.toString()}`);
console.log(` https://explorer.solana.com/address/${candyMachine.address.toString()}?cluster=devnet`);
}
Candy Machine 设置定义了收藏的大小和每个 NFT 相同的关键数据点(例如版权费、创作者、符号、可变性)。我们在这个示例中定义了一些值 - 根据自己的需要稍作修改。有关 Candy Machine 设置的详细概述,请访问 Metaplex.com。请注意,你可以在此步骤中包括 Candy Guards - 我们将在下一个单独的步骤中添加它们,让你逐步了解如何更新 Candy Machine。
继续并启用你的 Candy Machine。在应用末尾调用 generateCandyMachine():
generateCandyMachine();
然后,在终端中运行:
ts-node app
你应该会看到一个 Candy Machine ID 和链接到它的 Solana Explorer:
复制 Candy Machine ID 并更新你的 CANDY_MACHINE_ID 变量(对我们而言在第 11 行):
const CANDY_MACHINE_ID = 'D2ARG7rXosZfnZwVBx3v7piG3H2tcYvWyw5YJCPuEpBU';
如果你遇到错误或有疑问,请在 Discord 上告诉我们,我们将乐意提供帮助。
在继续之前,请删除或注释掉你对 generateCandyMachine() 的调用,因为我们将不再需要它。
Candy Machine V3 包括一个新特性,称为 “Candy Guards”(或简称 Guards)。Guards 是可以限制对 Candy Machine 铸造的访问的模块化代码片段,甚至可以向其添加新功能!(来源:Metaplex.com)。截至 2022 年 11 月,Metaplex 具有 16 种不同的 Guards 可供选择:
Metaplex 允许你组合、匹配和堆叠多个 Guards,以自定义 NFT 的铸造。你甚至可以创建各种“Guard Groups”,为不同用户创建自定义铸造体验。
对于我们的铸造,我们将设置一个 开始日期,一个 SOL 支付,以及每个用户 2 个铸造的限制。创建一个新函数 updateCandyMachine():
async function updateCandyMachine() {
const candyMachine = await METAPLEX
.candyMachines()
.findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });
const { response } = await METAPLEX.candyMachines().update({
candyMachine,
guards: {
startDate: { date: toDateTime("2022-10-17T16:00:00Z") },
mintLimit: {
id: 1,
limit: 2,
},
solPayment: {
amount: sol(0.1),
destination: METAPLEX.identity().publicKey,
},
}
})
console.log(`✅ - Updated Candy Machine: ${CANDY_MACHINE_ID}`);
console.log(` https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);
}
我们的函数做了三件事:
通过调用 candyMachines().update() 更新我们的 Candy Machine。我们首先通过步骤 1 传递我们的 candyMachine,然后定义我们的 Guards。每个 Guard 具有特定的对象键和唯一的 GuardSettings。有关每个 Candy Guard 的设置,请查看 Metaplex.com。
通过调用 updateCandyMachine()添加你的 Candy Guards。在应用末尾,添加以下内容:
updateCandyMachine();
然后,在终端中运行:
ts-node app
你应该在终端中看到类似内容:
做得好。在继续之前,请删除或注释掉你对 updateCandyMachine() 的调用,因为我们将不再需要它。
让我们向 Candy Machine 添加一些项目!
向你的 Candy Machine 添加项目的方法与更新非常相似。然而,我们需要调用 .insertItems() 而不是 .update()。创建一个新函数 addItems() 并添加以下代码:
async function addItems() {
const candyMachine = await METAPLEX
.candyMachines()
.findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });
const items = [];
for (let i = 0; i < 3; i++ ) { // 添加 3 个 NFT(我们的收藏大小)
items.push({
name: `QuickNode Demo NFT # ${i+1}`,
uri: NFT_METADATA
})
}
const { response } = await METAPLEX.candyMachines().insertItems({
candyMachine,
items: items,
},{commitment:'finalized'});
console.log(`✅ - Items added to Candy Machine: ${CANDY_MACHINE_ID}`);
console.log(` https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);
}
我们的函数做了三件事:
继续并通过调用 addItems() 添加你的项目。在应用末尾,添加以下内容:
addItems();
然后,在终端中运行:
ts-node app
你应该在终端中看到类似以下内容:
在继续之前,请删除或注释掉你对 addItems() 的调用,因为我们将不再需要它。
你现在应该有一个加载完毕的 Candy Machine,并设置了 Guards。让我们来进行测试吧!
与之前的步骤一样,我们需要获取我们的 Candy Machine 并调用一个新方法 candyMachines().mint()。创建一个新函数 mintNft():
async function mintNft() {
const candyMachine = await METAPLEX
.candyMachines()
.findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });
let { nft, response } = await METAPLEX.candyMachines().mint({
candyMachine,
collectionUpdateAuthority: WALLET.publicKey,
},{commitment:'finalized'})
console.log(`✅ - Minted NFT: ${nft.address.toString()}`);
console.log(` https://explorer.solana.com/address/${nft.address.toString()}?cluster=devnet`);
console.log(` https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);
}
这段代码应该看起来相当熟悉 - 它的功能如下:
最后,通过调用 mintNft() 铸造一个 NFT。在应用的末尾添加以下内容:
mintNft();
然后,在终端中运行:
ts-node app
你应该在终端中看到类似内容:
做得好!让我们来测试一下滚动带上其中一个 Candy Guards。重新运行你的脚本。你应该会看到类似的结果,并向你的钱包铸造第二个 NFT。然后再试一次。
第三次尝试将会给你带来一些问题。为什么?如果深入到你的错误代码中,你应该会看到类似下面的内容:
title: CandyGuardProgram > 达到允许的最大铸造数量,
problem: 地址为 [Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g] 的程序 [CandyGuardProgram] 引发了代码 [6029] 的错误,表示达到允许的最大铸造数量。
如果你记得,我们创建了一个 mintLimit Candy Guard 限制任何钱包只能铸造 2 个 NFT,因此 Guard 阻止我们铸造第三个!相当酷,对吧?
你现在拥有了一些有用的脚本,用于使用 TypeScript 与 Candy Machine 进行交互!我们期待看到你构建的内容。请加入 Discord 或 Twitter 共享你的项目!
寻找额外的挑战?尝试使用我们刚刚学习的脚本和 Solana dApp Scaffold 创建一个铸造网站!
如果你对本指南有任何反馈或问题,请 告诉我们。我们非常希望听取意见!
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!