Page cover image

Build NFT Gated Dapp

In this tutorial we will see how we can use NFTs as an access token to a web portal.

In this sample project tutorial, we will learn about Utility NFTs and how we can use an NFT as an access token to a web portal.

By the end of this tutorial, you will be able to build your very own NFT gated dapp similar to

Shyft's Landing pass project.

What are Utility NFTs?

Utility NFTs, or NFTs with utility are special kind of NFTs which have use cases that go beyond just being one-of-a-kind NFTs. They are NFTs that give their owners special privileges, access rights, or prizes that they would not otherwise have.

Utility NFTs may be useful in various scenarios. One such scenario may be, if we have a private party, and 200 people are to be invited, we can printout and issue 200 invitation passes. Each pass will be non-fungible. However, every individual pass grants the same privilege, in this instance that is admission to the private party. The party organizer could provide 200 utility NFTs instead of 200 printed invitations. The NFTs will be distinct, non-fungible, and will function exactly like the printed invitation, i.e. they will grant admission to the private party.

Even though discovering real-world use cases for NFTs is at a very early stage, the cryptographically distinct tokens have the potential to be more than just JPEGs stored on a specific blockchain. Utility NFTs, or NFTs with real-world applications, may potentially be the catalyst for the transition of NFTs from just an investment fad to a brand new mode of interaction, play, and work. In the following sample project tutorial, we will see how we can use an NFT as an access token. We will check if one particular NFT is in your wallet or not (using SHYFT APIs), and accordingly, we will grant you access to a portal.

Read SHYFT Documentation here.

Pre-requisites for the project

To get started, we will need a few things.

Authentication: Get your Shyft API key

x-api-key is an authentication parameter, which gives you access to SHYFT APIs. You can get your own API Key from the SHYFT website. Just signup with your email id here and you can get it for free.

Phantom Wallet

We will need the Phantom wallet browser extension, you can download it from the link below.

Once done, set up your Phantom wallet account. On-screen tips are available, which will guide you through setting up and getting started. You can also find a detailed guide related to this here.

We will use React to develop this project but you can choose any language of your choice. As we are using react we will need Node.js installed on our computer. You can download node.js from here.

Let's start building

In this sample project, we will design a web portal and grant users access to that particular web portal based on one particular type of NFT in their wallet. We will first use SHYFT's read_all API to access a list of all NFTs in the user's wallet and check for an NFT with a specified update authority, or any specific attribute. If found, we will navigate the user to a new web portal.

If we cannot find the specified NFT, we can provide the user an option to mint a new NFT using SHYFT APIs.

Create React App

To create a new react app, navigate to the directory in which you want to create a react app and open the terminal in that particular directory. Then use the following command to create a new react application.

npx create-react-app access-app

This will create a new react application and we will be all set to start creating our new react application.

Code Editor

We have used VScode as our code editor for this project but you can use any editor of your choice such as Sublime text, Notepad++, Atom, or any editor of your choice. Once decided, let's open up our project in VScode editor. It should look something like this.

The Visual Studio Code Editor

Connect Wallet and check module

Let's create a new module that will connect our wallet and check if one particular NFT is present in your wallet or not. We will need a few packages to get this module working. We have also used some of these modules in our previous projects, you can find the details here.

For connecting the wallet, we install and use the following packages,

npm install @solana/web3.js @solana/wallet-adapter-phantom

and we will need the following packages for making a network request.

npm install axios

Once done, let's create a react component for connecting the wallet. We will add a simple button that will connect the wallet and will get your wallet address. Once we have the wallet address, we will use SHYFT APIs to get all the wallet NFTs for checking purposes. Please note that we have used very preliminary styling for our sample project, but you can add styles of your own if you want.

Simple connect wallet button

We create a function that we will use to connect a wallet, and we will execute this function when we click on the connect wallet. Before that, we create a few state variables using react's very own useState hook for storing the wallet address and checking if we have access to the portal or not.

const [walletId,setWalletId] = useState(null);
const [hasAccess,setAccess] = useState(false);

Now we create the connect wallet function.

const connectWallet = async () => {
    const { solana } = window;
    
    if(!solana)
    {
        alert("Please Install Phantom"); //If wallet Adapter not installed
    }
    try{  
        const network = "devnet";
        const phantom = new PhantomWalletAdapter();
        await phantom.connect();
        const rpcUrl = clusterApiUrl(network);
        const connection = new Connection(rpcUrl,"confirmed");
        
        const wallet = {
            address: phantom.publicKey.toBase58(), //getting the wallet id in base 58 format
        };

        if(wallet.address)
        {
            const accountInfo = await connection.getAccountInfo(new PublicKey(wallet.address),"confirmed");
            console.log(accountInfo); 
            console.log('Wallet Connected'); 
            setWalletId(wallet.address); //setting the wallet id using reacts setState.
        }

    }
    catch(err)
    {
        console.log(err);
    }
}

There are several other methods that can be used to connect wallets, we have used this one, but can use any method you feel like. You can even take the wallet address as an input field directly.

Once connected, we are ready to make our API call. We use react's useEffect hook to make the API call, and we add the walletId state variable as a dependency, so that the API call takes place whenever the walletId changes.

The API call to fetch all NFTs

Before making the API calls, we will need the x-api-key. We will need to pass X-API-KEY in the header, this key is used for authentication purposes.

You can find more about our APIs here.

Getting Your Own X-API-KEY

x-api-key is an important parameter we pass on to the header while making the API call for authentication purposes. You can get your own x-api-key from our own SHYFT website. Just signup with your email id here and you can get it for free.

Now, once we have the wallet address, we are ready to make the API call to fetch our required data which in this case is the token list.

To fetch the data, we have used the axios package, but you can use JavaScript's very own fetch or any other package you want. We have made this call inside React's useEffect hook. Here is the code.

Our API endpoint for reading al NFTs

https://api.shyft.to/sol/v1/nft/read_all?network=devnet&address=wallet_address&update_authority=update_authority_of_the_nft&refresh=refresh`
useEffect(() => {
        let nftUrl = `https://api.shyft.to/sol/v1/nft/read_all?network=devnet&address=${walletId}&update_authority=wallet_address_which_you_will_use_for_auth&refresh=refresh`;
        //add the wallet address which you want to check as an authentication parameter
        //access will be granted if and only if an NFT with this update authority is present in your wallet
        const xKey = 'your-x-api-key-from-shyft-website'

        axios({
          // Endpoint to get NFTs
          url: nftUrl,
          method: "GET",
          headers: {
            "Content-Type": "application/json",
            "x-api-key": xKey,
          },
        })
          // Handle the response from backend here
          .then((res) => {
            console.log(res.data);
            if (res.data.success === true) {
              setNfts(res.data.result);
              //or check the length of the nfts array over here,
              // if greater than zero, it will imply atleast one NFT with the 
              //required update_authority is present
            } 
          })
          // Catch errors if any
          .catch((err) => {
            console.warn(err);
            
          });
    
     
    }, [walletId]);

If the response from this API is true, we should have a response that looks somewhat like this.

{
    "success": true,
    "message": "All NFTS in your wallet",
    "result": [
        {
            "name": "Girish",
            "symbol": "GN",
            "royalty": 5,
            "image_uri": "https://nftstorage.link/ipfs/bafybeidf3jfdczfu56knpfsqbcveks62xy44uognecz64kxvmaowqyg23q",
            "description": "Serial Entrepreneur ",
            "mint": "3iRECKHPvnfkH5wF6ZCTM4e9nULSevJJiCrxCfgG9eM7",
            "owner": "BvzKvn6nUUAYtKu2pH3h5SbUkUNcRPQawg4bURBiojJx",
            "attributes": {
                "girish": "true"
            },
            "update_authority": "BvzKvn6nUUAYtKu2pH3h5SbUkUNcRPQawg4bURBiojJx"
        },
        {
            "name": "Cool Monkry",
            "symbol": "CMY",
            "royalty": 5,
            "image_uri": "https://nftstorage.link/ipfs/bafkreie2ef3z2cixfnxby5zfprv2xa7lydy5biky34v2p2fgsb5b4mcfaa",
            "description": "Shyft makes web3 development so easy.",
            "mint": "BMv5StFwfJsXmMmehYATuytfhkmANvfhUHpu6YQHF1pX",
            "owner": "BvzKvn6nUUAYtKu2pH3h5SbUkUNcRPQawg4bURBiojJx",
            "attributes": {
                "edification": "100"
            },
            "update_authority": "BFefyp7jNF5Xq2A4JDLLFFGpxLq5oPEFKBAQ46KJHW2R"
        },
        {
            "name": "GUMBALL #247475",
            "symbol": "GUMBALL",
            "royalty": 1,
            "image_uri": "",
            "description": "Celebrate the new era of compressed NFTs",
            "mint": "6jhqJGJreGpQEP73ey5as7UBCzeRSWuLSM8m1V3pdBHb",
            "owner": "BvzKvn6nUUAYtKu2pH3h5SbUkUNcRPQawg4bURBiojJx",
            "attributes": {
                "Vibe Check": "Passed",
                "Solana Summer": "🔥 Started 🔥",
                "NFTs": "Compressed"
            },
            "update_authority": "2GDAzSBsMiS44gJzSEqH3APkabHGZcicNM9G7cmUo9hE"
        }
    ]
}

NFT Access Check

If successful and the length of the nfts array is greater than 0, it would imply that we have at least one NFT whose update_authority is the wallet address which we are using for authentication (update_authority = AagBXTi3HHFNMqTcWm3oYoQYSuUj1LGvb12vsPB if AagBXTi3HHFNMqTcWm3oYoQYSuUj1LGvb12vsPB is the wallet address we are using for authentication). We can also perform checking on NFTs with specific attributes, and check if the user's wallet has one NFT with some specified value such as "health:50" or "Power: 100", or maybe an attribute as a password, for that we would need to iterate through the nfts array and check if any element of the array has an attribute.

let flag = 0;
nfts.forEach((element) => {
  if (
    //check if element has an attribute that is equal to the attribute you are looking for authentication
  ) {
    flag = 1;
  }
});
if (flag === 1) {
    setAccess(true);
    //redirect user from here
} else {
    //dont redirect, and display the error message
    setAccess(false);
    setMsg('You do not have access');
}

Once authenticated we can redirect the user to our access portal.

Grant access to the portal if you have an NFT with the required update_authority in your wallet

If the authentication fails, that is, if the user does not have the NFT in their wallet, we can give them an option to mint an NFT from another wallet, we hope to illustrate this soon in our more upcoming tutorials.

That is all regarding this sample project tutorial, where we see how we can use NFT as an access token to access a portal. If you enjoyed this tutorial and want to give our code a whirl, or make some contributions, here is a link to this sample project.

Don't forget to experience the full flow here.

Project on Ultility NFTs: How to use NFTs as access tokens

Resources

If you liked this, you can also read our tutorials on How to get your user's token balances? or Read all NFTs from a wallet.

Hope you have a great time building Dapps with SHYFT APIs. Happy Hacking!! 😇

Last updated

Was this helpful?