WEB3DEV Español

Cover image for Cómo Construir un Tablero de Mercado NFT Usando la API NFT GraphQL de QuickNode
Gabriella Alexandra Martinez Viloria
Gabriella Alexandra Martinez Viloria

Posted on

Cómo Construir un Tablero de Mercado NFT Usando la API NFT GraphQL de QuickNode

Una guía paso a paso sobre cómo construir un tablero de mercado NFT interactivo, usando la API NFT GraphQL de QuickNode, React, Next.js y Tailwind CSS.

Los tokens no fungibles (NFTs) son activos digitales que representan la titularidad de un objeto único, como una pieza de arte o un coleccionable. Con el surgimiento de los NFTs, los desarrolladores están buscando formas eficientes y flexibles para construir aplicaciones que aprovechen las propiedades únicas de los NFTs.

Pero, obtener todos los datos del mercado de una forma consistente no es una tarea fácil, los desarrolladores tienen que arrastrarse entre la blockchain y filtrar las partes y piezas de datos importantes. Es una tarea tediosa y frustrante.

La API NFT GraphQL de QuickNode proporciona un método simple y unificado para que los desarrolladores interactúen con los mercados NFT, sin que importe la tecnología subyacente. Este tutorial te explicará, paso a paso, sobre cómo usar esta API.

Nota: QuickNode adquirió Icy.tools recientemente y usaremos la biblioteca icy-nft-hooks para acceder al API NFT GraphQL y no llamar a la API directamente.

¿Qué es QuickNode?

QuickNode es una plataforma blockchain que proporciona una infraestructura para los desarrolladores para que construyan y escalen aplicaciones descentralizadas (dApps). Ofrece una gama de herramientas y servicios, incluyendo un desarrollador API, para hacer que sea fácil para que los desarrolladores construyan, prueben y desplieguen dApps en múltiples redes blockchain. QuickNode apunta a simplificar el proceso de construcción en la blockchain y hacer que sea más accesible para los desarrolladores mientras proporciona una infraestructura de alta performance para soportar la demanda de crecimiento para las aplicaciones descentralizadas.

¿Qué es la API NFT GraphQL de QuickNode?

¡Suscríbete gratis a la API NFT GraphQL!

La API NFT GraphQL es un conjunto de herramientas y servicios que permite a los desarrolladores interactuar con las plataformas NFT usando el lenguaje de consulta GraphQL. La API proporciona una forma conveniente para que los desarrolladores descubran, rastreen y analicen los NFTs en el piso de tiempo real y el volumen de datos, histórico de gráficos y los datos en tendencia, el portafolio de valor NFT en cualquier cartera y más.

Actualmente se enfocan en transacciones ERC-721 a través de OpenSea, LooksRare, Genie, gem.xyz, Nifty Gateway, X2Y2, 0x y CryptoPunks. El soporte multicadena viene pronto, junto a más mercados. La API hace que sea fácil para los desarrolladores construir aplicaciones que aprovechen las propiedades únicas de los NFTs como la escasez digital y la prueba de titularidad.

¡Explora el Mercado QuickNode!

Además de su API NFT GraphQL, QuickNode ofrece muchas más herramientas y soluciones para los desarrolladores Web3 en su mercado. Esto incluye un estimador del precio de gas, la acuñación cruzada del NFT API, la API anti fraude GoPlus y una biblioteca masiva de guías expertas, tutoriales, documentación y otros recursos de desarrollador.

Inicio Rápido con el API de QuickNode

En esta sección, aprenderemos cómo construir un tablero NFT usando el API NFT GraphQL de QuickNode, React, JavaScript, Next,js y Tailwind CSS. La aplicación web resultante proveerá una interfaz amigable con el usuario que muestra, en tiempo real, los datos del mercado NFT como el precio mínimo, ventas, precio promedio, volumen y la capitalización bursátil.

Image description

Las Funcionalidades

  1. Los usuarios pueden colocar varias entradas como el Volumen, Precio Mínimo y Promedio, en la sección “Order By”.
  2. La aplicación va a interactuar con el API NFT GraphQL de QuickNode para retirar los datos del mercado NFT.
  3. La aplicación mostrará los datos en la vista de un tablero.
  4. Los usuarios pueden filtrar más aún el output, seleccionando el orden descendiente o ascendiente en la sección “Order Direction”.
  5. Los usuarios también pueden seleccionar el período de tiempo como la última hora, 12 horas o un día, para los datos.

El Paquete Tech

¡Comienza gratuitamente en QuickNode!

Los prerrequisitos

Paso 01: Crea un Proyecto Next.js

Configuraremos nuestro entorno e instalaremos las dependencias necesarias. Abre un terminal en tu máquina y navega a la locación del directorio donde te gustaría almacenar tu proyecto Next.js. Luego, ejecuta el siguiente comando:

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

Este comando crea un nuevo proyecto Next.js en el directorio especificado. Ahora, comienza el servidor de desarrollo local, ejecutando el siguiente comando:

yarn dev
Enter fullscreen mode Exit fullscreen mode

El comando de arriba configura tu entorno de desarrollo local. Copia y pega http://localhost:3000 en tu navegador web para lanzar el siguiente proyecto Next.js. Aquí está cómo tu navegador web debería verse:

Image description

La aplicación actual contiene el código inicial proporcionado por Next.js, el cual modificaremos a través de este tutorial para crear un frontend UI personalizado para nuestro tablero de mercado NFT.

Ahora, vamos a instalar Tailwind CSS y sus dependencias necesarias usando npm, ejecutando el siguiente comando en el terminal:

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

Ejecuta el comando init para generar ambos tailwind.config.js y los archivos postcss.config.js:

npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

En tu archivo tailwind.config.js, añade las rutas a todos los archivos plantilla, actualizando el código con lo siguiente:

Archivo ./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

Ahora añade las directivas @tailwind para cada una de las capas de Tailwind a tu archivo globals.css. La parte superior de tu archivo global.css debería verse así:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Paso 02: Instalar la Biblioteca icy-nft-hooks

Para crear el tablero de mercado NFT, necesitamos datos en tiempo real y buscaremos estos datos usando la API NFT GraphQL. Instalaremos y configuraremos icy-nft-hooks una biblioteca hook React que actúa como un envoltorio para las API GraphQL icy.tools. Esta biblioteca nos permite buscar datos del mercado NFT en tiempo real como el precio mínimo, ventas, precio promedio, volumen, capitalización bursátil, etc.

Instala icy-nft-hooks con el siguiente comando:

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

En el directorio pages, navega el archivo _app.js. Copia y pega el siguiente código en el archivo _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 el hook IceProvider desde el paquete icy-nft-hooks y envolver toda la aplicación web con el hook iceProvider.

Step 03: Obtener la Clave API NFT

Cómo puedes ver el código de arriba, necesitaremos una clave API para buscar los datos del mercado NFT en tiempo real. Para obtener la clave API, sigue estos pasos:

Abre el enlace Icy tools y haz click en el botón “Sign Up”

Image description

Coloca los detalles y haz click en el botón “Sign Up”:

Image description

Irás a la página “Explore” de icy.tools, donde verás algo así:

Image description

Haz click en el botón “Settings” en el lado izquierdo. Verás la clave API:

Image description

Paso 04: Instalar el Paquete dotenv

Recomiendo almacenar información sensible como las claves API, en el entorno de las variables en vez de hardcodearlas en el código. Usaremos el paquete dotenv para almacenar información sensible. Ejecuta el siguiente comando para instalar el paquete dotenv:

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

Crea un archivo .env en el directorio raíz. Añade la variable de entorno:

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

Paso 05: Buscando los Datos del Mercado NFT

En esta sección, crearemos la función Collections que acepta varias entradas desde el usuario como “Time Period” (1 hora, 12 horas, un día, siete días), “Order By” (Ventas, Promedio, Volumen) y “Order Direction” (Descendiente, Ascendiente).

icy-nft-hooks nos proporciona con la useTrendingCollections y los métodos TrendingCollectionsTimePeriod que implementaremos y utilizaremos dentro de nuestra función Collections.

Crea un nuevo archivo dentro del directorio pages y nómbralo Collections.js. Por favor copia y pega el siguiente código dentro de él:

Archivo: ./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

Si estás curioso sobre por qué usamos valores como ONE_HOUR, TWELVE_HOUR, SALES, DESC, AVERAGE, etc. Presiona ctrl + click izquierdo en TrendingCollectionsPeriod.

Paso 06: Añadiendo Estilo y Diseño

Crea un nuevo directorio llamado components en la raíz y, dentro, crea un nuevo archivo llamado Layout.js. Añade el siguiente código dentro de él:

File: ./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

Importa el Layout.js dentro del archivo _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

Ahora, navega al archivo index.js y haz los siguientes cambios:

File: ./pages/index.js

import Head from "next/head";
import Collections from "./Collections";

export default function Home() {
  return (
    <>
      <Head>
        <title> QuickNode Graph NFT API </title>
        <meta name="description" content="Generated by create next 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

Ahora, abre http://localhost:3000 en tu navegador. Haz creado un tablero de mercado NFT interactivo.

Base de Código Completo

Aquí está el repositorio GitHub del proyecto entero: Tablero del Mercado NFT

Image description

Recursos Adicionales

https://github.com/AAYUSH-GUPTA-coder/quicknode-graphql-nft-api-tutorial

https://docs.icy.tools/developer-api/api-reference

https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md

Este artículo es una traducción de Aayush Gupta, hecha por Gabriella Martínez. Puedes encontrar el artículo original aquí
Sería genial escucharte en nuestro Discord, puedes contarnos tus ideas, comentarios, sugerencias y dejarnos saber lo que necesitas.
Si prefieres puedes escribirnos a @web3dev_es en Twitter.

Discussion (0)