Nordstern

Simulate Swap

Simulates an arbitrary swap transaction via eth_call and returns the received output amount, gas usage and raw return data — without holding funds or sending anything on-chain.

POST/simulate/{chain_id}

Simulates any approval-based swap transaction — yours or another aggregator's — against live chain state and reports what it would actually return. Use it to re-validate quotes before execution, to compare aggregators on equal terms, or to debug reverting calldata.

No funds are needed: the simulation runs entirely inside an eth_call with state overrides. A minimal proxy contract is placed at the from address, the input-token balance of from and its allowance towards to are overridden to amountIn, and the proxy then calls to with the given calldata — measuring the received output tokens, the gas the call consumed and its raw return data. The block environment is realistic by default: tx.gasprice is the current network gas price, block.coinbase is the latest block's validator and the gas limit is derived from the block gas limit — so gas- and validator-dependent code paths behave as they would on-chain.

GET is also supported with the same fields as query parameters.

Parameters

chain_idreqinteger

EVM-compatible chain ID (path parameter).

fromreqstring

Wallet address the transaction would be sent from. Output tokens are measured at this address. It does not need to hold any funds or approvals — both are provided via state overrides.

toreqstring

Contract address the transaction calls (typically an aggregator router). Must differ from from.

datareqstring

Transaction calldata as a 0x-prefixed hex string. Submit exactly what you would send on-chain.

tokenInreqstring

Contract address of the input token. Must be an ERC-20: the endpoint models the approval-based flow (wallet approves the router, router pulls the tokens), so native-token inputs are not supported.

amountInreqstring

Input amount in the token's base units. The sender's balance and allowance are overridden to exactly this value. Decimal or 0x-hex.

tokenOutreqstring

Contract address of the output token to measure. Use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for the chain's native token.

gasPricestring

Gas price in wei, reflected by tx.gasprice during the simulation; the sender is automatically funded to cover it. Default: the current network gas price. Pass 0 to simulate without a gas price.

gasstring

Gas limit for the simulation. Default: 50% of the current block gas limit.

blockstring

Block to simulate at: a block number (decimal or 0x-hex) or a tag such as latest or pending. Default: latest.

spenderstring

Address the allowance override is granted to, when the router pulls tokens through a separate contract (e.g. Permit2-style flows). Default: to.

coinbasestring

Address to use as block.coinbase during the simulation. Default: the validator of the most recent block, so validator-dependent logic behaves as it would on-chain.

balanceSlotstring

ERC-20 base storage slot of the token's balance mapping. Resolved automatically for tokens known to the aggregator; required only for exotic tokens.

allowanceSlotstring

ERC-20 base storage slot of the token's allowance mapping. Resolved automatically for tokens known to the aggregator; required only for exotic tokens.

Request

curl 'https://api.nordstern.finance/simulate/8453' \
  -H "Content-Type: application/json" \
  -H "Referer: https://yourdomain.com" \
  -d '{
    "from": "0xYourWalletAddress",
    "to": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d",
    "data": "0x3f0bde25...",
    "tokenIn": "0x4200000000000000000000000000000000000006",
    "amountIn": "1000000000000000000",
    "tokenOut": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  }'
// Re-validate a quote: pass the quote's tx fields straight through.
const response = await fetch("https://api.nordstern.finance/simulate/8453", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Referer": "https://yourdomain.com",
  },
  body: JSON.stringify({
    from: "0xYourWalletAddress",
    to: quote.tx.to,
    data: quote.tx.data,
    tokenIn: "0x4200000000000000000000000000000000000006",
    amountIn: "1000000000000000000",
    tokenOut: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  }),
});
const result = await response.json();
console.log(result);
import requests

url = "https://api.nordstern.finance/simulate/8453"
body = {
    "from": "0xYourWalletAddress",
    "to": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d",
    "data": "0x3f0bde25...",
    "tokenIn": "0x4200000000000000000000000000000000000006",
    "amountIn": "1000000000000000000",
    "tokenOut": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
}
headers = {"Referer": "https://yourdomain.com"}
response = requests.post(url, json=body, headers=headers)
print(response.json())

Response

successboolean

Whether the simulated call succeeded. false means the transaction would revert on-chain; the simulation itself still ran and returns 200.

amountOutstring

Amount of tokenOut received by from, in base units. "0" when success is false.

gasUsedinteger

Gas consumed by the call to to. Excludes the 21,000 intrinsic transaction gas and calldata gas, so it is directly comparable across quotes but slightly below the full on-chain total.

returnDatastring

Raw return data of the call as 0x-prefixed hex. Carries the revert payload when success is false.

revertReasonstring

Human-readable decoded revert reason. Only present when success is false.

blockstring

The block parameter the simulation ran at (echoes the request, default latest).

{
  "success": true,
  "amountOut": "2120362157",
  "gasUsed": 431202,
  "returnData": "0x000000000000000000000000000000000000000000000000000000007e63c92d",
  "block": "latest"
}

A reverting transaction still returns 200, with the decoded reason:

{
  "success": false,
  "amountOut": "0",
  "gasUsed": 54210,
  "returnData": "0x08c379a0...",
  "revertReason": "Insufficient output",
  "block": "latest"
}
Note:

amountOut is measured as a real balance delta at from, so transfer taxes, rebases and router fees are all reflected — it is the amount the wallet would actually receive.

Errors

CodeMeaning
400Missing or invalid parameter, native tokenIn, unknown storage slots for an untracked tokenIn (provide balanceSlot/allowanceSlot), or a simulation setup revert (e.g. tokenOut is not an ERC-20). The plain-text response body describes the issue.
404Chain ID not supported.
502The RPC node backing the simulation failed. Safe to retry.

See Errors for the full error format.

On this page