WEB3DEV

Cover image for Como obter saldos de token em Solana?
Adriano P. Araujo
Adriano P. Araujo

Posted on

Como obter saldos de token em Solana?

Neste tutorial, veremos como podemos usar APIs SHYFT para listar todos os tokens fungíveis de uma carteira Solana e também obter os detalhes de um token específico.

Neste tutorial, criaremos um aplicativo simples, que listará todos os tokens fungíveis da sua carteira usando nossas próprias APIs SHYFT. Uma vez feito, você poderá mostrar uma lista de tokens fungíveis da sua carteira.

Você pode ler a documentação SHYFT aqui.

Pré-requisitos

Para começar, precisaremos de algumas coisas.

Autenticação: obtendo sua chave de API Shyft

x-api-key é um parâmetro de autenticação que fornece acesso às APIs SHYFT. Você pode obter sua própria chave de API na Site SHYFT. Basta se inscrever com seu ID de email aqui e você poderá obtê-lo gratuitamente.

Carteira Phantom

Precisamos da extensão da carteira Phantom no navegador, você pode baixá-lo no link abaixo.

Uma vez feito, configure sua conta Phantom. Estão disponíveis dicas na tela que o guiarão nessa configuração inicial. Você também pode encontrar um guia detalhado relacionado a isto aqui.

Vamos usar React para desenvolver este projeto, mas você pode escolher qualquer idioma de sua escolha. Como nós estamos usando o react, precisaremos do Node.js instalado em nosso computador. Você pode baixar o node.js aqui.

Configuração inicial

Agora, estamos prontos para criar nosso primeiro aplicativo de lista de tokens. Vamos criar um novo aplicativo React para criar nosso aplicativo. Para criar um aplicativo react, acione seu terminal e use o seguinte comando.

npx create-react-app list-all-tokens-from-wallet

Isso criará um template para o seu novo projeto react. Usaremos o vscode como nosso editor de código para este projeto, mas você pode usar qualquer editor de código de sua escolha. Depois que o comando acima concluir sua execução, abriremos a pasta do projeto usando o vscode e ela ficará assim.

Depois de abrir a pasta do projeto com vscode

Construindo o aplicativo

Dividimos o projeto em duas partes.

  1. Criaremos um módulo para buscar e exibir uma lista de todos os tokens na sua carteira.

  2. Criaremos um módulo para buscar e exibir todos os detalhes relacionados a um token específico.

Então, vamos começar a construir.

Exibindo uma lista de todos os tokens na sua carteira

Conectando-se a uma carteira Phantom

Este é o primeiro passo necessário para esta parte. Usaremos o endereço da sua carteira Phantom e o usaremos para buscar todos os tokens atuais na sua carteira e depois os exibiremos.

Para se conectar à sua carteira Phantom, precisamos de algumas dependências adicionadas ao nosso projeto. Para adicionar essas dependências, teremos que instalar os pacotes manualmente em nossa pasta do projeto ou podemos adicioná-lo à lista de dependências dentro do arquivo package.json  e executar o comando npm install para adicioná-los automaticamente ao nosso projeto.

Dentro do arquivo package.json, na seção de dependência, adicionamos o seguinte, salvamos e damos um npm ci


"dependencies": {

   ...

   "[@solana/wallet-adapter-phantom](http://twitter.com/solana/wallet-adapter-phantom)": "0.9.7",

   "[@solana/web3](http://twitter.com/solana/web3).js": "^1.50.0",

   "axios": "^0.27.2",   

   ...

 },

Enter fullscreen mode Exit fullscreen mode

Os dois primeiros pacotes mencionados nesta lista são usados para conectar-se à carteira Phantom e usaremos o pacote axios  para fazer solicitações http à nossa APIs SHYFT.

Nota: Sempre que adicionamos um pacote ou uma dependência ao nosso projeto, precisamos reiniciar o servidor local.

Uma vez feito, vamos executar o seguinte comando

npm run start

Isso iniciará um servidor de desenvolvimento local e seu aplicativo estará em funcionamento no seguinte link: http://localhost:3000

Agora, vamos criar um novo arquivo sob o diretório /src, nós vamos nomeá-lo como ListAll.js mas você pode o nomear como quiser.

Agora, vamos criar um botão simples que irá conectar o adaptador da carteira Phantom e recuperar nosso endereço de carteira.

( Usamos bootstrap para adicionar um estilo muito mínimo ao nosso projeto, mas isso não é necessário, você pode escrever suas próprias folhas de estilo ou usar outros métodos para modelar seu aplicativo )

Um botão simples para conectar-se à Carteira Phantom

Uma vez essa parte estando criada, precisamos criar uma função que se conecte à carteira Phantom quando esta for invocada. Para isso, temos que importar algumas coisas em nosso arquivo ListAll.js.


import { clusterApiUrl, Connection, PublicKey } from "[@solana/web3](http://twitter.com/solana/web3).js";

import { PhantomWalletAdapter } from '[@solana/wallet-adapter-phantom](http://twitter.com/solana/wallet-adapter-phantom)';

Enter fullscreen mode Exit fullscreen mode

e a função de conexão ao Phantom


const solanaConnect = async () => {

   const { solana } = window;

   if (!solana) {

     alert("Please Install Solana");

   }

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.toString(),

     };

if (wallet.address) {

       console.log(wallet.address);

       /obteremos o endereço da carteira aqui, podemos atribuí-lo a uma variável de estado

       const accountInfo = await connection.getAccountInfo(new PublicKey(wallet.address), "confirmed");

       console.log(accountInfo);

     }

   }

   catch (err) {

     console.log(err);

   }

}

Enter fullscreen mode Exit fullscreen mode

e invocaremos essa função assim que clicarmos no botão Connect Wallet como mostrado acima na imagem anterior.

Se executado com sucesso, receberemos o endereço da carteira Phantom. Vamos criar duas variáveis, uma para armazenar o endereço da carteira e outra para armazenar os dados que receberemos das nossas API’s.


const [walletAddress,setwalletAddress] = useState(null);

const [data,setData] = useState(null);

Enter fullscreen mode Exit fullscreen mode

Depois de receber o endereço da carteira, vamos atribuí-lo a variável de estado  walletaddress, criada usando o hook  useState do React

Fazendo a chamada da API

A URL da API que usaremos para recuperar os dados do token:

https://api.shyft.to/sol/v1/wallet/all_tokens?network=CURRENT_NETWORK&wallet=WALLET_ADDRESS

Também precisaremos passar X-API-KEY no cabeçalho, essa chave é usada para fins de autenticação.

Você pode encontrar mais sobre nossas API’s aqui.

Obtendo seu próprio X-API-KEY

x-api-key é um parâmetro importante que passamos para o cabeçalho enquanto fazemos a chamada da API para fins de autenticação. Você pode obter o seu próprio x-api-key no nosso Site SHYFT. Basta se inscrever com seu ID de email aqui e você pode obtê-lo gratuitamente.

Agora, quando tivermos o endereço da carteira, estamos prontos para fazer a chamada da API para buscar nossos dados necessários, que nesse caso são a lista de tokens.

Para buscar os dados, usamos o axios pacote, mas você pode usar a o fetch nativo do JavaScript ou qualquer outro pacote que desejar. Fizemos essa chamada dentro do hook  useEffect React. Aqui está o código.


const xAPIKey = "YOUR_API_KEY"; //your api key goes here

useEffect(() => {

   let reqUrl = `https://api.shyft.to/sol/v1/wallet/all_tokens?network=${netWrk}&wallet=${walletAddress}`;

axios({

        // Endpoint para executar a solicitação

        url: reqUrl,

        method: "GET",

        headers: {

        "Content-Type": "application/json",

        "x-api-key": xAPIKey,

        },

    })

        // Lida com a resposta do back-end aqui

        .then((res) => {

            console.log(res.data);

            setData(res.data.result); //storing the token array in data

        })

        // Captura os erros se houverem

        .catch((err) => {

            console.warn(err);

        });

    },[walletAddress,netWrk]);

Enter fullscreen mode Exit fullscreen mode

Se for bem-sucedida, a resposta que recebemos do servidor se parece um pouco com esse result contendo uma matriz de todos os tokens. Armazenamos a matriz de tokens na variável de estado dos dados.


{

    "success": true,

    "message": "2 tokens fetched successfully",

    "result": [

        {

            "address": "G6qTix6iGbnMYpRTsKaeDiTDHAW5E6WBdoRdTYkYKeuy",

            "balance": 20

        },

        {

            "address": "CjLYfcwZT8pfsLMKn21uzUefwsyCDppeLPJvm5HJtsGv",

            "balance": 50

        }

    ]

}

Enter fullscreen mode Exit fullscreen mode

Agora, vamos exibir essa matriz de tokens em nosso aplicativo. Usamos o método de map do JavaScript para exibir a matriz dentro de uma tabela.


data.map ( ( tokn ) = > (

   < tr key = { tokn.address } >

       < td className = "w-25 border-2" >

           < img src = { tokn.info.image } className = "img-fluido w-75 mx-auto" alt = "" / >

       < / td >

       < td className = "w-50 border-2" >

           < h4 > { tokn.info.name } < / h4 >

             { tokn.address }

        < / td >

        < td className = "w-25 border-2" > { tokn.balance } { tokn.info.symbol } < / td >

   < / tr >

) )

Enter fullscreen mode Exit fullscreen mode

Lista de tokens presentes na sua carteira e seus detalhes

Parabéns, você acabou de atingir nosso primeiro objetivo, buscando todos os tokens da sua carteira usando APIs SHYFT. Agora passamos para a próxima parte do nosso projeto, que é obter os detalhes de um token específico.

Obtenha os detalhes de um token específico

Agora, tentaremos buscar os detalhes de um token específico usando nossas próprias APIs SHYFT. Projetaremos este projeto como uma extensão da parte anterior do projeto usando React, mas você também pode projetá-lo como um projeto separado.

Tentaremos vincular os tokens na parte anterior a uma nova página que exibirá todos os detalhes desse token específico.

Para conseguir isso, precisamos configurar algumas rotas, a home(/ ) A rota exibirá os detalhes de todos os tokens e os detalhes da visualização (/view-details), essa rota exibirá os detalhes de um token específico.

Para configurar as rotas, usaremos o pacote react-router-dom . Para instalar este pacote, executamos o seguinte comando em nosso terminal dentro da pasta do projeto.

npm install react-router-dom

Depois de instalado, precisamos reiniciar nosso servidor local. Agora, é hora de configurar nossas rotas. Vamos criar um novo componente, vamos chamá-lo de componente Details , mas você pode nomear como quiser. Vamos colocar isso dentro, do diretório \src. Isso parecerá um pouco com isso

O novo componente Detalhes em src / Details.js

Configurando rotas

Agora, dentro do nosso componente App(App.js), montamos as rotas. Para configurar as rotas, precisamos do seguinte:

import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

Configuraremos duas rotas, uma para listar todos os tokens e outra para exibir os detalhes de um token específico.


import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

import ListAll from "./ListAll";

import Details from "./Details";

function App() {

  return (

    <div className="App">

      <Router>

          <Routes>

              <Route exact path="/" element={<ListAll />} />

              <Route exact path="/view-details" element={<Details />} />        

          </Routes>

      </Router>

    </div>

  );

}

export default App;

Enter fullscreen mode Exit fullscreen mode

Depois da configuração, poderemos acessar a rota /view-details dentro da nossa aplicação.

Vinculando via parâmetros de URL

Podemos vincular cada um dos tokens listados no componente ListAll para redirecionar para a rota /view-details  junto com token_address e network como parâmetros da rota. Isso nos ajudará a obter os detalhes de um token específico, atualizando a URL token_address  mesmo que nossa carteira não esteja conectada. Uma das maneiras pelas quais podemos conseguir isso é a seguinte:


data.map((tokn) => (

    <tr key={tokn.address}>

        <td className="w-25 border-2">

            <img src={tokn.info.image} className="img-fluid w-75 mx-auto" alt="" />

        </td>

        <td className="w-50 border-2">

            <Link

                to={`/view-details?token_address=${tokn.address}&network=${netWrk}`}

                  target="_blank"

                ><h4>{tokn.info.name}</h4>

              {tokn.address}

            </Link>

          </td>

          <td className="w-25 border-2">{tokn.balance} {tokn.info.symbol}</td>

    </tr>

))

Enter fullscreen mode Exit fullscreen mode

O componente <Link></Link> do pacote react-router-dom nos ajudará a navegar para o caminho desejado.

Construindo o componente de detalhes

Agora, vamos criar um layout para o nosso componente Details. Dentro do arquivo Details.js ( Details Component ), criaremos algumas variáveis de estado usando o hook useState do React para armazenar os dados e um layout simples para exibir os dados. Dentro do Componente Details, usamos o seguinte:


import { useState } from "react";

const Details = () => {

    const [image,setimage] = useState('');

    const [name,setName] = useState(null);

    const [desc,setDesc] = useState(null);

    const [sym,setSym] = useState(null);

    const [tokAddr,setTokAddr] = useState(null);

    const [mint,setmint] = useState(null);

    const [freeze,setFreeze] = useState(null);

    const [deci,setDeci] = useState(null);

    const [curSup,setCurSup] = useState(null);

    return ( 

        <div>

           <div className="container">

                <div className="card border-primary py-3 px-1 mt-5 w-75 mx-auto">

                    <div className="image-container w-25 mx-auto mt-3">

                        <img src={image} alt="" className="img-fluid" />

                    </div>

                    <div className="mt-3">

                        <table className="table">

                            <tbody>

                                <tr>

                                    <td className="w-50">Name</td>

                                    <td>{name}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Description</td>

                                    <td>{desc}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Symbol</td>

                                    <td>{sym}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Token Address</td>

                                    <td>{tokAddr}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Mint Authority</td>

                                    <td>{mint}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Freeze Authority</td>

                                    <td>{freeze}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Decimals</td>

                                    <td>{deci}</td>

                                </tr>

                                <tr>

                                    <td className="w-50">Current Supply</td>

                                    <td>{curSup}</td>

                                </tr>

                            </tbody>

                        </table>

                    </div>

                </div>

           </div> 

        </div>

     );

}

export default Details;

Enter fullscreen mode Exit fullscreen mode

Obtendo os detalhes de um token específico

Agora os parâmetros token_address  e network devem estar disponíveis no componente Details, como passamos por parâmetros de rota. Essa é uma maneira de passar o endereço do token. mas você pode ter seu próprio método, se quiser. Se esse fosse um aplicativo separado, poderíamos ter usado um formulário para coletar o endereço do token e os outros parâmetros necessários. Agora, vamos ver como podemos obter os detalhes de um token específico.

API SHYFT para buscar os detalhes de um token específico

https://api.shyft.to/sol/v1/token/get_info?network=CURRENT_NETWORK&token_address=TOKEN_ADDRESS

Antes de fazer essa chamada, precisamos ter nossa X-API-KEY. x-api-key é um parâmetro importante que passamos para o cabeçalho para fins de autenticação. Você pode obter o seu próprio x-api-key do nosso Site SHYFT. Basta se inscrever com seu ID de email aqui e você pode obtê-lo gratuitamente.

Depois que tivermos o nosso X-API-KEY, estamos prontos. Usaremos o pacote Axios para fazer a chamada da API, mas você pode usar qualquer outro pacote ou o próprio fetch nativo do Javascript para fazer essa chamada.

const xAPIKey = 'YOUR_X_API_KEY'; //enter your X-API-KEY here 

const ApiParams = window.location.search.substring(1); //fetching the url params

useEffect(() => {


     let reqUrl = `https://api.shyft.to/sol/v1/token/get_info?${ApiParams}`;

        axios({

            // Endpoint para executar a solicitação

            url: reqUrl,

            method: "GET",

            headers: {

                "Content-Type": "application/json",

                "x-api-key": xAPIKey,

            },

          })

            // Lida com a resposta do back-end aqui

            .then((res) => {

              console.log(res.data); //we get the response here

            })

            //  Captura os erros se houverem

            .catch((err) => {

              console.warn(err);

            });

    },[ApiParams]);

Enter fullscreen mode Exit fullscreen mode

Uma vez bem-sucedido, ele deve retornar uma resposta que conterá todas as informações relacionadas ao token. Aqui está uma resposta de amostra:


{

    "success": true,

    "message": "Tokens info",

    "result": {

        "name": "Mad Bug",

        "symbol": "MFB",

        "description": "Hair on fire problem solving",

        "image": "https://nftstorage.link/ipfs/bafybeib33qdmutebxe5ssucpkngmpemkyfedkp7533pquv7l2yegqrotb4",

        "address": "b656nATaqUKaQTC6m5to758ySR86eRbPcvN85RpmRHf",

        "mint_authority": "Gpxrb2UMTKwmBMrXtc5asyk7ga2TaSwfyjtw7Xsw8HFp",

        "freeze_authority": "Gpxrb2UMTKwmad2BMrXt2Mc5yk7ga2TaSwtw7Xsw8HFp",

        "current_supply": 1,

        "decimals": 0

    }

}

Enter fullscreen mode Exit fullscreen mode

Agora, para a etapa final, atribuiremos os dados recebidos na resposta às variáveis de estado, para exibir os detalhes no componente. Aqui está a parte do trecho que usaremos para atualizar os detalhes.


.then((res) => {

  console.log(res.data);

  if(res.data.success === true)

  {

    setName(res.data.result.name);

    setDesc(res.data.result.description);

    setimage(res.data.result.image);

    setSym(res.data.result.symbol);

    setTokAddr(res.data.result.address);

    setmint(res.data.result.mint_authority);

    setFreeze(res.data.result.freeze_authority);

    setDeci(res.data.result.decimals);

    setCurSup(res.data.result.current_supply);

  }

  else

  {

    setName('Failed to Load Data');

  }

})

Enter fullscreen mode Exit fullscreen mode

E isso é tudo o que você precisa fazer para obter os detalhes do token.

Parabéns, você acabou de criar um DAPP no qual pode obter todos os tokens de sua carteira assim como seus respectivos detalhes .

Aqui está um print do nosso projeto de amostra que criamos para a nossa comunidade.

Isso é lindo demais para este tutorial, se você gostou, tente também nossos outros tutoriais em Building your First NFT Dapp e Read all NFTs from a wallet. Mais tutoriais estão chegando em breve.

Sinta-se livre para clonar nosso código e contribuir para a nossa comunidade.

Se você gostou, pode aprender mais sobre as APIs SHYFT em nossas Documentação.

Você pode visualizar uma versão mais refinada deste projeto aqui. Um exemplo de rápido do projeto da comunidade foi ilustrado acima.

Recursos

Espero que você se divirta lendo nossos tutoriais e feliz hack!!!😇


Este artigo foi escrito por Team Shyft  e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)