WEB3DEV

Cover image for Como construir um painel de mercado NFT usando a API para NFT GraphQL do QuickNode
Diogo Jorge
Diogo Jorge

Posted on

Como construir um painel de mercado NFT usando a API para NFT GraphQL do QuickNode

Um tutorial passo a passo sobre como construir um painel interativo de mercado NFT usando API GraphQL NFT do QuickNode, React, Next.js e Tailwind CSS

Tokens não fungíveis (NFTs) são ativos digitais que representam a propriedade de um item único, como uma obra de arte ou um item colecionável. Com a ascensão dos NFTs, os desenvolvedores estão procurando maneiras eficientes e flexíveis de construir aplicativos que aproveitem as propriedades exclusivas dos NFTs.

Mas obter todos os dados do mercado de forma consistente não é uma tarefa simples; os desenvolvedores precisam rastrear a blockchain e filtrar os dados importantes. Uma tarefa tediosa e frustrante.

A API GraphQL NFT do QuickNode fornece um método simples e unificado para os desenvolvedores interagirem com os mercados NFT, independentemente da tecnologia subjacente. Este tutorial explicará passo a passo como usar essa API.

Nota: A QuickNode adquiriu recentemente Icy.tools e usaremos a biblioteca icy-nft-hooks para acessar a API GraphQL NFT e não chamar a API diretamente.

Image description

O que é a QuickNode?

A QuickNode é uma plataforma blockchain que fornece infraestrutura para desenvolvedores construir e dimensionar aplicativos descentralizados (DApps). Ela oferece um conjunto de ferramentas e serviços, incluindo uma API de desenvolvedor, para facilitar aos desenvolvedores a construção, teste e implantação de DApps em múltiplas redes blockchain.

A QuickNode visa simplificar o processo de construção em blockchain e torná-lo mais acessível para desenvolvedores, ao mesmo tempo que fornece infraestrutura de alto desempenho para suportar a crescente demanda por aplicações descentralizadas.

O que é a API para NFTs GraphQL do QuickNode?

Inscreva-se para obter a API para NFTs GraphQL gratuitamente!

A API para NFTs GraphQL é um conjunto de ferramentas e serviços que permite aos desenvolvedores interagir com plataformas NFT usando a linguagem de consulta GraphQL. Esta API fornece uma maneira conveniente para os desenvolvedores descobrirem, rastrearem e analisarem NFTs com dados de volume e piso em tempo real, gráficos históricos e dados de tendências, valores de portfólio de NFT em qualquer carteira e muito mais.

Atualmente eles se concentram em transações ERC-721 por meio da Opensea, LooksRare, Genie, Gem.xyz, Nifty Gateway, X2Y2, 0x, e CriptoPunks. O suporte multi-cadeia chegará em breve, junto com mais mercados. A API torna mais fácil para os desenvolvedores criarem aplicativos que aproveitem as propriedades exclusivas dos NFTs, como escassez digital e prova de propriedade.

Explore o Mercado da QuickNode!

Além de sua API para NFTs GraphQL, a QuickNode oferece muito mais ferramentas e soluções para desenvolvedores Web3 em seu Mercado. Isso inclui um estimador de preço do gás, API crossmint NFT, API antifraude GoPlus e uma enorme biblioteca de guias, tutoriais, documentação e outros recursos para desenvolvedores e criados por especialistas.

Início rápido com API QuickNode

Nesta seção, aprenderemos como construir um painel NFT usando API GraphQL NFT do QuickNode, React, JavaScript, Next.js e Tailwind CSS. O aplicativo da Web resultante fornecerá uma interface amigável que exibe dados de mercado NFT em tempo real, como preço mínimo, vendas, preço médio, volume e valor de mercado.

Image description

As Funcionalidades

  1. Os usuários podem inserir várias entradas, como Volume, Preço Mínimo e Média, na seção 'Ordenar por'.
  2. O aplicativo irá interagir com a API para NFTs GraphQL da QuickNode para recuperar dados de mercado NFT.
  3. O aplicativo exibirá os dados em uma visualização de tabela.
  4. Os usuários podem filtrar ainda mais a saída selecionando ordem crescente ou decrescente na seção 'Direção do pedido'.
  5. Os usuários também podem selecionar o período de tempo desejado, como as últimas 1 hora, 12 horas ou um dia, para os dados.

O stack de tecnologia

Comece gratuitamente na QuickNode!

Os pré-requisitos

Etapa 01: Crie um projeto Next.js

Vamos configurar nosso ambiente e instalaremos as dependências necessárias. Abra um terminal em sua máquina e navegue até o local do diretório onde deseja armazenar seu projeto Next.js. Em seguida, execute o seguinte comando:

yarn create next-app .
Enter fullscreen mode Exit fullscreen mode

Este comando cria um novo projeto inicial Next.js no diretório especificado. Agora, inicie o servidor de desenvolvimento local executando o seguinte comando:

Yarn dev
Enter fullscreen mode Exit fullscreen mode

O comando acima configura seu ambiente de desenvolvimento local. Copie e cole http://localhost:3000 em seu navegador da web para iniciar o projeto inicial Next.js. Esta é a aparência do seu navegador da Web:

Image description

O aplicativo atual contém apenas o código inicial fornecido por Next.js, que modificaremos ao longo deste tutorial para criar a interface de usuário personalizada para nosso painel de mercado NFT.

Agora, vamos instalar o Tailwind CSS e suas dependências necessárias usando npm, executando o seguinte comando no terminal:

npm install -D tailwindcss postcss autoprefixer
Enter fullscreen mode Exit fullscreen mode

Execute o comando init para gerar ambos arquivos tailwind.config.js e postcss.config.js:

npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

No seu arquivo tailwind.config.js, adicione os caminhos a todos os seus arquivos de modelo atualizando o código com o seguinte:

Arquivo ./tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode

Agora adicione as diretivas @tailwind para cada uma das camadas do Tailwind ao seu arquivo globals.css. O topo do seu arquivo globals.css deve ficar assim:

Arquivo ./styles/globals.css

@tailwind base;
@tailwind components;
@tailwind utilities;

...
Enter fullscreen mode Exit fullscreen mode

Etapa 02: Instalando a biblioteca icy-nft-hooks

Para criar o painel do mercado NFT, precisamos de dados em tempo real e iremos buscá-los usando a API para NFTs GraphQL. Vamos instalar e configurar icy-nft-hooks, uma biblioteca de ganchos da React que atua como um wrapper para a icy.tools da API GraphQL. Esta biblioteca nos permite obter dados de mercado NFT em tempo real, como preço mínimo, vendas, preço médio, volume, valor de mercado, etc.

Instale o icy-nft-hooks com o seguinte comando:

yarn add @quicknode/icy-nft-hooks
yarn add @apollo/client graphql
Enter fullscreen mode Exit fullscreen mode

No diretório pages, navegue até o arquivo _app.js. Copie e cole o seguinte código no arquivo_app.js.

import "../styles/globals.css";
import { IcyProvider } from "@quicknode/icy-nft-hooks";

export default function App({ Component, pageProps }) {
  return (
    <IcyProvider apiKey={QUICKNODE_NFT_API_KEY}>
      <Component {...pageProps} />
    </IcyProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Estamos importando o gancho IcyProvider do pacoteicy-nft-hookse agrupando todo o aplicativo da Web com o gancho IcyProvider.

Etapa 03: Obtendo uma chave API NFT

Como você pode ver no código acima, precisaremos de uma chave de API para buscar dados de mercado NFT em tempo real. Para obter a chave API, siga estas etapas:

Abra o link Icy.tools e clique no botão "Sign-up" (Cadastre-se).

Image description

Insira os dados e clique no botão "Cadastrar-se".

Image description

Você chegará à página "Explorar" da Icy.tools, onde verá algo assim:

Image description

Clique no botão "Settings" (Configurações) no lado esquerdo. Você verá a chave API.

Image description

Etapa 04: Instalando o pacote dotenv

Recomendo armazenar informações confidenciais, como chaves de API, em variáveis ​​de ambiente, em vez de codificá-las rigidamente no código. Nós vamos usar o pacote dotenv para armazenar informações confidenciais. Execute o seguinte comando para instalar o pacote dotenv:

yarn add --dev dotenv
Enter fullscreen mode Exit fullscreen mode

Crie um arquivo .env na pasta raiz. Adicione a variável de ambiente.

QUICKNODE_NFT_API_KEY ="c34kndhiflmln-API-KEY"
Enter fullscreen mode Exit fullscreen mode

Etapa 05: Buscando os dados de mercado NFT

Nesta seção, criaremos a função Collections (Coleções) que aceita várias entradas do usuário como "Período de tempo" (1 hora, 12 horas, um dia, sete dias), "Ordenar por" (Vendas, Média, Volume) e "Direção do pedido" (Descendente, Ascendente).

icy-nft-hooks nos fornece os métodos useTrendingCollections e TrendingCollectionsTimePeriod,que implementaremos e utilizaremos dentro de nossa função Collections.

Crie um novo arquivo dentro do diretório pages e nomeie-o Collections.js. Copie e cole o seguinte código dentro dele:

Arquivo: ./pages/Collections.js

import {
  useTrendingCollections,
  TrendingCollectionsTimePeriod,
} from "@quicknode/icy-nft-hooks";
import { useState, useEffect } from "react";

function Collections() {
  const [cursor, setCursor] = useState("");
  const [timePeriod, setTimePeriod] = useState(
    TrendingCollectionsTimePeriod.TWELVE_HOURS
  );
  const [orderBy, setOrderBy] = useState("VOLUME");
  const [orderDir, setOrderDir] = useState("DESC");
  const { collections, pageInfo } = useTrendingCollections(
    {
      orderBy: orderBy,
      orderDirection: orderDir,
      timePeriod: timePeriod,
      first: 10,
      after: cursor,
    }
  );

  return (
    <div className="App bg-black text-white flex flex-col justify-start items-center gap-10">
      <div className="w-full h-full flex flex-col justify-start gap-5 items-center">
        <h1 className="text-7xl font-bold">
          NFT Market Dashboard
        </h1>
        <h3 className="text-xl font-semibold">
          Powered by{" "}
          <a
            className="underline"
            href="https://docs.icy.tools/developer-api/api-reference"
          >
            QuickNode's GraphQL NFT API
          </a>
        </h3>
      </div>
      <div className="w-full h-full flex flex-col justify-evenly items-center">
        <div className="w-full h-full flex flex-col sm:flex-row justify-evenly items-center">
          <div className="w-full flex justify-start gap-3">
            <div className="text-xl">Stats in last</div>
            <button
              className="text-xl text-cyan-500"
              onClick={() =>
                setTimePeriod(
                  TrendingCollectionsTimePeriod.TWELVE_HOURS
                )
              }
            >
              12 hours
            </button>
            <button
              className="text-xl text-cyan-500"
              onClick={() =>
                setTimePeriod(
                  TrendingCollectionsTimePeriod.ONE_HOUR
                )
              }
            >
              1 hour
            </button>
            <button
              className="text-xl text-cyan-500"
              onClick={() =>
                setTimePeriod(
                  TrendingCollectionsTimePeriod.ONE_DAY
                )
              }
            >
              1 day
            </button>
            <button
              className="text-xl text-cyan-500"
              onClick={() =>
                setTimePeriod(
                  TrendingCollectionsTimePeriod.SEVEN_DAYS
                )
              }
            >
              7 days
            </button>
          </div>
          <div className="w-full flex justify-start gap-3">
            <div className="text-xl">Order By</div>
            <button
              className="text-xl text-cyan-500"
              onClick={() => setOrderBy("SALES")}
            >
              Sales
            </button>
            <button
              className="text-xl text-cyan-500"
              onClick={() => setOrderBy("AVERAGE")}
            >
              Average
            </button>
            <button
              className="text-xl text-cyan-500"
              onClick={() => setOrderBy("VOLUME")}
            >
              Volume
            </button>
          </div>
          <fieldset className="w-full flex justify-start gap-3">
            <div className="text-xl">Order Direction</div>
            <input
              id="desc"
              type="radio"
              name="orderDir"
              className="text-xl text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"
              onClick={() => setOrderDir("DESC")}
            />
            <label
              htmlFor="desc"
              className="text-xl text-cyan-500"
            >
              Descending
            </label>
            <input
              id="asc"
              type="radio"
              name="orderDir"
              className="text-xl text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"
              onClick={() => setOrderDir("ASC")}
            />
            <label
              htmlFor="asc"
              className="text-xl text-cyan-500"
            >
              Ascending
            </label>
          </fieldset>
        </div>
        <table className="table-auto border-separate border border-slate-400 w-full text-sm text-left text-white my-5">
          <thead className="table-header-group text-xl">
            <tr className="table-row">
              <th
                scope="col"
                className="table-cell text-left px-6 py-3"
              >
                Collection
              </th>
              <th
                scope="col"
                className="table-cell text-right px-6 py-3"
              >
                Floor
              </th>
              <th
                scope="col"
                className="table-cell text-right px-6 py-3"
              >
                Volume
              </th>
              <th
                scope="col"
                className="table-cell text-right px-6 py-3"
              >
                Total Sales
              </th>
              <th
                scope="col"
                className="table-cell text-right px-6 py-3"
              >
                Average
              </th>
            </tr>
          </thead>
          <tbody>
            {collections &&
              collections.map((collection) => {
                return (
                  <tr
                    key={collection.address}
                    className="table-row odd:bg-gray-800 odd:border-gray-700 even:bg-gray-900 even:border-gray-700"
                  >
                    <th
                      scope="row"
                      className="table-cell text-left  px-6 py-2 font-medium text-white whitespace-nowrap "
                    >
                      {collection.name}
                    </th>
                    <td className="table-cell text-right px-6 py-2  mono">
                      Ξ{collection.stats.floor.toFixed(3)}
                    </td>
                    <td className="table-cell text-right px-6 py-2  mono">
                      Ξ{collection.stats.volume.toFixed(3)}
                    </td>
                    <td className="table-cell text-right px-6 py-2  mono">
                      {collection.stats.totalSales}
                    </td>
                    <td className="table-cell text-right px-6 py-2  mono">
                      Ξ
                      {collection.stats.average.toFixed(3)}
                    </td>
                  </tr>
                );
              })}
          </tbody>
        </table>
        {pageInfo?.hasNextPage && (
          <div className="w-full flex items-center justify-end">
            <button
              onClick={() => {
                setCursor(pageInfo.endCursor ?? undefined);
              }}
              className="rounded-md bg-blue-900 p-5"
            >
              Next &gt;
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

export default Collections;
Enter fullscreen mode Exit fullscreen mode

Se você está curioso para saber por que estamos usando valores como ONE_HOUR, TWELVE_HOUR, SALES, DESC, AVERAGE,etc., pressione ctrl + clique com o botão esquerdo em TrendingCollectionsPeriod.

Etapa 06: Adicionando Estilo e Layout

Crie um novo diretório chamado components na raiz e, dentro dela, crie um novo arquivo chamado Layout.js. Adicione o seguinte código dentro dele:

Arquivo: ./components/Layout.js

import React from "react";

const Layout = (props) => {
  const { children } = props;
  return (
    <div className="w-full h-full flex flex-col p-10">
      <div className="w-full h-full flex flex-col">{children}</div>
    </div>
  );
};

export default Layout;
Enter fullscreen mode Exit fullscreen mode

Importe o Layout.js para dentro do arquivo_app.js.

import "../styles/globals.css";
import { IcyProvider } from "@quicknode/icy-nft-hooks";
import Layout from "components/Layout";

export default function App({ Component, pageProps }) {
  return (
    <IcyProvider apiKey={process.env.QUICKNODE_NFT_API_KEY}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </IcyProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Agora navegue para o arquivo index.js e faça as seguintes mudanças:

Arquivo: ./pages/index.js

import Head from "next/head";
import Collections from "./Coleções";

export default function Home() {
  return (
    <>
      <Head>
        <title> QuickNode Graph NFT API </title>
        <meta name="descrição" content="Gerado ao criar o próximo app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Collections />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Agora abra o http://localhost:3000 no seu navegador. Você criou um painel interativo do mercado NFT.

Image description

Base de código completa

Repositório GitHub do projeto completo: Painel do mercado NFT

Image description

Fontes adicionais

GitHub - AAYUSH-GUPTA-coder/quicknode-graphql-nft-api-tutorial: nft-market-dashboard

painel do mercado nft. Contribua para o desenvolvimento do AAYUSH-GUPTA-coder/quicknode-graphql-nft-api-tutorial criando uma conta no GitHub.

Referência de API docs.icy.tools

qn-oss/packages/libs/ui/nft-react-hooks/README.md em principal · quiknode-labs/qn-oss

Código aberto QuickNode. Contribua para o desenvolvimento do quiknode-labs/qn-oss criando uma conta no GitHub.

Este artigo foi escrito por Aayush Gupta e traduzido por Diogo Jorge. O artigo original pode ser encontrado aqui.

Latest comments (0)