> ## 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.

# simulateZerodevUserOperation

> Preview a ZeroDev user operation's effects before sending it

Simulates a ZeroDev user operation and returns a breakdown of expected asset changes, security
validation results, and optionally an estimated gas fee — before the operation is submitted to the
network.

Returns the same result shape as `simulateEvmTransaction`, since user operations are ultimately EVM
transactions. Powered by [Blockaid](https://blockaid.io) for security validation.

## Installation

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

## Usage

```javascript theme={"system"}
import { simulateZerodevUserOperation } from '@dynamic-labs-sdk/zerodev';
import { isEvmWalletAccount } from '@dynamic-labs-sdk/evm';
import { getPrimaryWalletAccount } from '@dynamic-labs-sdk/client';
import { parseEther, encodeFunctionData } from 'viem';

const walletAccount = getPrimaryWalletAccount();

if (walletAccount && isEvmWalletAccount(walletAccount)) {
  const result = await simulateZerodevUserOperation({
    walletAccount,
    userOperation: {
      sender: walletAccount.address,
      callData: encodeFunctionData({
        abi: erc20Abi,
        functionName: 'transfer',
        args: [recipientAddress, parseUnits('100', 18)],
      }),
    },
    networkId: '1',
    entryPoint: ENTRY_POINT_ADDRESS,
  });

  console.log('Assets going out:', result.outAssets);
  console.log('Security check:', result.validation?.result);
}
```

## Parameters

| Parameter       | Type                       | Description                                                  |
| --------------- | -------------------------- | ------------------------------------------------------------ |
| `walletAccount` | `EvmWalletAccount`         | The ZeroDev-enabled wallet account                           |
| `userOperation` | `Partial<UserOperation>`   | The user operation to simulate                               |
| `networkId`     | `string`                   | The chain ID (e.g., `'1'` for Ethereum, `'137'` for Polygon) |
| `entryPoint`    | `string`                   | The EntryPoint contract address                              |
| `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 (`0n` if the operation is sponsored) |
| `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 operation       |

<Note>
  When the operation is eligible for gas sponsorship, `feeData.nativeAmount` is `0n` — indicating the
  user will not pay gas. Use `canSponsorUserOperation` to check sponsorship eligibility before
  simulating.
</Note>

## Examples

### Token transfer

```javascript theme={"system"}
import { encodeFunctionData, parseUnits } from 'viem';

const result = await simulateZerodevUserOperation({
  walletAccount,
  userOperation: {
    sender: walletAccount.address,
    callData: encodeFunctionData({
      abi: erc20Abi,
      functionName: 'transfer',
      args: [recipientAddress, parseUnits('50', 18)],
    }),
  },
  networkId: '137',
  entryPoint: ENTRY_POINT_ADDRESS,
});

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

### With gas fee estimation

```javascript theme={"system"}
const result = await simulateZerodevUserOperation({
  walletAccount,
  userOperation: {
    sender: walletAccount.address,
    callData,
  },
  networkId: '1',
  entryPoint: ENTRY_POINT_ADDRESS,
  includeFees: true,
});

if (result.feeData) {
  if (result.feeData.nativeAmount === 0n) {
    console.log('Operation is sponsored — no gas cost');
  } else {
    console.log(`Estimated gas fee: ${result.feeData.humanReadableAmount} ETH`);
  }
}
```

### Security validation

```javascript theme={"system"}
const result = await simulateZerodevUserOperation({
  walletAccount,
  userOperation: { sender: walletAccount.address, callData },
  networkId: '1',
  entryPoint: ENTRY_POINT_ADDRESS,
});

if (result.validation?.result === 'malicious') {
  console.warn('Operation flagged as malicious. Blocking.');
  return;
}
```

### Error handling

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

try {
  const result = await simulateZerodevUserOperation({
    walletAccount,
    userOperation,
    networkId,
    entryPoint,
    includeFees: true,
  });
} catch (error) {
  if (error instanceof SimulationFailedError) {
    console.error('Simulation failed:', error.message);
  } else if (error instanceof FeeEstimationFailedError) {
    console.error('Fee estimation failed:', error.message);
  }
}
```

## Related functions

* [simulateEvmTransaction](/javascript/reference/evm/simulate-evm-transaction) - Simulate a standard EVM transaction
* [simulateSolanaTransaction](/javascript/reference/solana/simulate-solana-transaction) - Simulate a Solana transaction
* [sendUserOperation](/javascript/reference/zerodev/send-user-operation) - Send a user operation (single or batch)
* [canSponsorUserOperation](/javascript/reference/zerodev/can-sponsor-user-operation) - Check if a user operation can be sponsored
* [estimateUserOperationGas](/javascript/reference/zerodev/estimate-user-operation-gas) - Estimate gas for a user operation
