How to fetch token names, symbols, decimals, images, prices, tags, and contract addresses with the STON.fi REST API and TypeScript client.
If you are building a token selector, portfolio view, swap interface, analytics dashboard, or any other TON application, you rarely want to decode every jetton's metadata yourself. STON.fi provides an HTTP API that exposes normalized asset information and a TypeScript client that makes those endpoints easier to use.
For most applications, the workflow is simple: query STON.fi for an asset list, identify every asset by its contract address, read the metadata you need for display, and keep transaction-critical logic separate from labels such as token names and symbols. The API currently provides endpoints for listing assets, fetching one asset by address, and querying assets with search and filtering conditions.
What does STON.fi mean by an asset?
On TON, fungible tokens normally use the jetton standard. Their metadata can include a name, symbol, decimals, image, and other fields. TEP-64 allows metadata to be stored on-chain, off-chain, or through a semi-chain combination where some values come from the contract and others come from an external document.
STON.fi gives developers a more convenient application-level view of assets used around the DEX. Instead of decoding cells and resolving metadata yourself for every token, you can query the STON.fi API.
Depending on the endpoint, an asset can contain information such as:
- contract address
- asset kind
- token name and symbol
- decimals
- image URL
- STON.fi DEX price in USD
- tags
- popularity information
- wallet balance when a wallet-aware endpoint is used
- optional extensions and scaling information
The API currently distinguishes asset kinds such as Ton, Wton, Jetton, and NotAnAsset. Its newer asset schema groups display metadata under a meta object, while the older asset response exposes fields such as symbol, display_name, decimals, and image_url directly.
That schema difference is worth noticing because code written for getAsset() and code written for queryAssets() may access metadata differently.
Pick the query that matches your UI
STON.fi provides several related asset endpoints, but they answer different questions.
| What you need | REST endpoint | TypeScript client |
|---|---|---|
| Every available DEX asset | GET /v1/assets |
getAssets() |
| One known asset | GET /v1/assets/{address} |
getAsset(address) |
| Search and filter assets | POST /v1/assets/query |
queryAssets(...) |
| Assets held by a wallet | GET /v1/wallets/{address}/assets |
getWalletAssets(address) |
| One wallet asset and its balance | GET /v1/wallets/{address}/assets/{asset} |
getWalletAsset(...) |
For a production token selector, queryAssets() is usually more useful than downloading every known asset. It lets you search by text or address and combine the search with STON.fi asset conditions.
If you already know the contract address, however, fetching that specific asset is simpler and removes the ambiguity that comes with searching by a ticker.
Query one token directly by address
The most deterministic asset lookup starts with the contract address.
Using the REST API:
async function getStonAsset(address: string) {
const response = await fetch(
`https://api.ston.fi/v1/assets/${encodeURIComponent(address)}`
);
if (!response.ok) {
throw new Error(`STON.fi API returned ${response.status}`);
}
const data = await response.json();
return data.asset;
}
The official API base URL is:
https://api.ston.fi
The equivalent operation with the official TypeScript package is shorter:
npm install @ston-fi/api
import { StonApiClient } from "@ston-fi/api";
const client = new StonApiClient();
const asset = await client.getAsset("EQ...");
console.log(asset);
StonApiClient uses https://api.ston.fi by default, so no API configuration is required for a basic request. The current client source maps getAsset() directly to GET /v1/assets/{assetAddress}.
This pattern is ideal when an address comes from a trusted configuration, a pool response, a swap quote, or another part of your application where the asset has already been identified.
Search for tokens without downloading the whole list
A token picker has a different problem. The visitor may type USD, STON, or part of a token name, so you need discovery rather than an exact lookup.
STON.fi provides POST /v1/assets/query for this.
A direct REST request can look like this:
async function searchAssets(search: string) {
const response = await fetch(
"https://api.ston.fi/v1/assets/query",
{
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
search_terms: [search],
condition:
"asset:liquidity:very_high | asset:liquidity:high",
limit: 20,
}),
}
);
if (!response.ok) {
throw new Error(`Asset query failed: ${response.status}`);
}
const data = await response.json();
return data.asset_list;
}
The request schema supports search terms containing addresses or text such as token names and symbols. It also supports a condition, sorting parameters, a result limit, unconditional assets, and an optional wallet address.
With @ston-fi/api, the same query becomes easier to read:
import {
StonApiClient,
AssetTag,
} from "@ston-fi/api";
const client = new StonApiClient();
const assets = await client.queryAssets({
searchTerms: ["USD"],
condition: [
AssetTag.LiquidityVeryHigh,
AssetTag.LiquidityHigh,
].join(" | "),
limit: 20,
});
console.log(assets);
STON.fi's own quickstart uses the same approach to populate token selectors, combining LiquidityVeryHigh, LiquidityHigh, and LiquidityMedium tags and then storing the returned AssetInfoV2 objects in application state.
The older searchAssets() client method still exists, but the current source marks it as deprecated and redirects it through queryAssets(). New integrations should therefore use queryAssets() directly.
Turn the response into clean application data
A raw API object usually contains more information than a component needs. Normalizing it once makes the rest of your frontend much easier to maintain.
The newer query response exposes display metadata under meta.
import type { AssetInfoV2 } from "@ston-fi/api";
type TokenOption = {
address: string;
name: string;
symbol: string;
decimals?: number;
imageUrl?: string;
priceUsd?: string;
tags: string[];
};
function toTokenOption(asset: AssetInfoV2): TokenOption {
return {
address: asset.contractAddress,
name: asset.meta?.displayName ?? "Unknown token",
symbol: asset.meta?.symbol ?? "TOKEN",
decimals: asset.meta?.decimals,
imageUrl: asset.meta?.imageUrl,
priceUsd: asset.dexPriceUsd,
tags: asset.tags ?? [],
};
}
Then your UI can work with a small predictable model:
const options = assets.map(toTokenOption);
The official AssetInfoV2 structure includes the contract address, asset kind, optional balance, DEX price, meta, popularity information, tags, wallet address, scale, and extensions. Inside meta, fields such as decimals, symbol, display name, image URL, and custom payload API URI are optional.
That optionality matters. A robust token selector should not assume that every asset has a complete name, icon, or even every display field.
A reasonable display fallback is:
- Show
displayNamewhen available. - Fall back to
symbol. - Keep the contract address available as the definitive identifier.
- Use a local placeholder when no usable image exists.
Decimals are metadata that affect real amounts
A missing icon is mostly a visual problem. Incorrect decimals are different because decimals determine how integer token units become human-readable balances.
Suppose an API returns:
{
meta: {
symbol: "EXAMPLE",
decimals: 6
}
}
An on-chain amount of:
1250000
represents:
1.25 EXAMPLE
not 1,250,000 tokens.
Avoid normal JavaScript floating-point arithmetic when converting transaction amounts. A simple display helper can use BigInt:
function formatUnits(value: string, decimals: number) {
const units = BigInt(value);
const base = 10n ** BigInt(decimals);
const whole = units / base;
const fraction = (units % base)
.toString()
.padStart(decimals, "0")
.replace(/0+$/, "");
return fraction
? `${whole}.${fraction}`
: whole.toString();
}
TON's token metadata standard defines decimals as a jetton metadata attribute and specifies 9 as the default when the field is absent. Still, if your application receives incomplete or unexpected STON.fi metadata, treating that object carefully is safer than blindly assuming every response represents a normal jetton.
Use tags to improve token discovery
STON.fi does more than return names and icons. Its TypeScript client currently exposes a range of asset tags that can help shape search results and token lists.
Examples include:
AssetTag.Essential
AssetTag.Popular
AssetTag.LiquidityVeryHigh
AssetTag.LiquidityHigh
AssetTag.LiquidityMedium
AssetTag.WalletHasBalance
AssetTag.Deprecated
AssetTag.Blacklisted
AssetTag.Suspicious
AssetTag.Fake
AssetTag.Honeypot
AssetTag.NonSearchable
The exact tag set can evolve, so import the constants from the package instead of copying string values throughout your application. The current client source also includes tags for scaled assets, taxable assets, DMCA complaints, wallet liquidity, and several liquidity levels.
A wallet-aware selector can combine discovery with the connected wallet:
const walletAssets = await client.queryAssets({
condition: [
AssetTag.Essential,
AssetTag.Popular,
AssetTag.WalletHasBalance,
].join(" | "),
walletAddress,
});
That gives you a useful foundation for sections such as "Your tokens" or "Popular assets" without maintaining a separate token registry in your frontend.
Tags should still be treated as API classification data, not as cryptographic proof that an asset is safe.
Never identify a token by its symbol alone
Imagine your application searches for USD and receives several assets. Choosing the first item because its ticker looks familiar is a dangerous shortcut.
TON's own token metadata documentation explicitly warns that anyone can create a jetton using any name, description, or image. Applications should distinguish tokens by their addresses rather than relying on names or tickers.
For a production STON.fi integration, keep these rules simple:
- Use
contractAddressas the asset identifier. - Treat symbol and display name as presentation metadata.
- Preserve the selected address when requesting quotes or constructing transactions.
- Do not infer authenticity from an icon.
- Consider STON.fi tags when deciding which assets should appear prominently.
- Give users a way to inspect or verify the contract address for unfamiliar assets.
This becomes especially important for symbols such as USDT, USD, TON, or any popular project ticker that someone could imitate.
The interface may display:
Example USD
USD
$1.00
but the application state should fundamentally remember:
{
contractAddress: "EQ..."
}
The address is what connects the display object to the actual TON asset.
A practical STON.fi token selector
Putting the pieces together, a small React application might query STON.fi as the user types instead of loading the entire asset catalog.
import {
AssetTag,
StonApiClient,
type AssetInfoV2,
} from "@ston-fi/api";
const stonApi = new StonApiClient();
export async function findTokens(
searchTerm: string
): Promise<AssetInfoV2[]> {
const searchTerms = searchTerm.trim()
? [searchTerm.trim()]
: undefined;
return stonApi.queryAssets({
searchTerms,
condition: [
AssetTag.LiquidityVeryHigh,
AssetTag.LiquidityHigh,
AssetTag.LiquidityMedium,
].join(" | "),
limit: 30,
});
}
Your component can then render the fields STON.fi already normalized:
{assets.map((asset) => (
<button
key={asset.contractAddress}
onClick={() => setSelectedAsset(asset)}
>
{asset.meta?.imageUrl && (
<img
src={asset.meta.imageUrl}
alt=""
width={32}
height={32}
/>
)}
<strong>
{asset.meta?.symbol ?? "Unknown"}
</strong>
<span>
{asset.meta?.displayName ?? asset.contractAddress}
</span>
</button>
))}
For a real product, add loading states, request cancellation or debouncing for live search, image fallbacks, error handling, and caching. Metadata images and other external resources should also be treated as untrusted input. If your backend fetches arbitrary remote resources, apply normal URL validation and server-side request protections.
STON.fi's own Omniston quickstart follows the same core architecture: fetch assets through StonApiClient, keep AssetInfoV2 objects in state, display meta.symbol or meta.displayName, and pass the selected contract addresses into later swap operations.
Practical takeaway: use getAsset() when the contract address is already known and queryAssets() when you are building discovery or search. Keep the contract address as your canonical identifier, normalize optional metadata before it reaches your UI, and use STON.fi's tags to make large token lists easier to navigate.
Frequently Asked Questions
Can I query STON.fi token metadata without installing an SDK?
Yes. The REST API is available at https://api.ston.fi, so any environment capable of making HTTP requests can use it. GET /v1/assets/{address} retrieves a specific asset, while POST /v1/assets/query supports filtered discovery. The @ston-fi/api package is mainly a convenience layer for TypeScript and JavaScript applications.
What metadata does STON.fi return for a token?
Depending on the endpoint and schema, you can receive a contract address, kind, symbol, display name, decimals, image URL, prices, tags, popularity information, optional extensions, and wallet-related fields. Query responses use the newer model where core display metadata is grouped under meta, and those metadata fields can be optional.
Should I use getAssets() or queryAssets()?
Use getAssets() when you genuinely need the complete DEX asset collection. Use queryAssets() for most interactive interfaces because it supports search terms, conditions, wallet-aware queries, sorting, and limits. A search box usually does not need the full asset catalog before the user has typed anything.
Can two TON tokens have the same symbol?
Yes. Names and symbols are metadata, and token creators can choose them. A familiar ticker therefore does not uniquely identify a jetton. TON documentation recommends distinguishing tokens by address. Your frontend can display the symbol prominently, but your application logic should retain and use the contract address.
What should I do if meta.imageUrl or meta.displayName is missing?
Use a fallback. Display the symbol or a shortened address when a name is unavailable, and use a local placeholder image when no valid icon exists. Do not make rendering a token dependent on optional cosmetic metadata. AssetInfoV2 deliberately represents several metadata properties as optional.
Does STON.fi provide token prices together with metadata?
The asset schemas include optional STON.fi DEX price information such as dex_price_usd, exposed in camelCase by the TypeScript client. Treat price data separately from identity metadata because a price can be absent or change frequently, while the contract address is the persistent identifier used by your application.
Can I use STON.fi metadata to build a wallet token list?
Yes. STON.fi exposes wallet-specific asset endpoints, and queryAssets() can also accept a wallet address together with conditions such as AssetTag.WalletHasBalance. That makes it possible to combine searchable DEX assets with wallet-aware token selection without maintaining a completely separate metadata database.
What is the safest way to query a STON.fi asset before using it in a swap?
Start from the exact contract address whenever possible. Retrieve the asset, display its metadata for readability, but keep the address as the selected value passed into your swap logic. For search-based selection, show enough identifying information for the user to distinguish similar tokens and avoid treating a matching name, ticker, or image as proof of identity.
Sources and Further Reading
- STON.fi DEX API Reference - Official overview of asset, pool, wallet, swap, and other REST endpoints
- STON.fi REST API - Official introduction to the STON.fi HTTP API and TypeScript client
- STON.fi Swagger UI - Current interactive REST API schemas, asset endpoints, request parameters, and response models
- STON.fi API GitHub repository - Official source and usage examples for the
@ston-fi/apiTypeScript client - STON.fi asset types - Official
AssetInfo,AssetInfoV2,AssetKind, andAssetTagdefinitions - STON.fi Omniston Quickstart - Official React example showing how
StonApiClientandqueryAssets()populate token selectors - TON Token Metadata Documentation - Official explanation of on-chain, off-chain, and semi-chain token metadata and token identity considerations
- TEP-64 Token Data Standard - TON specification defining token metadata layouts and jetton metadata fields






Top comments (1)
Hi. If you find an error in the text, please let me know in the comments! It will be a great help to others reading this article! Thank you for your support and assistance!