> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# simulateEvmTransaction

> Preview an EVM transaction's effects before sending it

Simulates an EVM transaction and returns a breakdown of expected asset changes, security validation
results, and optionally an estimated gas fee — all before the transaction is sent to the network.

Powered by [Blockaid](https://blockaid.io) for security validation.

## Installation

```bash theme={"system"}
npm install @dynamic-labs-sdk/evm
```

## Usage

> [tab] JavaScript
>
> ```javascript theme={"system"}
> import { simulateEvmTransaction } from '@dynamic-labs-sdk/evm';
> import { isEvmWalletAccount } from '@dynamic-labs-sdk/evm';
> import { getPrimaryWalletAccount } from '@dynamic-labs-sdk/client';
> import { getAddress, parseEther } from 'viem';
>
> const walletAccount = getPrimaryWalletAccount();
>
> if (walletAccount && isEvmWalletAccount(walletAccount)) {
>   const result = await simulateEvmTransaction({
>     walletAccount,
>     transaction: {
>       from: getAddress(walletAccount.address),
>       to: '0x742d35Cc6634C0532925a3b844Bc9e7595f7ABCD',
>       networkId: '1',
>       value: parseEther('0.1'),
>     },
>   });
>
>   console.log('Assets going out:', result.outAssets);
>   console.log('Assets coming in:', result.inAssets);
>   console.log('Security check:', result.validation?.result);
> }
> ```

> [tab] React
>
> Call `simulateEvmTransaction` inside a button handler to preview the transaction before the user confirms it:
>
> ```tsx theme={"system"}
> import { simulateEvmTransaction, isEvmWalletAccount } from '@dynamic-labs-sdk/evm';
> import { useGetWalletAccounts } from '@dynamic-labs-sdk/react-hooks';
> import { useState } from 'react';
> import { parseEther } from 'viem';
>
> function SimulateButton({ recipientAddress }) {
>   const { data: walletAccounts = [] } = useGetWalletAccounts();
>   const walletAccount = walletAccounts[0];
>   const [result, setResult] = useState(null);
>
>   const handleSimulate = async () => {
>     if (!walletAccount || !isEvmWalletAccount(walletAccount)) return;
>
>     const simulation = await simulateEvmTransaction({
>       walletAccount,
>       transaction: {
>         from: walletAccount.address as `0x${string}`,
>         to: recipientAddress,
>         networkId: '1',
>         value: parseEther('0.1'),
>       },
>     });
>
>     setResult(simulation);
>   };
>
>   return (
>     <div>
>       <button onClick={handleSimulate}>Preview Transaction</button>
>       {result && (
>         <div>
>           <p>Security: {result.validation?.result}</p>
>           <p>Assets out: {result.outAssets.length}</p>
>         </div>
>       )}
>     </div>
>   );
> }
> ```

## Parameters

| Parameter | Type | Description |
| - | - | - |
| `walletAccount` | `EvmWalletAccount` | The wallet account initiating the transaction |
| `transaction` | `object` | The transaction to simulate (see below) |
| `transaction.from` | `string` | The sender address |
| `transaction.to` | `string` | The recipient or contract address |
| `transaction.networkId` | `string` | The chain ID (e.g., `'1'` for Ethereum mainnet) |
| `transaction.value` | `bigint` (optional) | Native token amount to send, in wei |
| `transaction.data` | `string` (optional) | Encoded contract call data |
| `includeFees` | `boolean` (optional) | Whether to include a gas fee estimate. Default: `false` |
| `client` | `DynamicClient` (optional) | Only required when using multiple clients |

## Returns

`Promise<EvmSimulationResult>` — an object with the following fields:

| Field | Type | Description |
| - | - | - |
| `inAssets` | `AssetDiff[]` | Assets the wallet will receive |
| `outAssets` | `AssetDiff[]` | Assets the wallet will send |
| `validation` | `BlockaidValidation` (optional) | Security assessment from Blockaid |
| `validation.result` | `'benign' \| 'warning' \| 'malicious'` | Overall security verdict |
| `validation.description` | `string` (optional) | Human-readable description |
| `validation.reason` | `string` (optional) | Reason for the verdict |
| `feeData` | `EvmTransactionFeeData` (optional) | Present only when `includeFees: true` |
| `feeData.humanReadableAmount` | `string` | Fee in ETH, formatted for display |
| `feeData.nativeAmount` | `bigint` | Fee in wei |
| `feeData.usdAmount` | `string` (optional) | Fee in USD if price data is available |
| `feeData.gasEstimate` | `bigint` | Estimated gas units |
| `priceData` | `PriceData` | Price information for the assets involved |
| `counterparties` | `string[]` (optional) | Other addresses involved in the transaction |

## Examples

### Simple ETH transfer

```javascript theme={"system"}
import { simulateEvmTransaction } from '@dynamic-labs-sdk/evm';
const result = await simulateEvmTransaction({
  walletAccount,
  transaction: {
    from: walletAccount.address,
    to: recipientAddress,
    networkId: '1',
    value: parseEther('0.5'),
  },
});

console.log('Sending:', result.outAssets);
```

### Contract call (ERC-20 transfer)

```javascript theme={"system"}
import { simulateEvmTransaction } from '@dynamic-labs-sdk/evm';
import { encodeFunctionData } from 'viem';

const result = await simulateEvmTransaction({
  walletAccount,
  transaction: {
    from: walletAccount.address,
    to: tokenContractAddress,
    networkId: '1',
    data: encodeFunctionData({
      abi: erc20Abi,
      functionName: 'transfer',
      args: [recipientAddress, parseUnits('100', 18)],
    }),
  },
});

console.log('Tokens going out:', result.outAssets);
console.log('Tokens coming in:', result.inAssets);
```

### With gas fee estimation

```javascript theme={"system"}
import { simulateEvmTransaction } from '@dynamic-labs-sdk/evm';
const result = await simulateEvmTransaction({
  walletAccount,
  transaction: {
    from: walletAccount.address,
    to: recipientAddress,
    networkId: '137', // Polygon
    value: parseEther('1'),
  },
  includeFees: true,
});

if (result.feeData) {
  console.log(`Estimated fee: ${result.feeData.humanReadableAmount} MATIC`);
  if (result.feeData.usdAmount) {
    console.log(`≈ $${result.feeData.usdAmount}`);
  }
}
```

### Security validation

```javascript theme={"system"}
import { simulateEvmTransaction } from '@dynamic-labs-sdk/evm';
const result = await simulateEvmTransaction({
  walletAccount,
  transaction: {
    from: walletAccount.address,
    to: contractAddress,
    networkId: '1',
    data: callData,
  },
});

if (result.validation?.result === 'malicious') {
  console.warn('This transaction has been flagged as malicious. Blocking.');
  return;
}

if (result.validation?.result === 'warning') {
  console.warn('Proceed with caution:', result.validation.description);
}
```

### Error handling

```javascript theme={"system"}
import { simulateEvmTransaction } from '@dynamic-labs-sdk/evm';
import { SimulationFailedError } from '@dynamic-labs-sdk/client';

try {
  const result = await simulateEvmTransaction({ walletAccount, transaction });
} catch (error) {
  if (error instanceof SimulationFailedError) {
    console.error('Simulation failed:', error.message);
  }
}
```

## Related functions

* [calculateEvmTransactionFee](https://docs.dynamic.xyz/docs/javascript/reference/evm/calculate-evm-transaction-fee.md) - Fee estimation only, without asset diffs or security validation
* [simulateSolanaTransaction](https://docs.dynamic.xyz/docs/javascript/reference/solana/simulate-solana-transaction.md) - Simulate a Solana transaction
* [simulateZerodevUserOperation](https://docs.dynamic.xyz/docs/javascript/reference/zerodev/simulate-zerodev-user-operation.md) - Simulate a ZeroDev user operation
* [sendUserOperation](https://docs.dynamic.xyz/docs/javascript/reference/zerodev/send-user-operation.md) - Send an EVM transaction via account abstraction


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.