Tokens and locations
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 |
<contract> |
usdt.tether-token.near |
Same as nep141:<contract> |
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:
intear-dex:near: native NEARintear-dex:nep141:<contract>intear-dex:nep245:<contract>:<token id>intear-dex:nep171:<contract>:<token id>
token_output in responses always uses the full form (nep141:..., never a bare contract ID).
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 Plach. Bettear Bot keeps all user funds in rhea-nep141: balances for this reason.
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.
{ "dex_id": "Plach", "token_output": "nep141:wrap.near", ...}If token_output differs from what you asked for:
- Execute the route.
- Find out how much of
token_outputthe trader received. The recommended way is to read the logs in the transaction’s execution outcome, for example the NEP-141ft_transferevent. - 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: 'near', amount_in: receivedAmount, max_wait_ms: '1000', 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", "near"), ("amount_in", received_amount.as_str()), ("max_wait_ms", "1000"), ("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?;The Intear DEX frontend does exactly this and can be used as a reference.
When the output is known exactly (an exact-output request, or a DEX without slippage like staking), the conversion is included and token_output matches your token_out.