alchemy_simulateExecutionBundle
https://api.triport.io/ethSimulates an ordered bundle of Ethereum transactions against a chosen block state and returns the per-transaction execution result for each one, without broadcasting anything on-chain.
alchemy_simulateExecutionBundle runs a list of transactions in sequence
against the EVM state at a given block, exactly as if they had been mined back
to back in a single block, and returns a result entry for each transaction.
State changes made by an earlier transaction in the bundle are visible to the
transactions that follow it, so you can model multi-step flows (approve →
swap → settle, sandwich detection, complex arbitrage paths) before you ever
sign or send them.
Nothing is broadcast and no state is persisted — the call is a read-only
simulation over a forked copy of the chosen block state. Use it to estimate
gas across a whole bundle, to confirm that every step would succeed before you
submit the real bundle with eth_sendBundle, or to
inspect the raw return data of each call.
This method belongs to the eth_trace category. It is available on the pro
tier (5 RPS) and business tier (15 RPS); calls on lower tiers are rejected
with -32002 (see Errors).
Parameters
A single positional parameter: a bundle object.
txsstring[]required0x-prefixed hex). They are simulated in array order.blockNumberstringoptional"0x149e2c2") or a tag ("latest", "pending"). Defaults to "latest".timestampnumberoptionalblock.timestamp during simulation. Defaults to the timestamp of the target block.Response
Response fields
| Field | Type | Description |
|---|---|---|
result.blockNumber | string | Hex block number whose state the bundle was simulated against. |
result.totalGasUsed | string | Hex total gas consumed by all transactions in the bundle. |
result.results | object[] | Per-transaction results, in the same order as the txs input. |
result.results[].success | boolean | true if the transaction executed without reverting. |
result.results[].gasUsed | string | Hex gas used by this individual transaction. |
result.results[].returnData | string | 0x-prefixed raw return data of the call. |
result.results[].error | string | null | Revert reason or execution error for this transaction, or null on success. |
Errors
JSON-RPC errors are returned in the standard error object with a numeric
code and a data payload. See the shared Errors reference
for the full envelope and the HTTP-status ↔ wire-code mapping.
| Code | Meaning | When it happens |
|---|---|---|
-32002 | tier_insufficient (HTTP 403) | Your key is below the pro tier required for this method. The data payload carries current_tier, required_tier, method, category, and upgrade_url. |
-32003 | rate_limited (HTTP 429) | You exceeded your tier's RPS for the eth_trace category (5 RPS pro / 15 RPS business). The data payload carries limit_rps, burst_capacity, and retry_after_sec; the response also sets Retry-After and X-RateLimit-Reset headers. |
Example -32002 response:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32002,
"message": "Method 'alchemy_simulateExecutionBundle' requires pro tier or higher",
"data": {
"current_tier": "free",
"required_tier": "pro",
"method": "alchemy_simulateExecutionBundle",
"category": "eth_trace",
"upgrade_url": "https://triport.io/upgrade/pro"
}
}
}Examples
JavaScript (fetch)
const res = await fetch("https://api.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_simulateExecutionBundle",
params: [{
txs: [rawTx1, rawTx2],
blockNumber: "latest",
}],
}),
});
const { result, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);
console.log(`bundle gas: ${parseInt(result.totalGasUsed, 16)}`);
for (const [i, tx] of result.results.entries()) {
console.log(`tx[${i}] success=${tx.success} gas=${parseInt(tx.gasUsed, 16)}`);
}TypeScript SDK (@triport/sdk)
import { Triport } from "@triport/sdk";
const client = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });
const result = await client.eth.rpc("alchemy_simulateExecutionBundle", [
{
txs: [rawTx1, rawTx2],
blockNumber: "latest",
},
]);
console.log(result.results.map((r) => r.success));Python (triport-sdk)
import os
from triport import Triport
client = Triport(api_key=os.environ["TRIPORT_API_KEY"])
result = client.eth.rpc(
"alchemy_simulateExecutionBundle",
[{
"txs": [raw_tx_1, raw_tx_2],
"blockNumber": "latest",
}],
)
for i, tx in enumerate(result["results"]):
print(f"tx[{i}] success={tx['success']} gas={int(tx['gasUsed'], 16)}")Notes
- Transactions are simulated in order and share state — a later transaction sees the effects of every earlier one in the same bundle.
- This is a simulation only; it neither broadcasts transactions nor changes
on-chain state. To actually submit a validated bundle for inclusion, use
eth_sendBundle. - Rate limiting is RPS-per-tier with a burst allowance; there is no daily quota.
On
-32003, honor theRetry-Afterheader before retrying. - All numeric quantities (
gasUsed,totalGasUsed, block numbers) are0x-prefixed hex, following standard Ethereum JSON-RPC conventions.