NFT 게이트 웹사이트를 만드는 방법

11577 단어 web3reactnftjavascript
NFT의 보다 역동적인 사용 사례 중 하나는 이를 NFT 보유자에게 멤버십 패스로 사용하는 것입니다. 컬렉션에서 특정 NFT에 액세스하여 제어되는 커뮤니티용 웹사이트를 만들고 싶다고 가정해 보겠습니다. NFT에 액세스하여 다운로드 가능한 콘텐츠 또는 숨겨진 페이지를 유지할 수 있습니다.

이 가이드에서는 React를 사용하여 NFT 소유를 기반으로 콘텐츠를 제한하는 웹사이트를 만들 것입니다.

예제 조직check it out here에서 최종 프로젝트의 사본을 가져올 수 있습니다.

NFT 드롭 발행



NFT 게이트 웹사이트를 만들려면 블록체인에 이미 배포된 NFT Collection , NFT Drop , Edition 또는 Edition Drop 계약이 필요합니다. 아직 생성하지 않은 경우 thirdwebTypeScript SDK 또는 thirdwebdashboard을 사용하여 생성할 수 있습니다.

If your NFTs are an NFT Drop or Edition Drop contract, set up claim phases before using the claiming functions mentioned later in the guide.



이 예에서는 Cookie Club 회원을 위해 Cookie Club이라는 NFT Drop 계약을 사용하고 있습니다. 🤫

thirdweb dashboard.에서 Cookie Club NFT Drop을 볼 수 있습니다.

템플릿 저장소 복제



시작하려면 작동하는 SDK 설정이 이미 포함된 cra-javascript-template를 사용합니다. 이 템플릿을 사용하면 프로젝트를 시작할 때 쉽게 배우고 시간을 절약할 수 있습니다.

If you’d prefer to use your own template, you can install the latest version of our SDK in your project with npm install @thirdweb-dev/sdk react ethers oryarn add @thirdweb-dev/sdk react ethers



먼저 cra-javascript-starter GitHub repository로 이동하고 '이 템플릿 사용'을 클릭하여 사본을 만듭니다.



프로젝트의 이름, 설명 및 기타 설정을 추가한 다음 장치에서 로컬로 복제합니다. 디렉터리를 열고 터미널에서 npm install를 실행하여 모든 종속성을 설치합니다.

블록체인 설정


src 폴더 내에서 index.js 파일을 엽니다. 먼저 체인 ID를 NFT Drop의 체인으로 변경합니다. 이 프로젝트에서는 NFT Drop 계약이 Rinkeby 테스트넷에 있으므로 Rinkeby를 사용합니다.

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { ChainId, ThirdwebProvider } from "@thirdweb-dev/react";

// This is the chainId your dApp will work on.
const activeChainId = ChainId.Rinkeby;

ReactDOM.render(
  <React.StrictMode>
    <ThirdwebProvider desiredChainId={activeChainId}>
      <App />
    </ThirdwebProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();


지갑 연결 버튼 설정



같은 폴더에 app.js 파일이 있습니다. 여기서는 사용자가 앱에 연결한 다음 사용자의 지갑 주소를 얻을 수 있도록 허용하려고 합니다. 프런트 엔드에서 사용자가 MetaMask와 연결할 수 있는 버튼을 만들 것입니다. 지갑이 연결되면 해당 주소가 표시됩니다.

import { useAddress, useMetamask } from "@thirdweb-dev/react";
import "./styles.css";

const App = () => {
  // get address of user & allow them to connect with metamask
  const address = useAddress();
  const connectWithMetamask = useMetamask();

  //if there isn't a wallet connected, display our connect MetaMask button
  if (!address) {
    return (
      <>
        <h1>Welcome to the Cookie Club</h1>
        <button className="btn" onClick={connectWithMetamask}>
          Connect MetaMask
        </button>
      </>
    );
  }

  // if an address is connected, display address
  return (
    <div>
      <p>Your address: {address}</p>
    </div>
  );
};

export default App;


앱이 어떻게 보이는지 미리 보고 터미널에서 npm start를 실행하여 작동하는지 확인하겠습니다.



조건부로 콘텐츠 렌더링 및 NFT 발행 버튼 추가



동일한App.js 파일에서 사용자의 연결 상태를 기반으로 특정 페이지를 렌더링하는 조건을 추가합니다. 우리는 사용자가 아직 NFT를 보유하지 않은 경우 드롭에서 NFT를 발행할 수 있기를 바랍니다. 연결된 사용자가 가지고 있는 경우 축하 텍스트를 표시합니다.
추가로 truncateAddress라는 단축 지갑 주소를 표시하는 도우미 기능을 추가했습니다. 앱에서도 자유롭게 추가하거나 생략할 수 있습니다.

import { useAddress, useMetamask } from '@thirdweb-dev/react';
import { useState, useEffect } from 'react';
import "./styles.css";

const App = () => {
    // get address of user & allow them to connect with metamask
    const address = useAddress();
    const connectWithMetamask = useMetamask();

    // add nft Drop contract
    const nftDrop = useNFTDrop("0x66463b3C1EBf08b9dE889BCc0A5cbf29dc0e2B7a");
    const [hasClaimedNFT, setHasClaimedNFT] = useState(false);
    const [isClaiming, setIsClaiming] = useState(false);

    // function to claim NFT
    const mintNFT = async () => {
        try {
            setIsClaiming(true);
            await nftDrop.claim(1);
            setHasClaimedNFT(true);
        catch (error) {
            setHasClaimedNFT(true);
            console.error("Failed to mint NFT", error);
        } finally {
            setIsClaiming(false);
        }
    }

    //if there isn't a wallet connected, display our connect MetaMask button
    if (!address) {
    return (
      <>
        <h1>Welcome to the Cookie Club</h1>
        <button className="btn" onClick={connectWithMetamask}>
          Connect MetaMask
        </button>
      </>
    );
  }

    // if the user is connected and has an NFT from the drop, display text
    if (hasClaimedNFT) {
    return <h2>Congratulations! You have a Cookie NFT! 🍪</h2>;
  }

  // helper function to truncate the address so it displays in a nice format
  function truncateAddress(address) {
    return `${address.slice(0, 6)}...${address.slice(-4)}`;
  }

    //if the user does not have an NFT, show their address and mint an NFT button
    return (
    <>
      <p className="address">
        There are no Cookie NFTs held by:{" "}
        <span className="value">{truncateAddress(address)}</span>
      </p>
      <button className="btn mint" disabled={isClaiming} onClick={mintNft}>
        Mint NFT
      </button>
    </>
  );
}

export default App;




상태 변경을 확인하기 위해 useEffect 추가



마지막으로 useEffect 기능을 추가하여 앱의 최신 상태를 최신 상태로 유지하려고 합니다. 이 함수는 종속성 배열의 항목이 변경될 때마다 트리거됩니다. 예를 들어 사용자의 주소 또는 nftDrop 연결이 끊어지거나 변경되면 그에 따라 새로 고치고 업데이트하려고 합니다.

import { useAddress, useMetamask, useNFTDrop } from "@thirdweb-dev/react";
import { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  // allow user to connect to app with metamask, and obtain address
  const address = useAddress();
  const connectWithMetamask = useMetamask();

  //
  const nftDrop = useNFTDrop("0x66463b3C1EBf08b9dE889BCc0A5cbf29dc0e2B7a");
  const [hasClaimedNFT, setHasClaimedNFT] = useState(false);
  const [isClaiming, setIsClaiming] = useState(false);

  useEffect(() => {
    // If they don't have an connected wallet, exit!
    if (!address) {
      return;
    }

    const checkBalance = async () => {
      try {
        const nfts = await nftDrop.getOwned(address);
        setHasClaimedNFT(nfts?.length > 0);
      } catch (error) {
        setHasClaimedNFT(false);
        console.error("Failed to get NFTs", error);
      }
    };
    checkBalance();
  }, [address, nftDrop]);

  const mintNft = async () => {
    try {
      setIsClaiming(true);
      await nftDrop.claim(1);
      setHasClaimedNFT(true);
    } catch (error) {
      setHasClaimedNFT(false);
      console.error("Failed to mint NFT", error);
    } finally {
      setIsClaiming(false);
    }
  };

    //if there isn't a wallet connected, display our connect MetaMask button
  if (!address) {
    return (
      <>
        <h1>Welcome to the Cookie Club</h1>
        <button className="btn" onClick={connectWithMetamask}>
          Connect MetaMask
        </button>
      </>
    );
  }

  // if the user is connected and has an NFT from the drop, display text
  if (hasClaimedNFT) {
    return <h2>Congratulations! You have a Cookie NFT! 🍪</h2>;
  }

  // truncates the address so it displays in a nice format
  function truncateAddress(address) {
    return `${address.slice(0, 6)}...${address.slice(-4)}`;
  }

  // if there are no NFTs from collection in wallet, display button to mint
  return (
    <>
      <p className="address">
        There are no Cookie NFTs held by:{" "}
        <span className="value">{truncateAddress(address)}</span>
      </p>
      <button className="btn" disabled={isClaiming} onClick={mintNft}>
        Mint NFT
      </button>
    </>
  );
}

export default function app;


프로젝트에 링크



당사example repository.에서 이 프로젝트의 사본을 만들 수 있습니다.

축하합니다!



갑시다! React를 사용하여 NFT 게이트 멤버십 웹 사이트를 만들었습니다. NFT 커뮤니티 회원을 위해 이 새 페이지 뒤에 다운로드 가능한 콘텐츠 또는 비밀 업데이트를 자유롭게 추가하십시오!

좋은 웹페이지 즐겨찾기