ساخت یک گالری از NFT های خود با استفاده از Next.js و Alchemy

ساخت یک گالری NFT به چندین دلیل می‌تواند مفید باشد. اولا، این کار به شما اجازه می‌دهد تا مجموعه NFT خود را به نمایش بگذارید و به راحتی برای خریداران بالقوه یا افراد علاقه‌مند در دسترس باشد.

دوما، این کار می‌تواند ارزش NFT های شما را با ایجاد یک نمایش منحصر به فرد و جذاب افزایش دهد.

سوما، ایجاد یک گالری NFT می‌تواند راهی جذاب و خلاقانه برای ارتباط با جامعه NFT باشد و به شما اجازه می‌دهد تا توانایی خلاقیت و سلیقه‌ی خود را به نمایش بگذارید.

در نهایت، ساخت یک گالری NFT می‌تواند یک تجربه‌ی آموزشی مفید باشد و به شما امکان می‌دهد تا مهارت‌های خود در توسعه وب، ادغام بلاکچین و طراحی تجربه کاربری را توسعه دهید.

الکمی (Alchemy) یکی از محبوب‌ترین سرویس‌های بلاکچینی است که به توسعه‌دهندگان کمک می‌کند تا به راحتی با شبکه‌های بلاکچین مانند Ethereum ارتباط برقرار کنند و برنامه‌هایی را ایجاد کنند که از قابلیت‌های این شبکه‌ها استفاده کنند.

ما از SDK الکمی برای ارتباط با بلاکچین اتریوم، خواندن داده ها و متادیتای NFT ها استفاده می کنیم. این SDK یک رابط ساده و آسان برای توسعه دهندگان فراهم می کند تا به شبکه اتریوم دسترسی پیدا کنند.

ما از همان زیر ساخت Next.js که در مطاب قبلی ایجاد کرده و توسعه دادیم استفاده خواهیم کرد. برای اضافه کردن SDK الکمی به پروژه، می توانید دستور زیر را در ترمینال خود اجرا کنید.

pnpm add alchemy-sdk

این دستور آخرین نسخه SDK الکمی را برای استفاده در پروژه Next.js شما نصب خواهد کرد.

در ادامه نیاز به ایجاد اینستنس جدیدی از SDK با استفاده از تنظیمات مورد نظر خود دایم. برای این کار در داخل پوشه utils فایل جدیدی با عنوان و محتوای زیر alchemy.ts بسازید.

import { Alchemy, Network } from 'alchemy-sdk'

const alchemyApikey = process.env.ALCHEMY_API_KEY

const alchemy = new Alchemy({
  apiKey: alchemyApikey,
  network: Network.ETH_MAINNET,
})

export { alchemy }

حالا ما به یک تابع نیاز داریم که همه NFT های متعلق به یک آدرس کیف پول خاص را بازیابی کند و یک آرایه از متادیتای توکن برگرداند. فایل جدیدی با عنوان nfts.ts در پوشه utils و با محتوای زیر ایجاد کنید.

import { alchemy } from './alchemy'

export type Nft = {
  contractAddress: string
  tokenId: string
  name: string
  type: string
  tokenUri: string | null
  imageUrl: string | null
  updatedAt: string | null
}

const replaceIpfsUrl = (url: string) => {
  if (url.startsWith('ipfs://')) {
    return `https://cloudflare-ipfs.com/ipfs/${url.slice(7)}`
  }
  return url
}

export async function getNftsByAddress(address: string): Promise<Nft[]> {
  // Retrieve NFTs owned by the wallet address
  const nftsForOwner = await alchemy.nft.getNftsForOwner(address)

  // Retrieve metadata for each NFT using Promise.all for concurrency
  const nfts = await Promise.all(
    nftsForOwner.ownedNfts.map(async (nft) => {
      const metadata = await alchemy.nft.getNftMetadata(
        nft.contract.address,
        nft.tokenId,
        {}, // Add empty options object to get all metadata, including custom attributes
      )

      const imageUrl = metadata.rawMetadata?.image ?? null

      // Extract relevant metadata and return it as an Nft object
      return {
        contractAddress: nft.contract.address,
        tokenId: nft.tokenId,
        name: metadata.title,
        type: metadata.tokenType,
        tokenUri: metadata.tokenUri?.gateway ?? null,
        imageUrl: imageUrl ? replaceIpfsUrl(imageUrl) : null,
        updatedAt: metadata.timeLastUpdated ?? null,
      }
    }),
  )

  return nfts
}

این کد یک تابع به نامgetNftsByAddress ارائه می‌دهد که لیستی از اطلاعات NFT‌هایی که متعلق به یک آدرس کیف پول مشخص هستند، بازمی‌گرداند.

بعد از نوشتن تابع getNftsByAddress، برای استفاده از آن برای ساخت گالری در یک سایت Next.js استاتیک، می‌توانید ازgetStaticProps استفاده کنید تا اطلاعات مربوط به NFT ها را بگیرید و در پروژه خود استفاده کنید.

درون پوشهpages، یک فایل جدید با نام gallery.tsx ایجاد کنید. در این فایل، ابتدا تابعgetNftsByAddress را وارد کرده و سپس با استفاده ازgetStaticProps اطلاعات لازم را برای گالری دریافت کنید.

import { GetStaticProps } from 'next'
import Image from 'next/image'
import Layout from '../components/layout'
import { getNftsByAddress, Nft } from '../utils/nfts'

type Props = {
  nfts: Nft[]
}

const Gallery = ({ nfts }: Props) => {
  return (
    <>
      <Layout title="Gallery">
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
          {nfts.map((nft) => (
            <div key={`${nft.contractAddress}-${nft.tokenId}`}>
              {nft.imageUrl && (
                <div className="relative h-80">
                  <Image src={nft.imageUrl} alt={nft.name} fill />
                </div>
              )}
              <div className="mt-2">{nft.name}</div>
            </div>
          ))}
        </div>
      </Layout>
    </>
  )
}

export default Gallery

export const getStaticProps: GetStaticProps<Props> = async () => {
  const walletAddress = process.env.WALLET_ADDRESS ?? ''
  const nfts = await getNftsByAddress(walletAddress)

  return {
    props: {
      nfts,
    },
  }
}

در کد بالا، ما ازgetStaticProps استفاده کردیم تا اطلاعات مربوط به NFT ها را دریافت کنیم و درprops قرار دهیم. سپس با استفاده از اینprops، می‌توانیم گالری مورد نظر را بسازیم.

در این مثال، ما از یکdiv با grid و ستون‌های ۳ تایی استفاده کردیم تا تصاویر را در ستون‌های مختلف نمایش دهیم. هر عکس در یکdiv جداگانه قرار دارد و نام NFT به همراه تصویر آن نمایش داده می‌شود.