simulateTransaction — Solana JSON-RPC

Status: Available

Simulates sending a Solana transaction without submitting it to the cluster, returning the would-be execution result, logs, and compute usage.

POSThttps://triport.io/sol
Network
Solana
Scope
sol_sim_bundle
Auth
x-token: $TRIPORT_API_KEY (or Authorization: Bearer)
Rate limit
pro+ — 5 / 15 RPS sustained · short burst 10 / 30 (pro / business). No free or basic access.; Burst capacity

Endpoint and plans: Solana RPC endpoint.

simulateTransaction runs a transaction against the current bank state and returns the result it would produce if submitted, without ever broadcasting it. Use it to pre-flight a transaction: confirm it would succeed, read the program logs it would emit, measure the compute units it would consume, and inspect the post-execution state of selected accounts.

This is the right call before sendTransaction when you want to surface errors to the user, estimate a compute-unit budget, or decode a program's return data without paying fees. Because simulation reflects live bank state, the result is advisory — a transaction that simulates cleanly can still fail on submission if state changes in the interim.

By default the transaction's recent blockhash must be valid for simulation to succeed. Set replaceRecentBlockhash: true to have the node substitute the most recent blockhash before simulating, which lets you simulate a transaction whose own blockhash has already expired.

Tier note: this method belongs to the sol_sim_bundle category and is available on pro and business tiers only. Free- and basic-tier keys are rejected with HTTP 403 tier_insufficient (plus an X-Required-Tier header) before the request reaches the RPC layer — see Errors.

Parameters

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

transactionstringrequired
The transaction, as an encoded string. The encoding must match the encoding field of config.
configobjectoptional
Optional simulation configuration (see below).
sigVerifybooleanoptional
If true, verify the transaction signatures. Mutually exclusive with replaceRecentBlockhash.
commitmentstringoptional
Commitment level used to evaluate state: processed, confirmed, or finalized.
encodingstringoptional
Encoding of the transaction string: base58 or base64. base64 is recommended.
replaceRecentBlockhashbooleanoptional
If true, replace the transaction's recent blockhash with the most recent blockhash before simulating. Mutually exclusive with sigVerify.
minContextSlotintegeroptional
Minimum slot the request must be evaluated at.
innerInstructionsbooleanoptional
If true, include inner instructions in the response.
accountsobjectoptional
Accounts to return post-simulation state for (see below).
config.accountsobject
addressesstring[]optional
Base-58 public keys of the accounts whose state to return after simulation.
encodingstringoptional
Encoding for the returned account data: base58, base64, base64+zstd, or jsonParsed.

Response

Response fields

FieldTypeDescription
resultobjectSimulateTransactionResponse envelope.
result.contextobjectThe context the simulation was evaluated against.
result.context.slotintegerThe slot at which the transaction was simulated.
result.context.apiVersionstringThe node software version that served the request.
result.valueobjectThe simulation result.
result.value.errobject | nullnull if the transaction would succeed; otherwise the error that caused it to fail.
result.value.logsstring[]Program log messages emitted during simulation.
result.value.accountsarray | nullPost-simulation account states, one per address in config.accounts.addresses (in order), or null if accounts was not requested.
result.value.unitsConsumedintegerThe number of compute units consumed by the transaction.
result.value.returnDataobject | nullThe most recent return data generated by an instruction, if any.
result.value.returnData.programIdstring (base-58)The program that generated the return data.
result.value.returnData.dataarrayThe return data, as [data, encoding].
result.value.innerInstructionsarrayInner instructions, present only when innerInstructions: true was set.

Each entry in result.value.accounts is an AccountInfo object with data, executable, lamports, owner, rentEpoch, and space fields.

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 paramstransaction is missing, the encoding does not match config.encoding, or config is malformed (e.g. both sigVerify and replaceRecentBlockhash set).
403Tier insufficientYour key's tier is below pro: simulateTransaction requires pro+ for the sol_sim_bundle category. An HTTP error with a plain JSON body — there is no JSON-RPC envelope: {"error":"tier_insufficient", …} with current_tier, required_tier, method, category and upgrade_url, plus an X-Required-Tier header.
429Rate limitedMore than your tier's RPS for sol_sim_bundle (5 pro / 15 business). Body {"error":"rate_limited", …} with limit_rps, burst_capacity and retry_after_sec; honour Retry-After (and X-RateLimit-Reset).
401UnauthorizedMissing or invalid Authorization: Bearer key.

A failing simulation (e.g. an instruction error) is not a JSON-RPC error: the request returns 200 with result.value.err populated and the relevant logs.

Examples

JavaScript (fetch)

const tx = "AVXo5X7UMtwHFeqHfwopBLrCftbS5UfPiDoXNi8gO1r..."; // base64-encoded tx


const res = await fetch("https://triport.io/sol", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "simulateTransaction",
    params: [tx, { encoding: "base64", replaceRecentBlockhash: true }],
  }),
});


const { result } = await res.json();
if (result.value.err) {
  console.error("Simulation failed:", result.value.err, result.value.logs);
} else {
  console.log(`OK — ${result.value.unitsConsumed} compute units consumed`);
}

Notes

  • sigVerify vs replaceRecentBlockhash: these are mutually exclusive. Set sigVerify: true only when you have a fully signed transaction and want the signatures checked; use replaceRecentBlockhash: true to simulate an unsigned or stale-blockhash transaction.
  • Compute budgeting: read value.unitsConsumed to size a ComputeBudget instruction before submitting the real transaction with sendTransaction.
  • Reading account state: pass config.accounts.addresses to get the post-execution AccountInfo for specific accounts — useful for verifying the effect of a transaction before broadcasting it.
  • Advisory result: a clean simulation does not guarantee on-chain success; state can change between simulation and submission.
  • Related methods: sendTransaction to submit, getFeeForMessage to price a message, and the bundle simulation methods for multi-transaction pre-flight.