TriportRPC

simulateBundle

POSThttps://api.triport.io/v1/sol

Dry-runs an MEV bundle — an ordered list of Solana transactions — against the current chain state without broadcasting any of them.

Solanasol_sim_bundlepro+ — 5 / 15 RPS (pro / business)

simulateBundle simulates the execution of an ordered bundle of Solana transactions exactly as they would run if landed back-to-back in a single block, and returns the per-transaction outcome — without submitting anything to the network. Use it to validate an MEV / atomic-arbitrage bundle (or any sequence of dependent transactions) before paying to send it with the bundle-submission methods.

Because the transactions are simulated in order against the same working state, later transactions in the bundle observe the account changes produced by earlier ones. This is the key difference from calling simulateTransaction on each transaction independently: a bundle that only succeeds atomically (for example, a swap that funds a later repay) can be validated as a whole.

This is a pro-tier-only method. It is rate-limited under the sol_sim_bundle category at 5 RPS (pro) / 15 RPS (business), with burst headroom of twice the sustained limit.

Parameters

The parameter schema is provisional (scaffold — finalized in a later spec version). The shape below reflects the intended contract.

JSON-RPC params is a positional array: [bundle, config?].

bundleobjectrequired
The bundle to simulate (see below).
transactionsstring[]required
Ordered list of fully-signed transactions, each as an encoded string. Simulated in array order against a shared working state.
configobjectoptional
Optional simulation configuration (see below).
encodingstringoptional
Encoding of the transactions in bundle.transactionsbase64 (recommended) or base58.
commitmentstringoptional
Commitment level the simulation is evaluated at: processed, confirmed, or finalized.

Response

The result schema is provisional (scaffold — finalized in a later spec version). The shape below reflects the intended contract; the result is an open object, so additional fields may appear.

resultobject
Open response envelope (additionalProperties allowed).
result.contextobject
The context the bundle was simulated against.
result.context.slotinteger
The slot at which the bundle was simulated.
result.context.apiVersionstring
The node software version that served the request.
result.valueobject
The simulation outcome.
result.value.summarystring | object
Overall bundle result — succeeds only if every transaction succeeds in order.
result.value.transactionResultsobject[]
Per-transaction results, in bundle order.
result.value.transactionResults[].errobject | null
null if the transaction simulated successfully, otherwise the transaction error.
result.value.transactionResults[].logsstring[]
Program log output captured during simulation.
result.value.transactionResults[].unitsConsumedinteger
Compute units consumed by the transaction.

Errors

Errors are returned in the standard JSON-RPC error envelope. See the shared errors reference for the full envelope shape and shared codes.

CodeMeaningWhen it happens
-32602Invalid paramsbundle is missing/malformed, transactions is empty or not an array, or a transaction is not decodable under the chosen encoding.
-32002Tier insufficient (HTTP 403)The key's tier is below pro. The error data includes current_tier, required_tier, category (sol_sim_bundle), and an upgrade_url.
-32003Rate limited (HTTP 429)More than your tier's sustained RPS on sol_sim_bundle (5 pro / 15 business). data includes limit_rps and burst_capacity; honor the Retry-After header.
401UnauthorizedMissing or invalid Authorization: Bearer key.

A tier-insufficient response looks like:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32002,
    "message": "Method 'simulateBundle' requires pro tier or higher",
    "data": {
      "current_tier": "free",
      "required_tier": "pro",
      "method": "simulateBundle",
      "category": "sol_sim_bundle",
      "upgrade_url": "https://triport.io/upgrade/pro"
    }
  }
}

Examples

JavaScript (fetch)

const res = await fetch("https://api.triport.io/v1/sol", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "simulateBundle",
    params: [
      { transactions: [base64Tx1, base64Tx2] },
      { encoding: "base64", commitment: "confirmed" },
    ],
  }),
});


const { result, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);


const ok = result.value.transactionResults.every((t) => t.err === null);
console.log(ok ? "bundle simulated clean" : "bundle would revert");

TypeScript SDK (@triport/sdk)

import { TriportClient } from "@triport/sdk";


// simulateBundle requires a pro-tier (or higher) API key.
const client = new TriportClient({ apiKey: process.env.TRIPORT_API_KEY });


const { value } = await client.solana.simulateBundle(
  { transactions: [base64Tx1, base64Tx2] },
  { encoding: "base64", commitment: "confirmed" }
);


const ok = value.transactionResults.every((t) => t.err === null);
console.log(`bundle ${ok ? "OK" : "would fail"}`);

Python (triport-sdk)

import os
from triport import TriportClient


# simulateBundle requires a pro-tier (or higher) API key.
client = TriportClient(api_key=os.environ["TRIPORT_API_KEY"])


result = client.solana.simulate_bundle(
    {"transactions": [base64_tx_1, base64_tx_2]},
    encoding="base64",
    commitment="confirmed",
)


ok = all(t["err"] is None for t in result["value"]["transactionResults"])
print("bundle simulated clean" if ok else "bundle would revert")

Notes

  • Scaffold / provisional: params and result are finalized in spec api.2.2/2.3/2.4. Treat the shapes on this page as the intended contract and re-pin once a published schema version is available.
  • Pro tier only: sol_sim_bundle has no free or basic access — see rate limits and tiers.
  • Ordering matters: transactions are simulated in array order against a shared state, so a later transaction sees earlier transactions' effects. This is what makes it suitable for validating atomic bundles.
  • Dry-run only: simulateBundle never broadcasts. Once a bundle simulates cleanly, submit it with the Solana bundle-submission methods.
  • Related methods: use simulateTransaction to dry-run a single transaction independently, and sendTransaction to broadcast one transaction at a time.