alchemy_simulateAssetChanges — Ethereum JSON-RPC
Simulates a single transaction against the latest state and returns the asset balance changes (ETH, ERC-20, ERC-721, ERC-1155) it would produce — without broadcasting it.
https://triport.io/eth- Network
- Ethereum
- Auth
- x-token: $TRIPORT_API_KEY (or Authorization: Bearer)
- Rate limit
- Pro — 5 RPS sustained · up to 10 burst · Business — 15 RPS sustained · up to 30 burst (with burst); Burst capacity
Endpoint and plans: Ethereum RPC endpoint.
alchemy_simulateAssetChanges runs a transaction through the EVM against the
current chain state and reports the asset movements it would cause if it were
mined now. Use it to preview the effect of a transaction — how much ETH and
which tokens leave or enter each address — before asking a user to sign, so you
can show an accurate "you will send / you will receive" summary and catch
unexpected approvals or transfers.
The simulation is read-only: the transaction is not submitted to the network and no gas is spent. Results reflect the latest committed state at the time of the call, so a transaction that simulates cleanly can still revert or produce different changes once on-chain if state shifts in between.
This method belongs to the eth_trace category and is available on the Pro
tier (5 RPS) and Business tier (15 RPS). A request from a lower tier is
rejected with HTTP 403 tier_insufficient.
Parameters
A single positional parameter: the transaction object to simulate. Fields use
the same hex-quantity and hex-data encoding as eth_call / eth_sendTransaction.
transactionobjectrequiredtransaction.fromstring (address)requiredtransaction.tostring (address)optionaltransaction.valuestring (hex quantity)optional"0xde0b6b3a7640000" for 1 ETH). Defaults to 0x0.transaction.datastring (hex data)optionaltransaction.gasstring (hex quantity)optionalResponse
Response fields
| Field | Type | Description |
|---|---|---|
jsonrpc | string | JSON-RPC protocol version, always "2.0". |
id | number | string | Echoes the request id. |
result | object | The simulation outcome. |
result.changes | array | One entry per asset movement the transaction would cause. Empty if it moves no assets. |
result.changes[].assetType | string | Asset class: NATIVE (ETH), ERC20, ERC721, or ERC1155. |
result.changes[].changeType | string | TRANSFER or APPROVE. |
result.changes[].from | string (address) | Address the asset leaves. |
result.changes[].to | string (address) | Address the asset arrives at. |
result.changes[].rawAmount | string | Amount in base units (no decimal scaling). |
result.changes[].amount | string | Human-readable amount, scaled by decimals. |
result.changes[].symbol | string | null | Token symbol, when known. |
result.changes[].decimals | number | null | Token decimals, when known. |
result.changes[].contractAddress | string | null | Token contract; null for native ETH. |
result.changes[].tokenId | string | null | Token id for ERC-721 / ERC-1155; null otherwise. |
result.gasUsed | string (hex quantity) | Gas the transaction consumed in simulation. |
result.error | string | null | Revert reason if the transaction would revert; null on success. |
Errors
| Code | Meaning | When it happens |
|---|---|---|
403 | tier_insufficient | Your plan is below the Pro tier required for alchemy_simulateAssetChanges. A plain HTTP error rejected before the RPC layer: the body carries current_tier, required_tier and upgrade_url at the top level, plus an X-Required-Tier header. |
429 | rate_limited | You exceeded your tier's RPS limit (5 RPS sustained · up to 10 burst on Pro, 15 RPS sustained · up to 30 burst on Business). A plain HTTP error: the body carries limit_rps, burst_capacity and retry_after_sec, plus Retry-After and X-RateLimit-Reset headers. |
Example response body (tier too low) — HTTP 403, a plain body with no JSON-RPC envelope:
{
"error": "tier_insufficient",
"message": "tier insufficient for method alchemy_simulateAssetChanges",
"method": "alchemy_simulateAssetChanges",
"category": "eth_trace",
"chain": "eth",
"current_tier": "free",
"required_tier": "pro",
"upgrade_url": "https://triport.io/upgrade"
}Example response body (rate limited) — HTTP 429, also a plain body:
{
"error": "rate_limited",
"message": "Rate limit exceeded: 5 RPS sustained on eth_trace (pro tier)",
"current_tier": "pro",
"category": "eth_trace",
"limit_rps": 5,
"burst_capacity": 10,
"retry_after_sec": 1
}A 429 also carries a Retry-After header. See errors.md
for the full error envelope and the shared error-code reference.
Examples
JavaScript (fetch)
const res = await fetch("https://triport.io/eth", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "alchemy_simulateAssetChanges",
params: [
{
from: "0xf1a726210550c306a9964b251cbcd3fa5ecb275d",
to: "0x2e2ed0cfd3ad2f1d34481277b3204d807ca2f8c2",
value: "0xde0b6b3a7640000",
data: "0x",
},
],
}),
});
const { result } = await res.json();
for (const change of result.changes) {
console.log(`${change.amount} ${change.symbol}: ${change.from} -> ${change.to}`);
}Notes
- The transaction is simulated against the latest committed state and is never broadcast — re-simulate just before signing for time-sensitive flows, since state can move between the call and the on-chain inclusion.
- If the transaction would revert,
result.errorcarries the revert reason andresult.changesreflects only the changes up to the revert point. - Requires the Pro tier or higher; a lower tier is rejected with HTTP
403tier_insufficient. - Rate limiting is RPS-per-tier with burst; there is no daily quota.
- To simulate a sequence of transactions together rather than a single one, see alchemy_simulateExecutionBundle.