# Simulation

> Dry-run the transaction for a LayerHop quote with POST /v1/simulate before the user signs, to catch reverts, low allowances and failing Solana transactions.

Source: https://docs.layerhop.com/concepts/simulation

To check whether a LayerHop swap would succeed before the user signs, call `POST /v1/simulate` with the `quoteId`. LayerHop builds the same transaction as `POST /v1/orders` and dry-runs it over RPC (`eth_call` and `eth_estimateGas` on EVM, `simulateTransaction` on Solana) without recording an order or sending anything.

## What does POST /v1/simulate return?

```http
POST /v1/simulate
{ "quoteId": "q_…" }
```

```json
{
  "quoteId": "q_…",
  "provider": "relay",
  "ok": true,
  "vm": "evm",
  "needsApproval": true,
  "simulated": "tx",
  "gasEstimate": "184211",
  "tx": { "vm": "evm", "chainId": 8453, "to": "0x…", "data": "0x…", "value": "0", "approval": { "...": "..." } }
}
```

| Field | Meaning |
|---|---|
| `ok` | `true` if the simulated transaction would succeed |
| `vm` | `evm` or `svm` |
| `gasEstimate` | EVM gas units for what was simulated (decimal string), when the RPC returns one |
| `computeUnits` | Solana compute units consumed |
| `needsApproval` | EVM: the sender's allowance is below `tx.approval.amount`; send the approval first |
| `simulated` | `tx` (the swap itself was simulated) or `approval` (only the approval could be) |
| `error` | `{ code, message, logs? }` when `ok` is `false` |
| `tx` | The built transaction, the same shape as from `POST /v1/orders` |

A failing simulation is still HTTP `200` with `ok: false`. Errors such as an unknown or expired quote use the normal [error shape](/errors).

## How is an EVM transaction simulated?

1. If the transaction has an `approval`, LayerHop reads the sender's current allowance.
2. When the allowance is too low, it sets the allowance through an RPC state override (trying the common ERC-20 storage layouts at once) and confirms it with an `allowance()` call. The swap is then simulated as if the approval were already mined, and `needsApproval` is `true`.
3. If the RPC does not support state overrides, only the approval is simulated (`simulated: "approval"`).
4. The swap runs as `eth_call` from the sender, followed by `eth_estimateGas`. Reverts are decoded into a readable message where possible.

## How is a Solana transaction simulated?

With `simulateTransaction`, signature verification off and the recent blockhash replaced, so an unsigned transaction can be checked. On failure, `error.logs` holds the last program log lines.

## What do the error codes mean?

| `error.code` | Meaning | What to do |
|---|---|---|
| `SIMULATION_FAILED` | The transaction would revert or fail | Show the message; get a new quote, or check balance and recipient |
| `RPC_ERROR` | The simulation could not run (RPC unreachable, rate-limited, method unsupported) | Retry, or skip simulation and rely on the wallet's own preview |

## What does simulation not cover?

- It runs against the current chain state on a public RPC, not a fork; the state can change before the user signs.
- It covers the source-chain transaction only. Delivery on the destination chain is up to the provider.
- There is no call trace yet.

Simulation is optional. Wallets also preview transactions, and the order flow works without it. From the SDK: `await lh.simulate(quoteId)`. See [Simulate the transaction](/api-reference#simulate-the-transaction).
