Skip to main content

🖼 从糖果机展示NFTs

现在我们已经铸造了一个NFT,接下来我们将学习如何铸造一系列的NFT。为此,我们将利用Candy Machine来实现——这是Solana的一个程序,使创作者能够将他们的资产上链。虽然这并非创建系列的唯一方式,但在Solana上它却成了标准,因为它具备了许多有用的功能,例如机器人保护和安全随机化。你是否感受到过看到闪亮的新iPhone时的那股兴奋感?稀有的NFT有点儿类似于此。对于优秀的艺术家而言,仅仅是观看这些NFT也极富乐趣。毕竟,艺术的本质就是用来欣赏的!接下来,我们将探讨如果我们只有Candy Machine的地址,应该如何展示NFTs

你能猜到这里有何不同之处吗?没错,我们仅在SDK上采用了一种不同的方法!

由于这里并没有钱包,我们不需要使用 walletAdapterIdentity,只需使用metaplex对象即可。

我们在此有几个选择 - findByAddress 就是我们所需的。

与我们为单个NFT所获取的相似,我们将会得到整个糖果机实例的元数据。items 字段是糖果机内所有NFT的数组。每个项目都不会直接包含我们想要的内容,而是会引向一个我们可以从中提取资产的URI。

鉴于收藏品可能会相当庞大,我们不会一次性获取所有的NFT。相反,我们将基于分页系统,只获取我们想要展示的NFT

那么,让我们一起来绘制一些像素吧!

🥁 请准备一个糖果机

你可以从上一节的进度继续,或者使用我们上次使用的相同模板(从起始分支开始即可)。

赶紧跳入 FetchCandyMachine.tsx 文件吧。你会发现一些设置已经为你准备好了。我们将使用 getPage 函数从糖果机上获取某“页面”上的物品。在此之前,我们需要获取糖果机的元数据账户。

在空的 fetchCandyMachine 函数上方设置 metaplex 对象的连接。

export const FetchCandyMachine: FC = () => {
// 占位符 CMv2 地址
const [candyMachineAddress, setCandyMachineAddress] = useState("")
const [candyMachineData, setCandyMachineData] = useState(null)
const [pageItems, setPageItems] = useState(null)
const [page, setPage] = useState(1)

const { connection } = useConnection()
const metaplex = Metaplex.make(connection)

在创建有状态变量时,请确保添加你的Candy Machine地址。

export const FetchCandyMachine: FC = () => {
const [candyMachineAddress, setCandyMachineAddress] = useState("CM_ADDRESS_HERE")
...

接下来,我们将完善 fetchCandyMachine 函数。我们将使用之前看到的 findByAddress 方法。

export const FetchCandyMachine: FC = () => {
...

// 通过地址获取糖果机
const fetchCandyMachine = async () => {

// 设置页面为1 - 我们想要在获取新糖果机时始终位于第一页
setPage(1)

// 获取糖果机数据
try {
const candyMachine = await metaplex
.candyMachinesV2()
.findByAddress({ address: new PublicKey(candyMachineAddress) })

setCandyMachineData(candyMachine)
} catch (e) {
alert("请输入有效的CMv2地址。")
}
}
...
}

注意:Metaplex CLI的最新版本在函数调用的末尾不需要 run()

现在来到重要的部分 - 浏览我们将获取的CM数据。以下是 getPage 函数的样子:

export const FetchCandyMachine: FC = () => {
...

// 分页
const getPage = async (page, perPage) => {
const pageItems = candyMachineData.items.slice(
(page - 1) * perPage,
page * perPage
)

// 获取页面中NFT的元数据
let nftData = []
for (let i = 0; i < pageItems.length; i++) {
let fetchResult = await fetch(pageItems[i].uri)
let json = await fetchResult.json()
nftData.push(json)
}

// 设置状态
setPageItems(nftData)
}
...
}

我们在这里做的是将 items 数组切割成大小为10的部分。然后我们获取页面上每个NFT的元数据,并将其存储在 nftData 中。最后,我们将 pageItems 状态变量设置为刚刚获取的 nftData

这意味着我们的应用程序在任何时候只会渲染当前页面的NFT。相当棒!

让我们填写 prevnext 函数:

// 上一页
const prev = async () => {
if (page - 1 < 1) {
setPage(1)
} else {
setPage(page - 1)
}
}

// 下一页
const next = async () => {
setPage(page + 1)
}

当用户点击“上一页”和“下一页”按钮时,这些功能将运行。这些按钮只会在 pageItems 不为空时显示(即当我们获取了CM的NFT时)。

现在我们需要一些 useEffects 来开始。整个过程一开始可能有点复杂,所以让我们一步一步解释。

    1. 在页面加载时运行 fetchCandyMachine 函数(如果 candyMachineAddress 不为空)。
    1. 每当使用 fetchCandyMachine 获取糖果机时,将 page 设置为1,这样你就可以从第一页开始。
    1. 每当 candyMachineDatapage 发生变化时(即输入新的CM地址或点击下一个/上一个按钮),重新加载页面。

以下是代码示例:

export const FetchCandyMachine: FC = () => {
...

// 页面加载时获取占位符糖果机
useEffect(() => {
fetchCandyMachine()
}, [])

// 当页面或糖果机发生变化时获取NFT的元数据
useEffect(() => {
if (!candyMachineData) {
return
}
getPage(page, 9)
}, [candyMachineData, page])

}

快到 localhost:3000 上试试吧!你应该能够看到你的糖果机上NFT的第一页。