Build Your Own NFT Wallet Gallery with near.social and indexer.xyz

Joshua OwenJoshua Owen
Mar 16, 2023|4 min read

In the rapidly evolving world of blockchain and NFTs, having a personalized wallet gallery to showcase your NFT collection is not only a convenience but also a statement. In this tutorial, we'll guide you through creating a visually appealing and functional NFT Wallet Gallery using the power of near.social and indexer.xyz. By the end of this tutorial, you'll have a solid foundation to build upon and customize as you please, while also contributing to the growing NFT ecosystem.

Introduction

near.social is a decentralized platform for creating React applications that leverage the power of blockchain. It enables developers to create applications that are censorship-resistant, secure, and decentralized.

indexer.xyz is a powerful API that provides access to a wide range of NFT metadata from various blockchains, making it easy for developers to create NFT-focused applications.

By combining the capabilities of near.social and indexer.xyz, we'll build an NFT Wallet Gallery that showcases your NFTs based on your wallet address. And the best part? The code is open-source, so you can easily fork it, make updates, and create your own unique NFT Wallet Gallery.

🔗 Source Code Here

Prerequisites

Before we dive into the code, make sure you have the following:

  1. A basic understanding of JavaScript and React.
  2. Familiarity with the Fetch API for making HTTP requests.
  3. A code editor of your choice.

The NFT Wallet Gallery we'll create consists of several key components:

  1. An input field for the wallet address.
  2. A button to fetch NFT data based on the wallet address.
  3. A responsive grid displaying NFT cards, each containing an image, name, rank, token ID, and collection.
  4. Links to the respective NFTs on the TradePort platform.

Step 1: Set Up the Application

First, let's set up a new React application on near.social. Head over to near.social and follow the steps to create a new application.

Once your application is set up, you'll have a basic near.social app to start building your NFT Wallet Gallery.

Step 2: Initialize State

In your application's main component, initialize the state to hold the wallet address and NFT data:

initState({
  walletAddress: "",
  nftData: [],
});

Step 3: Fetch NFT Data

Now, let's create a function that fetches NFT data from indexer.xyz based on the wallet address:

const fetchData = async () => {
  // ...
};

Inside this function, use the Fetch API to make a POST request to the indexer.xyz GraphQL endpoint:

const response = await fetch("https://byz-multi-chain-01.hasura.app/v1/graphql", {
  // ...
});

Be sure to include the necessary headers and the GraphQL query in the request body:

headers: {
  "x-api-key": "ChRbeKE.c94220449dbb45973a67a614b1f590be",
  "Content-Type": "application/json",
  "Hasura-Client-Name": "near-social",
},
body: JSON.stringify({
  query: `
    query MyQuery {
      near {
        nft_meta(where: {nft_state: {owner: {_eq: "${state.walletAddress}"}}}) {
          // ...
        }
      }
    }`,
}),

After fetching the data, update the state with the NFT data

const data = await response.json();
const nftData = data.data.near.nft_meta;
State.update({ nftData: nftData });

All together now!

const fetchData = () => {
  State.update({ nftData: [] });

  let data = fetch("https://byz-multi-chain-01.hasura.app/v1/graphql", {
    method: "POST",
    headers: {
      "x-api-key": "ChRbeKE.c94220449dbb45973a67a614b1f590be",
      "Content-Type": "application/json",
      "Hasura-Client-Name": "near-social",
    },
    body: JSON.stringify({
      query: `
        query MyQuery {
          near {
            nft_meta(where: {nft_state: {owner: {_eq: "${state.walletAddress}"}}}) {
              image
              name
              token_id
              collection {
                slug
              }
              rarity
              ranking
            }
          }
        }`,
    }),
  });

  if (data) {
    const nftData = data.body.data.near.nft_meta;
    State.update({ nftData });
  }
};

Step 4: Update Wallet Address

Create a function to update the wallet address in the state when the user inputs a new value:

const updateWalletAddress = (e) => {
  State.update({ walletAddress: e.target.value });
};

Step 5: Display NFT Cards

Now that we have the NFT data, let's create a responsive grid to display NFT cards. Each card will contain the NFT image, name, rank, token ID, and collection.

First, create a function that returns the appropriate color based on the rarity of the NFT:

const getRarityColor = (rarity) => {
  // ...
};

Next, create the JSX for the NFT Wallet Gallery. This includes the input field for the wallet address, the fetch button, and the grid containing the NFT cards:

return (
  <div
    style={{
      fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
      maxWidth: "1200px",
      margin: "0 auto",
      padding: "20px",
    }}
  >
    <a href="https://indexer.xyz/" target="_blank" rel="noopener noreferrer">
      <img
        src="https://indexer.xyz/indexer-logo-black.svg"
        alt="Indexer.xyz logo"
        style={{ height: "1.5em", verticalAlign: "middle" }}
      />
    </a>
    <h1 style={{ fontSize: "48px", fontWeight: "bold", marginBottom: "20px" }}>
      NFT Wallet Gallery
    </h1>
    <div
      style={{
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        marginBottom: "30px",
        flexWrap: "wrap",
      }}
    >
      <label
        htmlFor="walletAddressInput"
        style={{ fontSize: "16px", marginRight: "10px" }}
      >
        Enter Wallet Address:
      </label>
      <input
        type="text"
        id="walletAddressInput"
        value={state.walletAddress}
        onChange={updateWalletAddress}
        style={{
          border: "1px solid #ccc",
          borderRadius: "5px",
          padding: "5px 10px",
          margin: "0 10px 10px 0",
          flexGrow: 1,
        }}
      />
      <button
        onClick={fetchData}
        style={{
          backgroundColor: "#0070c9",
          border: "none",
          borderRadius: "5px",
          color: "#fff",
          cursor: "pointer",
          padding: "5px 10px",
          marginLeft: "10px",
        }}
      >
        Fetch NFTs
      </button>
    </div>
    {state.nftData.length > 0 && (
      <div
        style={{
          display: "flex",
          flexWrap: "wrap",
          gap: "20px",
          justifyContent: "center",
          marginTop: "20px",
        }}
      >
        {state.nftData.map((nft) => (
          <a
            href={`https://www.tradeport.xyz/near/collection/${nft.collection.slug}/${nft.token_id}`}
            target="_blank"
            rel="noopener noreferrer"
            style={{ textDecoration: "none", color: "inherit" }}
          >
            <div
              style={{
                backgroundColor: "#f0f0f0",
                borderRadius: "10px",
                boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)",
                padding: "20px",
                width: "200px",
                textAlign: "center",
              }}
            >
              <img
                src={nft.image}
                alt={nft.name}
                style={{
                  width: "100%",
                  height: "auto",
                  borderRadius: "5px",
                  objectFit: "cover",
                  marginBottom: "15px",
                }}
              />
              <h3 style={{ fontSize: "18px", margin: "0 0 10px" }}>
                {nft.name}
              </h3>
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "space-between",
                  marginBottom: "5px",
                }}
              >
                <span
                  style={{
                    backgroundColor: "#3f51b5",
                    borderRadius: "20px",
                    color: "#fff",
                    display: "inline-block",
                    fontSize: "12px",
                    fontWeight: "bold",
                    padding: "3px 8px",
                  }}
                >
                  Rank: {Math.round(nft.ranking)}
                </span>
              </div>
              <p style={{ fontSize: "14px", marginBottom: "5px" }}>
                Token ID: {nft.token_id}
              </p>
              <p style={{ fontSize: "14px" }}>
                Collection: {nft.collection.slug}
              </p>
            </div>
          </a>
        ))}
      </div>
    )}
  </div>
);

Conclusion

Congratulations! You have successfully built an NFT Wallet Gallery using near.social and indexer.xyz. The combination of near.social's decentralized React platform and indexer.xyz's powerful API makes it easy to create unique, decentralized, and responsive NFT applications.

We encourage you to fork the code, make updates, and create your own unique NFT Wallet Gallery. The possibilities are endless when you combine the power of near.social and indexer.xyz. Share your creations and contribute to the growing NFT ecosystem. Happy coding!