Get Tokens Example

View Get Tokens example


Edit on Github

Get Tokens Example

In this tutorial, we will learn how to get tokens from an address with real data using components from MultiversX Design System and MultiversX API.

Requirements

React Next.js Combined Shape@1x Created with Sketch. MultiversX API

Create a New Next.js Project

See how to create a new project in the official Next.js documentation here: Next.js.

Add Dependencies

We recommend the following dependencies to be added to your package.json file:

{
"name": "Your project",
"version": "1.0.0",
"author": "Author",
"license": "License",
"homepage": "your\*homepage",
"repository": {
"type": "git",
"url": "your_url"
},
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"export": "next export",
"lint": "next lint",
"format": "prettier --write '\*\*/\_.{js,ts,tsx,json}'"
},
"dependencies": {
"next": "^12.2.0",
"react": "17.0.2",
"@useelven/core": "0.4.0",
"react-bootstrap": "^2.4.0",
"react-dom": "17.0.2",
"react-router-dom": "^6.3.0",
"sass": "^1.53.0"
},
"devDependencies": {
"@types/jsonwebtoken": "^8.5.8",
"@types/lodash.clonedeep": "^4.5.7",
"eslint": "8.19.0",
"eslint-config-next": "12.2.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-valtio": "0.4.4",
"prettier": "2.7.1",
"typescript": "4.7.4"
}
}

Get Collection from MultiversX API

In your new component created file, you can use the below code to get stats collection data:

import React, { useEffect, useState } from 'react';
import NavTabsInit from './NavTabsInit';
import ReactPaginate from 'react-paginate';
import NoNFT from './NoNFT';
import HeaderMain from './Header';
import { useAccount } from '@useelven/core';

interface IApiData {
getTokens?: string[];
getMetaESDT?: string[];
}

const Tokens = () => {
const { address } = useAccount();
const [tokens, setTokens] =
useState < IApiData | null > ();

    useEffect(() => {
        const urls = [
            `https://api.multiversx.com/accounts/${address}/tokens`,
            `https://api.multiversx.com/${address}/nfts?type=MetaESDT`,
        ];

        Promise.all(
            urls.map((url) => fetch(url).then((resp) => resp.json()))
        ).then((data) => {
            setTokens({
                getTokens: data[1],
                getMetaESDT: data[2],
            });
        });
    }, [address]);

    const [loading, setLoading] = useState(true);

    // We start with an empty list of items.
    const [currentItems, setCurrentItems] = useState < any[] > ([]);
    const [pageCount, setPageCount] = useState(0);
    // Here we use item offsets; we could also use page offsets
    // following the API or data you're working with.
    const [itemOffset, setItemOffset] = useState(0);
    const itemsPerPage = 5;

    useEffect(() => {
        // Fetch items from another resources.
        const endOffset = itemOffset + itemsPerPage;
        setCurrentItems(tokens.getTokens.slice(itemOffset, endOffset));
        setPageCount(Math.ceil(tokens.getTokens.length / itemsPerPage));

        setTimeout(() => {
            setLoading(false);
        }, 1500);
    }, [itemOffset, tokens.getTokens]);

    // Invoke when user click to request another page.
    const handlePageClick = (event: { selected: number }) => {
        const newOffset = (event.selected * itemsPerPage) % tokens.getTokens.length;
        setItemOffset(newOffset);
    };

    const formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
    });

    const getValueFromBalance = (balance: string, decimals: number) => {
        const position = balance.length - decimals;
        if (position < 0) {
            let size = Math.abs(position);
            let zeros = '';
            while (size > 0) {
                zeros += '0';
                size--;
            }
            return `0.${zeros}${balance}`;
        } else {
            return parseFloat(
                balance.substring(0, position) + '.' + balance.substring(position)
            ).toLocaleString();
        }
    };

    return ();

};

export default Tokens;

Design Stats Card

In the previously created component, you can add the code for the tokens card inside the return () statement. This token card will use the received data to be displayed on our new card:

<div className="row">
    <div className="col-12">
      <h2 className="mb-2 font-weight-bolder mt-6 text-center">
        My Tokens
      </h2>
      <p className="text-lg mb-2 text-center mb-5"> 
        Find out the details about each Token and MetaESDT from your
        wallet.
      </p>
    </div>
  </div>
  <div className="row mt-5">
    <div className="col-md-7 mx-auto">
      <div className="card h-100 shadow-none">
        <div className="card-body p-3 pt-0">
          <div className="tab-content" id="myTabContent">
            <div
              className="tab-pane fade show active"
              id="tokens-tab"
              role="tabpanel"
              aria-labelledby="tokens-tab"
              tabIndex={0}
            >
              <ul className="list-group mb-4 mt-2">
                {currentItems.map(
                  (token: any, i: React.Key | null | undefined) => (
                    <li
                      className={`list-group-item border ${
                        i !== currentItems.length - 1
                          ? 'border-bottom-0'
                          : null
                      } d-flex align-items-center px-0`}
                      key={i}
                    >
                      <div className="avatar avatar-sm rounded-circle me-3 ms-3">
                        <img
                          src={`https://media.elrond.com/tokens/asset/${token.identifier}/logo.svg`}
                          alt={`${token.identifier}`}
                          className="w-100"
                        />
                      </div>
                      <div className="d-flex align-items-start flex-column justify-content-center">
                        <h6 className="mb-0 font-weight-semibold text-lg">
                          {token.name}
                        </h6>
                        <p className="mb-0 text-xs text-secondary">
                          {token.identifier}
                        </p>
                        <p className="mb-0 mt-2 font-weight-bold text-sm text-dark">
                          {getValueFromBalance(
                            token.balance,
                            token.decimals
                          )}{' '}
                          (
                          <span>
                            {token.valueUsd
                              ? formatter.format(token.valueUsd)
                              : '$0'}
                          </span>
                          )
                        </p>
                      </div>

                      <a
                        href={`https://explorer.elrond.com/tokens/${token.identifier}`}
                        target="_blank"
                        type="button"
                        className="btn btn-sm btn-outline-dark ms-auto me-3 mb-0"
                      >
                        Token Details
                      </a>
                    </li>
                  )
                )}
              </ul>
            </div>
            <div
              className="tab-pane fade"
              id="esdt-tab"
              role="tabpanel"
              aria-labelledby="esdt-tab"
              tabIndex={0}
            >
              <ul className="list-group mb-4 mt-2">
                {currentItems.map(
                  (token: any, i: React.Key | null | undefined) => (
                    <li
                      className={`list-group-item border ${
                        i !== currentItems.length - 1
                          ? 'border-bottom-0'
                          : null
                      } d-flex align-items-center px-0`}
                      key={i}
                    >
                      <div className="avatar avatar-sm rounded-circle me-3 ms-3">
                        <img
                          src={`${token.assets.pngUrl}`}
                          alt={`${token.name}`}
                          className="w-100"
                        />
                      </div>
                      <div className="d-flex align-items-start flex-column justify-content-center">
                        <h6 className="mb-0 font-weight-semibold text-lg">
                          {token.name}
                        </h6>
                        <p className="mb-0 text-xs text-secondary">
                          {token.identifier}
                        </p>
                        <p className="mb-0 mt-2 font-weight-bold text-sm text-dark">
                          {getValueFromBalance(
                            token.balance,
                            token.decimals
                          )}{' '}
                          (
                          <span>
                            {token.valueUsd
                              ? formatter.format(token.valueUsd)
                              : ''}
                          </span>
                          )
                        </p>
                      </div>
                    </li>
                  )
                )}
              </ul>
            </div>
            <ReactPaginate
              breakLabel="..."
              nextLabel=">"
              onPageChange={handlePageClick}
              pageRangeDisplayed={1}
              pageCount={pageCount}
              previousClassName="page-item"
              nextClassName="page-item"
              previousLinkClassName="page-link font-weight-bold"
              nextLinkClassName="page-link font-weight-bold me-0"
              breakClassName="page-item"
              breakLinkClassName="page-link font-weight-bold"
              previousLabel="<"
              renderOnZeroPageCount={undefined}
              className="pagination justify-content-end mb-0"
              pageClassName="page-item"
              pageLinkClassName="page-link font-weight-normal"
              activeClassName="active"
            />
          </div>
        </div>
      </div>
    </div>

  </div>