Tokens and locations
This page is also Markdown, for agents: /dex-aggregator/guides/tokens.md, and /llms.txt lists every page.
The same token can be held in different places: native NEAR or wNEAR in your wallet, a token in your wallet or in your inner balance on a DEX. The aggregator calls these locations and can move tokens between them for you.
Token ID format
Section titled “Token ID format”Use these formats for token_in and token_out:
| Format | Example | Meaning |
|---|---|---|
near |
near |
Native NEAR |
nep141:<contract> |
nep141:usdt.tether-token.near |
NEP-141 token in the trader’s wallet |
rhea-nep141:<contract> |
rhea-nep141:wrap.near |
NEP-141 token in the trader’s Rhea inner balance |
intear-dex:<asset> |
intear-dex:nep141:wrap.near |
Asset in the trader’s Intear DEX inner balance |
Intear DEX asset IDs are the ones Intear DEX uses itself, for NEAR and NEP-141 tokens:
intear-dex:near: native NEARintear-dex:nep141:<contract>
Intear DEX also holds NEP-171 and NEP-245 tokens, but the aggregator doesn’t swap them: intear-dex:nep171: and intear-dex:nep245: tokens fail with Only NEAR and NEP-141s on Intear DEX are supported.
Conversions are automatic
Section titled “Conversions are automatic”Most DEXs only work with NEP-141 tokens in the wallet. When you ask for something else, the route includes the conversions:
nearas input: the route wraps it to wNEAR withnear_depositfirst (or deposits native NEAR directly where the DEX supports it).rhea-nep141:orintear-dex:as input: the route withdraws the tokens from the inner balance first.- A different location as output: the route converts the output at the end, if the amount is known exactly (see below).
Along the way it adds the storage deposits and registrations the trader is missing, based on trader_account_id.
Inner balance shortcuts
Section titled “Inner balance shortcuts”Keeping tokens in a DEX’s inner balance skips steps. For example, a swap from rhea-nep141: to rhea-nep141: is a single swap call on Rhea, instead of ft_transfer_call on the input token, ft_on_transfer on Rhea and ft_transfer of the output. The same works for intear-dex: assets with IntearDex. That makes every swap 2 blocks faster, but inner balances are not displayed in some wallets and it takes longer to withdraw when a swap has to go through another DEX, so choose it based on your app’s usage model.
When token_output differs
Section titled “When token_output differs”The last conversion needs an exact amount. For a swap with slippage and an exact input, the output amount is only known after the swap, so the aggregator can’t add the conversion. In that case the quote’s token_output is not your token_out: the swap delivers the tokens to token_output, and converting them to token_out is a second step you do yourself. For example, token_in=near&token_out=rhea-nep141:usdt.tether-token.near gets quotes that deliver USDt to the wallet:
{ "dex_id": "IntearDex", "token_output": "nep141:usdt.tether-token.near", ...}If token_output differs from what you asked for:
- Execute the route.
- Check the outcome with your
token_inandtoken_out. Itsnext_stepsconvert what the trader received totoken_out. - Execute
next_steps.
You can also do the conversion yourself:
- Find out how much of
token_outputthe trader received, for example from the NEP-141ft_transferevent in the logs of the transaction’s execution outcome. Whentoken_outputisnearor anintear-dex:asset, read the Intear DEX events instead. - Request a second route from
token_outputto yourtoken_out, withamount_inset to the received amount anddexes=Wrap. This conversion is always 1:1, without fees or slippage. - Execute the second route.
const params = new URLSearchParams({ token_in: quote.token_output, token_out: tokenOut, // the token_out of the first route amount_in: receivedAmount, slippage_type: 'Fixed', slippage: '0', dexes: 'Wrap', trader_account_id: 'alice.near',});const response = await fetch(`https://router.intear.tech/route?${params}`);if (!response.ok) throw new Error(await response.text());const conversion = await response.json();let received_amount = received_amount.to_string();let url = reqwest::Url::parse_with_params( "https://router.intear.tech/route", [ ("token_in", quote.token_output.as_str()), ("token_out", token_out), // the token_out of the first route ("amount_in", received_amount.as_str()), ("slippage_type", "Fixed"), ("slippage", "0"), ("dexes", "Wrap"), ("trader_account_id", "alice.near"), ],)?;let conversion: Vec<Quote> = reqwest::get(url).await?.error_for_status()?.json().await?;When the output is known exactly (an exact-output request, or a DEX without slippage like Wrap), the conversion is included and token_output matches your token_out.