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>