Skip to main content
Glama

simulate_transaction

Simulate blockchain transactions to preview policy tier, estimated fees, balance changes, and warnings before execution. Test transfers, token operations, contract calls, approvals, or batches without side effects.

Instructions

Simulate a transaction without executing it. Returns policy tier, estimated fees, balance changes, and warnings. No side effects.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toYesDestination address
amountYesAmount in smallest units (wei for EVM, lamports for Solana). Example: "1000000000000000000" = 1 ETH
typeNoTransaction type. Default: TRANSFER
tokenNoRequired for TOKEN_TRANSFER
calldataNoHex-encoded calldata (EVM)
abiNoABI fragment (EVM)
valueNoNative token value in smallest units (wei for EVM). Example: "1000000000000000000" = 1 ETH
programIdNoSolana program ID
instructionDataNoBase64-encoded instruction data (Solana)
accountsNoSolana accounts
spenderNoSpender address (APPROVE type)
instructionsNoBatch instructions array
networkNoTarget network (e.g., "polygon-mainnet" or CAIP-2 "eip155:137").
wallet_idNoWallet ID for multi-wallet sessions
gas_conditionNoGas price condition (included for request compatibility, ignored by simulation)

Implementation Reference

  • The handler function within the `simulate_transaction` MCP tool, which prepares the transaction data and calls the /v1/transactions/simulate API endpoint.
    async (args) => {
      const body: Record<string, unknown> = { to: args.to, amount: args.amount };
      if (args.type) body.type = args.type;
      if (args.token) body.token = args.token;
      if (args.calldata !== undefined) body.calldata = args.calldata;
      if (args.abi !== undefined) body.abi = args.abi;
      if (args.value !== undefined) body.value = args.value;
      if (args.programId !== undefined) body.programId = args.programId;
      if (args.instructionData !== undefined) body.instructionData = args.instructionData;
      if (args.accounts !== undefined) body.accounts = args.accounts;
      if (args.spender !== undefined) body.spender = args.spender;
      if (args.instructions !== undefined) body.instructions = args.instructions;
      if (args.network !== undefined) body.network = args.network;
      if (args.wallet_id) body.walletId = args.wallet_id;
      if (args.gas_condition) {
        body.gasCondition = {
          maxGasPrice: args.gas_condition.max_gas_price,
          maxPriorityFee: args.gas_condition.max_priority_fee,
          timeout: args.gas_condition.timeout,
        };
      }
      const result = await apiClient.post('/v1/transactions/simulate', body);
      return toToolResult(result);
    },
  • The `registerSimulateTransaction` function registers the 'simulate_transaction' tool with the MCP server.
    export function registerSimulateTransaction(server: McpServer, apiClient: ApiClient, walletContext?: WalletContext): void {
      server.tool(
        'simulate_transaction',
        withWalletPrefix('Simulate a transaction without executing it. Returns policy tier, estimated fees, balance changes, and warnings. No side effects.', walletContext?.walletName),
        {
          to: z.string().describe('Destination address'),
          amount: z.string().describe('Amount in smallest units (wei for EVM, lamports for Solana). Example: "1000000000000000000" = 1 ETH'),
          type: z.enum(['TRANSFER', 'TOKEN_TRANSFER', 'CONTRACT_CALL', 'APPROVE', 'BATCH']).optional()
            .describe('Transaction type. Default: TRANSFER'),
          token: z.object({
            address: z.string().describe('Token mint/contract address'),
            decimals: z.number().describe('Token decimals'),
            symbol: z.string().describe('Token symbol'),
            assetId: z.string().optional().describe('CAIP-19 asset identifier'),
          }).optional().describe('Required for TOKEN_TRANSFER'),
          // CONTRACT_CALL fields
          calldata: z.string().optional().describe('Hex-encoded calldata (EVM)'),
          abi: z.array(z.record(z.unknown())).optional().describe('ABI fragment (EVM)'),
          value: z.string().optional().describe('Native token value in smallest units (wei for EVM). Example: "1000000000000000000" = 1 ETH'),
          programId: z.string().optional().describe('Solana program ID'),
          instructionData: z.string().optional().describe('Base64-encoded instruction data (Solana)'),
          accounts: z.array(z.object({
            pubkey: z.string(),
            isSigner: z.boolean(),
            isWritable: z.boolean(),
          })).optional().describe('Solana accounts'),
          // APPROVE fields
          spender: z.string().optional().describe('Spender address (APPROVE type)'),
          // BATCH fields
          instructions: z.array(z.record(z.unknown())).optional().describe('Batch instructions array'),
          // Common fields
          network: z.string().optional().describe('Target network (e.g., "polygon-mainnet" or CAIP-2 "eip155:137").'),
          wallet_id: z.string().optional().describe('Wallet ID for multi-wallet sessions'),
          gas_condition: z.object({
            max_gas_price: z.string().optional(),
            max_priority_fee: z.string().optional(),
            timeout: z.number().optional(),
          }).optional().describe('Gas price condition (included for request compatibility, ignored by simulation)'),
        },
        async (args) => {
          const body: Record<string, unknown> = { to: args.to, amount: args.amount };
          if (args.type) body.type = args.type;
          if (args.token) body.token = args.token;
          if (args.calldata !== undefined) body.calldata = args.calldata;
          if (args.abi !== undefined) body.abi = args.abi;
          if (args.value !== undefined) body.value = args.value;
          if (args.programId !== undefined) body.programId = args.programId;
          if (args.instructionData !== undefined) body.instructionData = args.instructionData;
          if (args.accounts !== undefined) body.accounts = args.accounts;
          if (args.spender !== undefined) body.spender = args.spender;
          if (args.instructions !== undefined) body.instructions = args.instructions;
          if (args.network !== undefined) body.network = args.network;
          if (args.wallet_id) body.walletId = args.wallet_id;
          if (args.gas_condition) {
            body.gasCondition = {
              maxGasPrice: args.gas_condition.max_gas_price,
              maxPriorityFee: args.gas_condition.max_priority_fee,
              timeout: args.gas_condition.timeout,
            };
          }
          const result = await apiClient.post('/v1/transactions/simulate', body);
          return toToolResult(result);
        },
      );
    }
  • Zod schema definition for the input arguments of the `simulate_transaction` MCP tool.
    {
      to: z.string().describe('Destination address'),
      amount: z.string().describe('Amount in smallest units (wei for EVM, lamports for Solana). Example: "1000000000000000000" = 1 ETH'),
      type: z.enum(['TRANSFER', 'TOKEN_TRANSFER', 'CONTRACT_CALL', 'APPROVE', 'BATCH']).optional()
        .describe('Transaction type. Default: TRANSFER'),
      token: z.object({
        address: z.string().describe('Token mint/contract address'),
        decimals: z.number().describe('Token decimals'),
        symbol: z.string().describe('Token symbol'),
        assetId: z.string().optional().describe('CAIP-19 asset identifier'),
      }).optional().describe('Required for TOKEN_TRANSFER'),
      // CONTRACT_CALL fields
      calldata: z.string().optional().describe('Hex-encoded calldata (EVM)'),
      abi: z.array(z.record(z.unknown())).optional().describe('ABI fragment (EVM)'),
      value: z.string().optional().describe('Native token value in smallest units (wei for EVM). Example: "1000000000000000000" = 1 ETH'),
      programId: z.string().optional().describe('Solana program ID'),
      instructionData: z.string().optional().describe('Base64-encoded instruction data (Solana)'),
      accounts: z.array(z.object({
        pubkey: z.string(),
        isSigner: z.boolean(),
        isWritable: z.boolean(),
      })).optional().describe('Solana accounts'),
      // APPROVE fields
      spender: z.string().optional().describe('Spender address (APPROVE type)'),
      // BATCH fields
      instructions: z.array(z.record(z.unknown())).optional().describe('Batch instructions array'),
      // Common fields
      network: z.string().optional().describe('Target network (e.g., "polygon-mainnet" or CAIP-2 "eip155:137").'),
      wallet_id: z.string().optional().describe('Wallet ID for multi-wallet sessions'),
      gas_condition: z.object({
        max_gas_price: z.string().optional(),
        max_priority_fee: z.string().optional(),
        timeout: z.number().optional(),
      }).optional().describe('Gas price condition (included for request compatibility, ignored by simulation)'),
    },

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/minhoyoo-iotrust/WAIaaS'

If you have feedback or need assistance with the MCP directory API, please join our Discord server