Skip to content

GET /route/outcome

GET https://router.intear.tech/route/outcome

Once the trader has sent a route’s transactions, this tells you what they did: how much of the input they spent, how much of the output they received, and why the swap failed if it did. It waits for the transactions to execute, so you can call it right after sending them. With wait_until=swap, it answers as soon as the swap executed, before the output reaches the trader.

It also returns next_steps: transactions that move tokens which ended up somewhere other than token_in or token_out to where they belong. Examples are the wNEAR left over when a swap from NEAR fails, or the output of a route whose token_output isn’t the token_out you asked for.

See Checking the outcome for how it fits in a swap.

https://router.intear.tech/route/outcome?token_in=near&token_out=nep141:usdt.tether-token.near&trader_account_id=alice.near&tx_hashes=9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U,4mSbD8V5E3kCdNghTnzVh7fhCwuC2wB6K9a5xbdZvR3P
Parameter Type Description
token_in token ID The token_in of the route request
token_out token ID The token_out of the route request. Must be different from token_in
trader_account_id account ID The account that signed the transactions
tx_hashes comma-separated list Hashes of the route’s transactions, without its fee transactions. 1 to 20 of them, each once, all signed by trader_account_id
Parameter Type Description
fee_amount integer string The quote’s fee_amount, so that next_steps leave it in the wallet for the fee transactions. Defaults to 0
wait_until string When to answer: executed, the default, once every transaction and receipt executed, with the balances compared; or swap, as soon as the swap executed
key string API key, to lift the rate limit

200 OK with Content-Type: application/json:

{
"charge_fee": true,
"amount_in": "1000000000000000000000000",
"amount_out": "4880007",
"balance_changes": [
{ "token": "near", "change": "-1000000000000000000000000" },
{ "token": "nep141:usdt.tether-token.near", "change": "4880007" }
],
"next_steps": [],
"error": null,
"settled": true
}
Field Type Description
charge_fee boolean Whether the swap went through: true if the trader received any of the output. Send the route’s fee transactions only if it’s true
amount_in string How much of the input the transactions spent, wherever it was held. For NEAR, gas and storage deposits don’t count. What the fee transactions pay isn’t included, since they haven’t been sent yet. Fees paid in the swap’s own transaction are: Plach’s referral fees, which Intear DEX takes in the swap, and the fees of a Rhea swap between Rhea balances (rhea-nep141:)
amount_out string How much of the output the transactions gave, wherever it ended up
balance_changes array Each balance of the input and output tokens that changed, as { "token", "change" }: the token ID of the place it’s held, and the change, a signed integer string, negative if the balance went down
next_steps array Execution instructions that move what ended up somewhere else to token_in or token_out. Execute them like a route’s, after its fee transactions. Usually empty
error string or null Why the swap failed, written to show to the trader. Present when charge_fee is false, null otherwise. See error messages
settled boolean Whether every transaction and receipt executed and the balances were compared. false only for an answer at the swap, whose balance_changes and next_steps are empty

All amounts are strings in the token’s smallest unit. Parse them as big integers.

A failed swap from NEAR on Rhea DCL, where near_deposit succeeded and the swap refunded the wNEAR, gets a next_steps that unwraps it:

{
"charge_fee": false,
"amount_in": "0",
"amount_out": "0",
"balance_changes": [
{ "token": "near", "change": "-1000000000000000000000000" },
{ "token": "nep141:wrap.near", "change": "1000000000000000000000000" }
],
"next_steps": [
{
"NearTransaction": {
"receiver_id": "wrap.near",
"actions": [
{
"FunctionCall": {
"method_name": "near_withdraw",
"args": "eyJhbW91bnQiOiIxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn0=",
"gas": 30000000000000,
"deposit": "1"
}
}
],
"is_fee_transaction": false
}
}
],
"error": "The price moved more than your slippage allows while the transaction was on its way. Try again, or increase the slippage.",
"settled": true
}

The aggregator waits until every transaction and its receipts have executed, at least optimistically, for up to 60 seconds in total. Then it compares the trader’s balances before the block of the first transaction with the balances after the block of the last receipt, in every place a token can be held:

  • NEAR: native NEAR, wNEAR in the wallet, on Rhea and on Intear DEX, and NEAR on Intear DEX
  • Other tokens: the wallet, the Rhea inner balance (rhea-nep141:) and the Intear DEX inner balance (intear-dex:)

Native NEAR is added up from the transactions themselves, so gas and storage deposits don’t count. The other balances are read at those two blocks, so anything else that changes them in between, like another transaction of the trader, counts too.

amount_in and amount_out add up the changes of all the places, so moving a token from one place to another, like wrapping NEAR, isn’t spending it. For a Wrap route between two places of the same token, they’re the changes of token_in and token_out themselves.

With wait_until=swap, the aggregator asks how far the transactions got every 100 ms, and answers as soon as their swaps executed, at least optimistically. It doesn’t wait for the output to reach the trader, for callbacks or for gas refunds. A Plach swap that withdraws to the wallet, for example, is answered at the block it swapped in, a block before the tokens arrive and two before the callback.

It reads the trader’s swaps from what the DEXes log of them:

  • Intear DEX’s swap events, for Plach
  • Rhea DCL’s swap events
  • Rhea’s Swapped <amount> <token> for <amount> <token> logs

It answers once each transaction has either executed or logged a swap, nothing has failed so far, and the swaps gave some of the output. amount_in and amount_out are then what the swaps logged, of the tokens in any of their places, and settled is false. For Plach, the aggregator adds the referral fees of Intear DEX’s swap event to its input, so amount_in is the same as with wait_until=executed. Rhea logs only what it swapped, so with fees, a Rhea swap between Rhea balances has an amount_in less than the one of wait_until=executed by the fees. balance_changes and next_steps are empty, since what ends up somewhere else isn’t known until everything executed: to move it, ask again with wait_until=executed after sending the fee transactions, and execute its next_steps.

A swap that failed, a route without a swap, like a Wrap route, and transactions that all executed before their swaps were seen, are answered as with wait_until=executed, with settled: true.

Errors are plain text (text/plain), as for /route:

Status Message Cause
400 tx_hashes must have 1 to 20 transaction hashes tx_hashes is missing, empty, or has more than 20 hashes
400 tx_hashes must not repeat a transaction A hash is in tx_hashes twice
400 Token in and token out must be different token_in equals token_out
400 fee_amount is too large fee_amount doesn’t fit a signed 128-bit integer
400 Transaction <hash> is signed by <signer>, not <trader> A transaction isn’t signed by trader_account_id
400 Failed to deserialize query string: ... A parameter is missing or has the wrong format
502 Failed to get block <hash>: ... and others Reading a transaction, block or balance from the chain failed
504 Transaction <hash> didn't execute in 60s: <reason> A transaction wasn’t found, or didn’t finish executing, within 60 seconds. For example, it was never sent
504 The transactions didn't execute in 60s: <reason> With wait_until=swap: a transaction wasn’t found, or its swap didn’t execute, within 60 seconds
504 Reading the balances took more than 20s

A request over the rate limit gets 429 Too Many Requests, and a wrong key 401 Unauthorized, as for /route.

When the swap failed, error describes the first failure of the transactions that it recognizes:

error Cause
The price moved more than your slippage allows while the transaction was on its way. Try again, or increase the slippage. The output was less than the minimum, or the input more than the maximum, on Rhea, Rhea DCL or Plach
The pool doesn't have enough liquidity for this trade. Try a smaller amount. A Plach pool doesn’t have enough of the output
You don't have enough tokens for this trade. The balance of the input is too low
Your account isn't registered for one of the tokens. Try again. The trader isn’t registered with a token or DEX
Your account doesn't have enough NEAR for storage. Try again. The trader’s storage deposit on a DEX is too low
The quote expired before the transaction executed. Request a new route and try again. The route’s fee discount expired
The transaction ran out of gas. Try again with a smaller amount. A receipt ran out of gas
Your account doesn't have enough NEAR left for gas and storage. Deposit some NEAR and try again. The trader’s NEAR balance is too low for the account’s storage

Other failures are The swap failed: followed by what the contract panicked with, and a swap that gave nothing without failing is The swap didn't give any tokens.