alchemy_simulateAssetChanges
https://api.triport.io/v1/ethSimulates 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.
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 returns
-32002 (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 |
|---|---|---|
-32002 | tier_insufficient | Your plan is below the Pro tier required for alchemy_simulateAssetChanges. The error data includes current_tier, required_tier, and an upgrade_url. |
-32003 | rate_limited | You exceeded your tier's RPS limit (5 RPS on Pro, 15 RPS on Business). The error data includes limit_rps, burst_capacity, and retry_after_sec. |
Example error envelope (tier too low):
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32002,
"message": "tier insufficient for method alchemy_simulateAssetChanges",
"data": {
"method": "alchemy_simulateAssetChanges",
"category": "eth_trace",
"chain": "eth",
"current_tier": "free",
"required_tier": "pro",
"upgrade_url": "https://api.triport.io/upgrade"
}
}
}Example error envelope (rate limited):
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32003,
"message": "Rate limit exceeded: 5 RPS sustained on eth_trace (pro tier)",
"data": {
"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://api.triport.io/v1/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}`);
}TypeScript SDK (@triport/sdk)
import { Triport } from "@triport/sdk";
const client = new Triport({ apiKey: process.env.TRIPORT_API_KEY });
const result = await client.eth.request("alchemy_simulateAssetChanges", [
{
from: "0xf1a726210550c306a9964b251cbcd3fa5ecb275d",
to: "0x2e2ed0cfd3ad2f1d34481277b3204d807ca2f8c2",
value: "0xde0b6b3a7640000",
data: "0x",
},
]);
console.log(result.changes);Python (triport-sdk)
import os
from triport import Triport
client = Triport(api_key=os.environ["TRIPORT_API_KEY"])
result = client.eth.request("alchemy_simulateAssetChanges", [
{
"from": "0xf1a726210550c306a9964b251cbcd3fa5ecb275d",
"to": "0x2e2ed0cfd3ad2f1d34481277b3204d807ca2f8c2",
"value": "0xde0b6b3a7640000",
"data": "0x",
},
])
for change in result["changes"]:
print(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 returns
-32002(tier_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.