Shyft
Start BuildingSupportWebsite
  • Welcome
    • 👋Introducing Shyft
    • 🏗️Start Building
  • Solana Infrastructure
    • 🚁Shyft RPCs
  • Yellowstone gRPC Network
    • Decoding gRPC Latency
    • ⚡gRPC Docs
      • Introduction
      • Authentication
      • Subscribe Requests
      • FAQ
      • Getting Started
        • Initializing the Yellowstone Client
        • Making a gRPC connection
        • Adding a Reconnection Mechanism
        • 🔥Replaying Slots with Solana yellowstone gRPCs
        • Modifying your Subscribe Request
        • Closing a gRPC Connection
      • Subscribing to Transactions
        • All Transactions of an address
        • Subscribing to all transactions of a Liquidity Pool
        • Subscribing to all transactions of multiple addresses
        • Subscribing to all transactions of a Token
      • Subscribing to Accounts
        • Account Updates for a Program
        • Account Updates for an Address
        • Account updates using memcmp
      • Streaming Blocks & BlocksMeta
        • Streaming Block Updates
        • Subscribing to BlocksMeta
      • Modifying & Unsubscribing
  • Solana defi data
    • DeFI APIs
      • Get Pool By Address
      • Get Pools By Token Pair
      • Get All Pools for a Token
      • Get Liquidity Details of a Pool
  • Callbacks
    • ☎️What are Callbacks?
      • Transaction Callbacks
      • Account Callbacks
    • 📔Callback APIs
      • Response Structure
      • List Callbacks
      • Register callback
      • Remove callback
      • 🔥Pause a callback
      • 🔥Resume a callback
      • Update Callbacks
      • Add Addresses
      • Remove addresses
  • Solana Super Indexers
    • 🌩️GraphQL APIs
      • Getting Started
      • Building Queries
      • Paginating Response
      • Applying Filters
      • Ordering and Sorting Data
    • 📀Case Studies
      • Tensor
        • Get Active Listings of a Wallet
        • Get Active Bids of a Wallet
        • Get Active Listings of a Collection
        • Get all Bids of a Collection
        • Get all Pools of a Margin Account
        • Get all Pools by Owner
      • Raydium
        • Get Pool By Address
        • Get Pools By Token Address
        • Get Pools Created Between Time
        • Get Pool Burn Percentage
        • Get Liquidity Details of a Pool
        • Get Pool and OpenBook Market Info
        • Get Token Supply Percentage In Pool
      • Orca Whirlpool
        • Get Pool by Address
        • Get Pool by Token Address
        • Get Positions for a Pool
        • Get Positions for a Wallet
        • Get Liquidity Details of a Pool
      • Kamino
        • Get Borrow Details of a Wallet
        • Get Deposit Details of a Wallet
        • Get Reserve Details
      • Cross Marketplace Queries
        • Get active listings across marketplaces for a wallet
        • Get listings for a collection across marketplaces
        • Get floor price of a collection
      • Cross Defi Queries
        • Fetch Liquidity Pools for Token
      • Native Staking
        • Get Stakes for a Wallet
        • Get Stakes For Validator
      • Governance/Realms
        • Get DAO Token Owners
        • Get Proposals For Governing Mint
        • Get All Proposals For DAO
        • Get DAO Treasury Info
        • Get All Active Proposals For Wallet
      • Meteora
        • Get All LB Position Pairs
        • Get Position of a User Wallet
        • Get Pool by Token Addresses
        • Get All Deposits for a User
        • Get All Withdraws for a User
        • Get All Fees Claimed by a User
        • Get All User Positions and Deposits for a Pool
        • Get All User Positions and Withdrawals for a Pool
      • Fluxbeam
        • Get Pool by Address
        • Get Pool by Token Addresses
      • Drift
        • Get User account for Delegate
        • Get User accounts based on authority
        • Get User details based on Referrer
        • Get Borrow/Deposit Amount for an User
        • Get PrepPositions for an User Account
        • Getting OrderId and userOrderId
        • Get OpenOrders for a User Account
      • 🔥Pumpswap
        • 🔥Get Pool by Address
        • 🔥Get Pool by Creator Address
        • 🔥Get Pools by Token Addresses
      • Raydium Launchpad
        • Get Bonding Curve Details by Pool Address
        • Get All Pools for a Creator
        • Get Pools by Token Addresses
        • Get Migration details of a Pool
  • Solana APIs
    • API Reference
    • Transactions
      • Parsed Transaction Structure
      • Transaction APIs
        • History
        • Parse Signature
        • Parse Multiple Signatures
        • Send
        • Send Multiple
    • NFT
      • 🔥Create Gasless
      • Create
      • Read All
      • Burn
      • 🔥Burn Multiple NFTs V2
      • Update
      • 🔥Create NFT from Metadata
      • 🔥Read Wallet Nfts
      • 🔥Read Selected NFTs
      • 🔥Get NFT Owners
      • 🔥Update NFT Metadata Uri
      • 🔥Update V2
      • Search
      • Transfer
      • Transfer Multiple NFTs
      • Mint
      • Read
    • Wallet
      • Get Balance
      • Get Token Balance
      • Get All Tokens Balance
      • Get Portfolio
      • Resolve Address
      • Get All Domains
      • Get Stake Accounts
    • Fungible Tokens
      • Create
      • Mint
      • Burn
      • 🔥Update
      • Get Token Info
      • Transfer
      • Airdrop
Powered by GitBook
On this page
  • Pre-requisites
  • Initial Setup
  • Building the application
  • Displaying a list of all tokens in your wallet
  • Get the details of one particular token
  • Resources

Was this helpful?

  1. Dev Guides
  2. Solana
  3. Fungible Tokens

How to get token balances?

In this sample project tutorial, we will see how we can use SHYFT APIs to list all fungible tokens from our wallet and also get the details of one particular token

Last updated 2 years ago

Was this helpful?

In this tutorial, we will build a simple app, which will list all the fungible tokens in your wallet using our very own SHYFT APIs. Once done, you will be able to show a list of Fungible Tokens from your wallet.

You can read SHYFT Documentation

Pre-requisites

To get started, we will need a few things.

Authentication: Get your Shyft API key

x-api-key is an authentication parameter, which gives you access to SHYFT APIs. You can get your own API Key from the . Just signup with your email id and you can get it for free.

Phantom Wallet

We will need the Phantom wallet browser extension, you can download it from the link below.

  • .

  • .

Once done, set up your Phantom wallet account. On-screen tips are available, which will guide you through setting up and getting started. You can also find a detailed guide related to this .

We will use to develop this project but you can choose any language of your choice. As we are using react we will need Node.js installed on our computer. You can download node.js from .

Initial Setup

Now, we are all set to create our first token-listing app. Let's create a new React application for building our app. To create a react app, fire up your terminal and use the following command.

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

This will create a boilerplate template for you new react project. We have used vscode as our code editor for this project, but you can use any code editor of your choice. Once the above command has completed its execution, we will open up that project folder using vscode and it should look like this.

Building the application

We have divided the project into two parts.

So, let's start building.

Displaying a list of all tokens in your wallet

Connecting to Phantom wallet.

This is the first step to required for this part. We will use the Wallet Address from your Phantom Wallet and use it to fetch all tokens currently in your wallet and then we will display them.

To connect to your phantom wallet, we need a few dependencies added to our project. To add these dependencies, we will have to install the packages manually in our project folder or we can add this to the dependencies list inside the package.json file and run the npm install command to automatically add these to our project.

Inside the package.json file dependency section, we add the following and the save and hit npm ci

"dependencies": {
    ...
    "@solana/wallet-adapter-phantom": "0.9.7",
    "@solana/web3.js": "^1.50.0",
    "axios": "^0.27.2",    
    ...
  },

Note: Every time we add a package or a dependency to our project, we have to restart the local server.

Once done, let's run the following command

npm run start

Now, let's create a new file under the /src directory, we have used the name ListAll.js but you can name it anything you want.

Now, let's create a simple button which will connect to the phantom wallet adapter and retrieve our wallet address.

Once created, we have to create a function which will connect to the phantom wallet when invoked. For this we have to import a few things in our ListAll.js file.

import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { PhantomWalletAdapter } from '@solana/wallet-adapter-phantom';

and the function for connecting to 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); 
        //we will get the wallet address here, we can assign it to a state variable
        const accountInfo = await connection.getAccountInfo(new PublicKey(wallet.address), "confirmed");
        console.log(accountInfo);
        
      }
    }
    catch (err) {
      console.log(err);
    }

  }

and we will invoke this function once we have clicked on the Connect Wallet button as shown above in the image before.

If executed successfully, we will receive the wallet address from phantom. Let's create two variables, one for strong the wallet address and one for storing the data we will receive from our APIs.

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

Once we receive the wallet address, we assign it to the the walletaddress state variable created using the React's useState hook.

Making the API call.

API url we will use here to retrieve the token data:

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

We will also need to pass X-API-KEY in the header, this key is used for authentication purposes.

Getting Your Own X-API-KEY

Now, once we have the wallet address, we are ready to make the API call to fetch our required data which in this case is the token list.

To fetch the data, we have used the axios package, but you can use JavaScript's very own fetch or any other package you want. We have made this call inside React's useEffect hook. Here is the code.

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 to perform request
        url: reqUrl,
        method: "GET",
        headers: {
        "Content-Type": "application/json",
        "x-api-key": xAPIKey,
        },
    })
        // Handle the response from backend here
        .then((res) => {
            console.log(res.data);
            setData(res.data.result); //storing the token array in data
        })
        // Catch errors if any
        .catch((err) => {
            console.warn(err);
        });
    },[walletAddress,netWrk]);

If successful, the response which we get back from the server looks somewhat like this with the result containing an array of all the tokens. We store the array of tokens in the data state variable.

{
    "success": true,
    "message": "4 tokens fetched successfully",
    "result": [
        {
            "address": "G6qTix6iGbnMYpRTsKeaDiTDHAW5E6WBdoRdTYkYKeuy",
            "balance": 20,
            "info": {
                "name": "PIKACOIN",
                "symbol": "PKN",
                "image": "https://nftstorage.link/ipfs/bafkreidyw4o3cu2mucewbakib5aa5udej7hywvgn6a5rmaypg2uclwt6oa"
            }
        },
        {
            "address": "7yPeRofJpfPkjLJ8CLB7czuk4sKG9toXWVq8CcHr4DcU",
            "balance": 75.22,
            "info": {
                "name": "Standrd",
                "symbol": "SD",
                "image": "https://nftstorage.link/ipfs/bafkreig7amamflgtsovczf2el7jt7kuwf274jeaeofjy7iaa34r7exydzm"
            }
        },
        {
            "address": "EFZqqWNC2PqFk8rntHhdPhh86vafZJyy2neX5oGEeeiC",
            "balance": 92.32,
            "info": {
                "name": "ShyftCoin",
                "symbol": "SFC",
                "image": "https://nftstorage.link/ipfs/bafkreigo7yipv25crpi3d5oyoc36ridaj46knwa42wt64trywhq56eirqy"
            }
        },
        {
            "address": "CjLYfcwZT8pfsLMKntKuzUefwsyCDppeLPJvm5HJtsGv",
            "balance": 50,
            "info": {
                "name": "OKACOIN",
                "symbol": "OKC",
                "image": "https://nftstorage.link/ipfs/bafkreidyw4o3cu2mucewbakib5aa5udej7hywvgn6a5rmaypg2uclwt6oa"
            }
        }
    ]
}

The following details are returned from the API for each token present in our wallet: name, address, balance, symbol and image.

Now, let's display this array of tokens in our app. We use JavaScript's map method to display the array inside a table.

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">
            <h4>{tokn.info.name}</h4> {tokn.address}
          </td>
          <td className="w-25 border-2">{tokn.balance} {tokn.info.symbol}</td>
    </tr>
))

Get the details of one particular token

Now, we will attempt to fetch the details of one particular token using our very own SHYFT APIs. We will design this project as an extension of the previous part of the project using React, but you can also design this as a separate project as well.

We will attempt to link the tokens in the previous part with a new page which will display all the details of that particular token.

To achieve this, we have to setup a few routes, the home (/) route will display the details of all tokens and the view-details (/view-details) route will display the details of one particular token.

To setup the routes, we will use the react-router-dom package. To install this package, we run the following command in our terminal inside our project folder.

npm install react-router-dom

Once installed, we have to restart our local server. Now, it's time to setup our routes. Let's create a new component, we will name it the Details component, but you can name it anything you want. We will place this inside Details.js, inside the \src directory. It looks somewhat like this.

Setting Up Routes

Now, inside our App Component (App.js), we set up the Routes. For setting up the Routes, we need the following:

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

We will setup two routes, one for listing all the tokens and another one for displaying the details of one particular token.

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;

Once setup, we should be able to access the /view-details route within our application.

Linking via URL Parameters

We can link each of the token listed in the ListAll component to redirect to the /view-details route along with token_address and network as route parameters. This will help us to get the details of one particular token by updating the token_address in the url even if our wallet is not connected. One of the ways we can achieve this is this:

{
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>
))
}

The <Link></Link> component of the react-router-dom package will help us to navigate to the desired path.

Building the details component

Now, let's create a layout for our Details component. Inside the Details.js file(Details Component), we will create a few state variables using React's useState hook for storing the data and a simple layout for displaying the data. Inside the Details Component, we use the following:

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;

Getting the details of one particular token

Now the token_address and network parameters should be available in the Details component, as we have passed them via route parameters. This is one way of passing the token address. but you can have your own method if you want. If this was a separate application, we could have used a form to collect the token address and the other required parameters. Now, let's see how we can get the details of one particular token.

SHYFT API to fetch the details of one particular token

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

Once we have our X-API-KEY, we are all set. We will use the axios package to make the API call, but you can use any other package or Javascript's very own fetch to make this call.

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 to perform request
            url: reqUrl,
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "x-api-key": xAPIKey,
            },
          })
            // Handle the response from backend here
            .then((res) => {
              console.log(res.data); //we get the response here
                
            })
            // Catch errors if any
            .catch((err) => {
              console.warn(err);
            });
    },[ApiParams]);
    

Once successful, it should return a response which will contain all the information related to the token. Here is a sample response:

{
    "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
    }
}

Now, for the final step, we will assign the data received in the response to the state variables, to display the details in the component. Here is the part of the snippet we will use to update the details.

.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');
  }
    
})

And that's all you have to do get the details of the token.

Congratulations, you have just completed creating a DAPP in which you can get all the tokens in your wallet and their details.

Resources

.

The first to packages mentioned in this list is used for connecting to the phantom wallet, and we will use the axios package to make http requests to our .

This will start a local development server and your application will be up and running at the following link:

(We have used to add very minimal styling to our project but this is not necessary, you can write your own stylesheets or use any other methods for styling your application)

You can find more about our APIs .

x-api-key is an important parameter we pass on to the header while making the API call for authentication purposes. You can get your own x-api-key from our own . Just signup with your email id and you can get it for free.

Congratulations, you have just accomplished out first goal, fetching all tokens from your wallet using . Now we move on the next part of our project that is getting the details of one particular token.

Before making this API call, we need to have our X-API-KEY. x-api-key is an important parameter we pass on to the header for authentication purposes. You can get your own x-api-key from our own . Just signup with your email id and you can get it for free.

That's pretty much for this tutorial, if you enjoyed this then also try out our other tutorials on and . More tutorials are coming soon.

Feel free to clone our and contribute to our community.

If you liked this, you can learn more about SHYFT APIs in our .

You can view a more refined version of this project . A sample snapshot from the community project has been illustrated above.

Join our

Hope you have a good time reading our tutorials and happy hacking!!

📘
😇
here
.
SHYFT website
here
Chrome/Brave
Firefox
here
React
here
SHYFT APIs
http://localhost:3000
bootstrap
here
SHYFT website
here
SHYFT APIs
SHYFT website
here
Building your First NFT Dapp
Read all NFTs from a wallet
code
API Documentation
here
SHYFT API Documentation
Shyft Website
Get API Key
Github
Discord
We will create a module for fetching and displaying a list of all the tokens in your wallet
We will create a module for fetching and displaying all the details related of one particular token.
After opening up your project folder with vscode
A simple button to connect to the Phantom Wallet
List of all tokens associated with your wallet
The new Details component in src/Details.js
Here is a snapshot from our sample project which we have created for our community.