NOVO: Helius adquire a Light Protocol
Como criar um visualizador de portfólio da Solana com Next.js e a DAS API da Helius
Blog/Desenvolvimento

Como criar um visualizador de portfólio da Solana com Next.js e a DAS API da Helius

Engenheiro de Experiência do DesenvolvedorOwen Venter no XOwen Venter no LinkedIn
6 min de leitura

Objetivos

Neste tutorial, criaremos uma aplicação front-end para exibir o conteúdo de uma carteira Solana usando a DAS API da Helius. Mostraremos diferentes tipos de token e suas informações detalhadas, incluindo metadados, dados de coleções e preços de tokens fungíveis.

Este tutorial mostrará como criar algo semelhante à Galleria, detalhando as etapas necessárias.

Pré-requisitos

  • Chave de API da Helius.
  • Familiaridade com React.
  • Experiência com Next.js.

Visão geral das tecnologias utilizadas

  • Next.js: um framework React para criar aplicações renderizadas no servidor.
  • DAS API da Helius: uma API abrangente para acessar dados de tokens da Solana.
  • Vercel: uma plataforma para hospedar aplicações Next.js.
  • Tailwind CSS: um framework CSS utility-first para estilização.

Configurando o projeto

A DAS API

A DAS API é uma especificação e um sistema de código aberto oferecidos pela Helius. A API fornece uma interface simples para interagir com ativos digitais na blockchain Solana. Ela oferece suporte a vários tipos de token, incluindo tokens fungíveis, NFTs tradicionais e NFTs compactados, além de recursos como indexação de metadados off-chain.

Configuração da chave de API

Para obter uma chave de API da Helius, acesse o Portal do Desenvolvedor da Helius. Veja como começar:

  1. Crie uma conta usando uma carteira Solana ou uma conta do Google ou GitHub.
  2. Após entrar, você verá uma solicitação para criar uma chave de API.
  3. Armazene essa chave com segurança, pois ela será usada para fazer nossas chamadas de API.

Criando a aplicação Next.js

Etapa 1: configurar seu projeto Next.js

Crie uma nova aplicação Next.js com Tailwind

Código
npx create-next-app@latest helius-portfolio --typescript --eslint

Use as seguintes configurações:

Isso permitirá usar o Tailwind CSS para estilização, além do novo App Router.

Código
cd helius-portfolio

‍Etapa 2: criar componentes

Crie uma pasta components no diretório app para manter uma estrutura organizada.

Componente SearchBar (components/SearchBar.js):

Esse componente processa os dados inseridos pelo usuário para endereços de carteira. Ele utiliza o hook useState para gerenciar o estado do endereço e useRouter para navegar após o envio do formulário. O formulário é estilizado com classes do Tailwind CSS para oferecer uma aparência elegante.

Componente TokenCard (components/TokenCard.js):

Esse componente foi desenvolvido para exibir informações de tokens. Ele renderiza condicionalmente diferentes layouts para tokens fungíveis e não fungíveis e utiliza os tipos Token e Attribute de ../types/Token.

Componente SearchBar:

components/searchBar.ts

Código
import { useRouter } from "next/navigation";
import React, { useState } from "react";

export default function SearchBar() {
  const router = useRouter();
  const [address, setAddress] = useState("");

  function handleSubmit(event: React.FormEvent) {
    event.preventDefault();
    router.push(`/${address}`);
  }

  return (
    
       setAddress(e.target.value)}
        className="border-2 border-gray-300 rounded-md w-full text-center px-4 py-2 mb-4 flex-grow text-black"
      />
      
        Search
      
    
  );
}

Componente TokenCard:

Esse componente analisa os dados de tokens recebidos da API e mostra as informações relevantes em cada cartão de token.

No exemplo abaixo, mostramos algumas informações básicas, como imagem, símbolo, quantidade e valor de cada token fungível. Para tokens não fungíveis, mostramos a imagem, o nome, a descrição e os atributos. Você pode extrair qualquer informação fornecida pela API e exibi-la no cartão.

Um exemplo seria mostrar informações específicas de compactação para cNFTs ou informações de inscrição para ativos inscritos. Para saber mais sobre as informações específicas com as quais você pode trabalhar, consulte a documentação da DAS.

Código
"use client";

import React from "react";
import { Token, Attribute } from "../types/Token";

interface TokenCardProps {
  token: Token;
  tokenType: string;
}

const TokenCard = ({ token, tokenType }: TokenCardProps) => {
  return (
    
      {/* Other token information */}
      {tokenType === "fungible" ? (
        
          
          
            
              {token.content.metadata.symbol}
            
            {/* {token.content.metadata.description} */}
            Amount:{token.token_info.balance}
            {token.token_info.price_info?.total_price ? (
              Value: ${token.token_info.price_info.total_price}
            ) : null}
          
        
      ) : (
        
          
          
            
              {token.content.metadata.name}
            
            {token.content.metadata.description}
            
              {token.content.metadata?.attributes?.map(
                (attribute: Attribute, index: number) => (
                  
                    {attribute.trait_type}: {attribute.value}
                  
                )
              )}
            
          
        
      )}
    
  );
}

export default TokenCard;

Etapa 3: buscar dados da DAS

Usaremos o método searchAssets da DAS API para buscar dados de tokens. Esse método é flexível e permite especificar critérios como endereços de carteira e tipos de token.

Criando uma pasta lib:

  1. Crie uma pasta lib no diretório app para a chamada de API.
  2. Dentro dela, crie um arquivo searchAssets.ts.

Função de chamada da API (lib/searchAssets.ts):

  • Essa função busca tokens com base no endereço da carteira.
  • Ela processa possíveis erros e registra respostas para depuração
Código
interface Tokens {
  items: any[];
}

const fetchTokens = async (walletAddress: string): Promise => {
  const url = `https://mainnet.helius-rpc.com/?api-key=`;
  console.log(
    `Starting search for tokens for wallet address: ${walletAddress}`
  );
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: "my-id",
        method: "searchAssets",
        params: {
          ownerAddress: walletAddress,
          tokenType: "all",
          displayOptions: {
            showCollectionMetadata: true,
          },
        },
      }),
    });
    const data = await response.json();
    console.log(
      `Data returned for wallet address ${walletAddress}:`,
      data.result
    );
    return { items: data.result };
  } catch (error) {
    console.error("Error fetching tokens:", error);
    return { items: [] };
  }
};

export default fetchTokens;

Configure o tipo de token

  • Precisaremos configurar um tipo para a resposta da DAS API. Essa é uma boa prática ao trabalhar com Typescript. Você pode criar uma pasta chamada types e um arquivo chamado token.ts
Código
export interface ApiResponse {
  total: number;
  limit: number;
  cursor?: string;
  items: Token[];
}

export interface Token {
  interface: string;
  id: string;
  content: Content;
  authorities: Authority[];
  compression: Compression;
  grouping: Grouping[]; // or any[]
  royalty: Royalty;
  creators: Creator[]; // or any[]
  ownership: Ownership;
  supply: Supply | null | number;
  mutable: boolean;
  burnt: boolean;
  token_info: TokenInfo;
  mint_extensions: MintExtensions;
  inscription: Inscription;
  spl20?: Spl20;
}

export interface Content {
  $schema: string;
  json_uri: string;
  files: any[];
  metadata: Record;
  links: Record;
}

export interface Authority {
  address: string;
  scopes: string[];
}

export interface Compression {
  eligible: boolean;
  compressed: boolean;
  data_hash: string;
  creator_hash: string;
  asset_hash: string;
  tree: string;
  seq: number;
  leaf_id: number;
}

export interface Grouping {
  group_key: string;
  group_value: string;
  collection_metadata: CollectionMetadata;
}

export interface Royalty {
  royalty_model: string;
  target: string | null;
  percent: number;
  basis_points: number;
  primary_sale_happened: boolean;
  locked: boolean;
}

export interface Creator {
  address: string;
  share: number;
  verified: boolean;
}

export interface Ownership {
  frozen: boolean;
  delegated: boolean;
  delegate: null | string;
  ownership_model: string;
  owner: string;
}

export interface Supply {
  print_max_supply: number;
  print_current_supply: number;
  edition_nonce: number;
}

export interface TokenInfo {
  symbol: string;
  balance: number;
  supply: number;
  decimals: number;
  token_program: string;
  associated_token_address: string;
  price_info: PriceInfo;
}

export interface Inscription {
  order: number;
  size: number;
  contentType: string;
  encoding: string;
  validationHash: string;
  inscriptionDataAccount: string;
}

export interface Spl20 {
  p: string;
  op: string;
  tick: string;
  amt: string;
}

export interface File {
  uri: string;
  cdn_uri: string;
  mime: string;
}

export interface Metadata {
  attributes: Attribute[];
  description: string;
  name: string;
  symbol: string;
}

export interface Attribute {
  value: string;
  trait_type: string;
}

export interface CollectionMetadata {
  name: string;
  symbol: string;
  image: string;
  description: string;
  external_url: string;
}

export interface PriceInfo {
  price_per_token: number;
  total_price: number;
  currency: string;
}

export interface MintExtensions {}

Etapa 4: exibir informações dos tokens

Categorizaremos a resposta da API em tokens fungíveis e não fungíveis. Esses tokens serão exibidos usando o componente Token Card. Um botão de alternância permite que os usuários troquem entre os dois tipos de token.

Integrando os componentes à página de busca

  • Página de busca (pages/index.ts)
  • A página inicial apresenta uma barra de busca na qual os usuários podem inserir endereços de carteira.
  • Ela é estilizada com Tailwind CSS para oferecer um design limpo e responsivo.
Código
"use client";

import React from "react";
import SearchBar from "./components/searchBar";

export default function Home() {
  return (
    
      
        
          Solana Portfolio Viewer
        
        
          {"Built with Helius's DAS API"}
        
        
          
        
      
    
  );
}

Configurando a página de tokens

Usaremos rotas dinâmicas do Next.js para endereços de carteira individuais. Isso melhora a experiência do usuário, facilitando a navegação e o compartilhamento de URLs.

Configure um diretório chamado [wallet]. Os colchetes habilitam o roteamento dinâmico. Depois disso, crie um arquivo chamado page.tsx, que conterá toda a lógica de negócios de todas as páginas carregadas dinamicamente.

Configuração da página de tokens (pages/[wallet]/page.tsx):

Essa página exibe os tokens associados ao endereço da carteira presente na URL. Ela faz uma chamada de API para buscar os dados dos tokens e os exibe usando o componente Token Card.

Código
"use client";

import React, { useState, useEffect } from "react";
import fetchTokens from "../lib/searchAssets";
import TokenCard from "../components/tokenCard";
import { Token, Attribute } from "../types/Token";

interface Tokens {
  items: Token[];
}

interface PageProps {
  params: {
    wallet: string;
  };
}

export default function Page({ params }: PageProps) {
  const [tokens, setTokens] = useState(null);
  const [tokenType, setTokenType] = useState("fungible");

  useEffect(() => {
    fetchTokens(params.wallet).then(setTokens).catch(console.error);
  }, [params.wallet]);

  console.log("tokens", tokens);

  const fungibleTokens = tokens
    ? tokens.items.filter(
        (token) =>
          token.interface === "FungibleToken" ||
          token.interface === "FungibleAsset"
      )
    : [];

  const nonFungibleTokens = tokens
    ? tokens.items.filter(
        (token) =>
          token.interface !== "FungibleToken" &&
          token.interface !== "FungibleAsset"
      )
    : [];

  const displayedTokens =
    tokenType === "fungible" ? fungibleTokens : nonFungibleTokens;

  return (
    
      
        Portfolio Viewer
      
      {params.wallet}
      
         setTokenType("fungible")}
        >
          Fungible Tokens
        
         setTokenType("nonFungible")}
        >
          Non-Fungible Tokens
        
      
      {displayedTokens.length > 0 ? (
        
          {displayedTokens.map((token) => (
            
          ))}
        
      ) : (
        Loading...
      )}
    
  );
}

Depois de configurar tudo isso, o diretório do seu projeto deverá ter esta aparência:

Etapa 5: estilizar a aplicação

O Tailwind CSS será nosso framework de estilização. Sua abordagem utility-first permite estilizar componentes rapidamente, mantendo um design consistente e responsivo. Você pode usar o Tailwind para personalizar sua aplicação como quiser.

Etapa 6: testar a aplicação

Execute sua aplicação Next.js para testá-la localmente:

Código
npm run dev

Faça testes inserindo diferentes endereços de carteira e verifique se os dados corretos são exibidos.

Implantação

Implantaremos nossa aplicação usando a Vercel. A Vercel oferece hospedagem gratuita, além de análises e insights valiosos, o que a torna uma opção ideal para hospedar aplicações Next.js. Você pode fazer a configuração em https://vercel.com/.

Conclusão

Parabéns por concluir este tutorial! Esperamos que ele tenha sido útil.

A DAS API é uma ferramenta muito rápida e poderosa que permite recuperar dados de tokens da blockchain.

Este visualizador de portfólio é um excelente exemplo do que a API pode fazer.

Esperamos que você possa usar o site básico criado aqui e transformá-lo em algo incrível. Se tiver alguma dúvida, entre no nosso Discord e fale diretamente conosco!

Você encontra o código completo aqui: https://github.com/helius-labs/galleria

Outros recursos de aprendizagem

Para aprofundar seu conhecimento sobre Next.js, a blockchain Solana e a integração de APIs, confira estes recursos:

Este guia oferece uma base sólida para criar aplicações baseadas em blockchain com Next.js e interagir com a blockchain Solana usando a DAS API.

‍

Assine a Helius

Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos

Imagem ampliada