Skip to main content
Dynamic provides React hooks to simulate transactions programmatically without using the built-in UI. These hooks allow you to validate transactions before sending them to the network.

useEVMTransactionSimulation

Use this hook to simulate EVM transactions and get detailed information about the transaction’s expected outcome, including asset transfers, balance changes, and security validations.

Usage

import { useEVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';

const { simulateEVMTransaction, isLoading, error } = useEVMTransactionSimulation();

Parameters

The simulateEVMTransaction function accepts an object with the following parameters:
ParameterTypeDescription
transactionobjectThe transaction object containing from, to, data, value, etc.
typestringThe transaction type (e.g., ‘SignTransaction’)
The transaction object supports the following fields:
FieldTypeDescription
fromstringThe sender’s address
tostringThe recipient’s address
datastringThe transaction data (optional)
valuebigintThe transaction value in wei (optional)
gasstringThe gas limit (optional)
gasPricestringThe gas price in wei (optional)
Note: The chainId is automatically fetched from the wallet connector and should not be included in the parameters.

Response

The simulation returns a SimulateTransactionResponse object containing:
  • assetTransfers - Array of asset transfers that will occur
  • assetDiffs - Balance changes for each asset
  • blockaidValidation - Security validation results
  • priceData - Price information for assets involved

Example

import { useEVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import { parseEther } from 'viem';

const MyComponent = () => {
  const { primaryWallet } = useDynamicContext();
  const { simulateEVMTransaction, isLoading, error } = useEVMTransactionSimulation();

  const handleSimulate = async () => {
    if (!primaryWallet) return;

    try {
      const result = await simulateEVMTransaction({
        transaction: {
          from: primaryWallet.address,
          to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
          value: parseEther('1'), // 1 ETH
        },
        type: 'SignTransaction',
      });

      console.log('Simulation result:', result);
      console.log('Asset transfers:', result.assetTransfers);
      console.log('Security validation:', result.blockaidValidation);
    } catch (err) {
      console.error('Simulation failed:', err);
    }
  };

  return (
    <button onClick={handleSimulate} disabled={isLoading}>
      {isLoading ? 'Simulating...' : 'Simulate Transaction'}
    </button>
  );
};

Simulating contract interactions

import { useEVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';
import { encodeFunctionData, parseEther } from 'viem';

const MyComponent = () => {
  const { simulateEVMTransaction } = useEVMTransactionSimulation();

  const handleSimulateContractCall = async () => {
    const data = encodeFunctionData({
      abi: contractAbi,
      functionName: 'transfer',
      args: [recipientAddress, amount],
    });

    const result = await simulateEVMTransaction({
      transaction: {
        from: walletAddress,
        to: contractAddress,
        data,
        value: parseEther(amount),
      },
      type: 'SignTransaction',
    });

    console.log('Contract call simulation:', result);
  };

  return <button onClick={handleSimulateContractCall}>Simulate Contract Call</button>;
};

Simulating Account Abstraction transactions

For ZeroDev wallets and other account abstraction implementations, use the simulateEVMTransactionAA function:
import { useEVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';
import { parseEther } from 'viem';

const MyComponent = () => {
  const { simulateEVMTransactionAA } = useEVMTransactionSimulation();

  const handleSimulateAA = async () => {
    const result = await simulateEVMTransactionAA({
      transaction: {
        from: smartWalletAddress,
        to: recipientAddress,
        value: parseEther('0.1'),
      },
      type: 'SignTransaction',
    });

    console.log('AA simulation result:', result);
  };

  return <button onClick={handleSimulateAA}>Simulate AA Transaction</button>;
};

useSVMTransactionSimulation

Use this hook to simulate Solana (SVM) transactions and validate them before sending to the network.

Usage

import { useSVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';

const { simulateSVMTransaction, isLoading, error } = useSVMTransactionSimulation();

Parameters

The simulateSVMTransaction function accepts an object with the following parameters:
ParameterTypeDescription
transactionTransactionThe Solana Transaction object (not serialized)
typestringThe transaction type (e.g., ‘SignTransaction’)
Note: The hook accepts the Transaction object directly and handles bs58 encoding internally. Do not serialize the transaction to base64.

Response

The simulation returns a SimulateTransactionResponse object containing:
  • assetTransfers - Array of asset transfers that will occur
  • assetDiffs - Balance changes for each asset
  • blockaidValidation - Security validation results
  • priceData - Price information for assets involved

Example

import { useSVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

const MyComponent = () => {
  const { primaryWallet } = useDynamicContext();
  const { simulateSVMTransaction, isLoading, error } = useSVMTransactionSimulation();

  const handleSimulate = async () => {
    if (!primaryWallet) return;

    // Create a Solana transaction
    const solTransaction = new Transaction().add(
      SystemProgram.transfer({
        fromPubkey: new PublicKey(primaryWallet.address),
        toPubkey: new PublicKey('recipient-address'),
        lamports: 1000000000, // 1 SOL
      })
    );

    try {
      const result = await simulateSVMTransaction({
        transaction: solTransaction, // Pass Transaction object directly
        type: 'SignTransaction',
      });

      console.log('Simulation result:', result);
      console.log('Asset transfers:', result.assetTransfers);
      console.log('Security validation:', result.blockaidValidation);
    } catch (err) {
      console.error('Simulation failed:', err);
    }
  };

  return (
    <button onClick={handleSimulate} disabled={isLoading}>
      {isLoading ? 'Simulating...' : 'Simulate Transaction'}
    </button>
  );
};

Simulating versioned transactions

import { useSVMTransactionSimulation } from '@dynamic-labs/sdk-react-core';
import { VersionedTransaction, TransactionMessage, PublicKey } from '@solana/web3.js';

const MyComponent = () => {
  const { simulateSVMTransaction } = useSVMTransactionSimulation();

  const handleSimulateVersioned = async () => {
    // Create a versioned transaction
    const messageV0 = new TransactionMessage({
      payerKey: new PublicKey(walletAddress),
      recentBlockhash: blockhash,
      instructions: [instruction],
    }).compileToV0Message();

    const versionedTx = new VersionedTransaction(messageV0);

    const result = await simulateSVMTransaction({
      transaction: versionedTx, // Pass VersionedTransaction object directly
      type: 'SignTransaction',
    });

    console.log('Versioned transaction simulation:', result);
  };

  return <button onClick={handleSimulateVersioned}>Simulate Versioned Transaction</button>;
};

Error handling

Both hooks provide error states that you can use to handle simulation failures:
const { simulateEVMTransaction, isLoading, error } = useEVMTransactionSimulation();

if (error) {
  console.error('Simulation error:', error);
  // Handle error appropriately
}

Security validation

The simulation response includes security validation from Blockaid, which helps identify potentially malicious transactions:
const result = await simulateEVMTransaction({
  transaction: {
    from: walletAddress,
    to: contractAddress,
    data,
  },
  type: 'SignTransaction',
});

if (result.blockaidValidation?.result === 'malicious') {
  console.warn('Warning: This transaction may be malicious');
  console.log('Reason:', result.blockaidValidation.reason);
  // Show warning to user
}