# Transaction simulation

Simulate EVM transactions against the current chain state without broadcasting them. The API executes your calls in a sandboxed environment and returns predicted balance changes, emitted events, gas estimates, and revert errors.

## When to use simulation

- **Pre-flight checks** - verify a transaction will succeed before asking a user to sign it.
- **Fee estimation** - get accurate gas costs for complex contract interactions.
- **Balance previews** - show users exactly which tokens will move and by how much.
- **Batch validation** - test multiple calls in a single block to catch ordering issues.


## Make a simulation request

Send one or more calls to [`POST /simulate/evm/{chain_gid}`](/apis/platform/api/simulate/simulate-evm). The `chain_gid` is a CAIP-2 identifier such as `eip155:1` (Ethereum) or `eip155:137` (Polygon). All fields in each call - `from`, `to`, `value`, and `data` - are required. Values are hex-encoded.

curl

```bash
curl -X POST "https://api.vilna.io/v1/simulate/evm/eip155:1" \
  -H "X-Api-Key: ${VILNA_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "block_state_calls": [
      {
        "calls": [
          {
            "from": "0x974caa59e49682cda0ad2bbe82983419a2ecc400",
            "to": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
            "value": "0x0",
            "data": "0xa9059cbb000000000000000000000000d0930a8fc56fd94038250bb93dbac0e13da4eb99000000000000000000000000000000000000000000000000000000003b9aca00"
          }
        ]
      }
    ]
  }'
```

TypeScript

```typescript
const { data, error } = await client.POST("/simulate/evm/{chain_gid}", {
  params: { path: { chain_gid: "eip155:1" } },
  body: {
    block_state_calls: [
      {
        calls: [
          {
            from: "0x974caa59e49682cda0ad2bbe82983419a2ecc400",
            to: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
            value: "0x0",
            data: "0xa9059cbb000000000000000000000000d0930a8fc56fd94038250bb93dbac0e13da4eb99000000000000000000000000000000000000000000000000000000003b9aca00",
          },
        ],
      },
    ],
  },
});
```

You can include multiple calls in a single `block_state_calls` entry to simulate them sequentially within the same block. This is useful for testing approval-then-transfer flows.

## Understand the response

The response contains an `items` array with one `SimulatedTransaction` per input call, plus a `references` map with token and blockchain metadata.

Each simulated transaction includes:

| Field | Description |
|  --- | --- |
| `is_success` | Whether the call executed without reverting. |
| `events` | Canonical events (transfers, approvals, fees) that would be emitted. |
| `activity` | Predicted balance changes per address and asset, with `direction` (`in`/`out`) and `delta`. |
| `error` | Present only on failure. Contains `code`, `message`, and hex-encoded `data` for revert decoding. |
| `chain_gid` | The chain the transaction was simulated on. |
| `txid` | A synthetic transaction hash for correlation. |
| `block_number` | The block height used for simulation. |


The `references` object maps asset GIDs to token details (symbol, decimals) and chain GIDs to blockchain metadata, so you can resolve human-readable names without extra API calls.

## Limitations

- EVM chains only. Non-EVM chains (Solana, Tron, Bitcoin) are not supported.
- Simulation reflects state at the current block. The actual outcome may differ if state changes between simulation and broadcast.
- Requires the `api:blockchain:read` permission on your API key.


## Next steps

Core Concepts
Amounts, references, and the response envelope pattern

Integration Patterns
Deposit detection, portfolio tracking, and other common workflows