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

# simulateTransaction

> Симулирует отправку транзакции

## Параметры

<ResponseField name="transaction" type="string" required>
  Транзакция для симуляции в виде строки в кодировке base-64
</ResponseField>

<ResponseField name="config" type="object" optional>
  Объект конфигурации, содержащий:

  <ResponseField name="sigVerify" type="boolean" optional>
    Если true, проверить подписи транзакции
  </ResponseField>

  <ResponseField name="commitment" type="string" optional>
    Уровень подтверждения (processed, confirmed, finalized)
  </ResponseField>

  <ResponseField name="encoding" type="string" optional>
    Формат кодирования транзакции (base58, base64, json)
  </ResponseField>

  <ResponseField name="replaceRecentBlockhash" type="boolean" optional>
    Если true, заменить недавний blockhash транзакции наиболее актуальным blockhash
  </ResponseField>

  <ResponseField name="accounts" type="object" optional>
    Объект конфигурации счетов, содержащий:

    <ResponseField name="encoding" type="string" optional>
      Формат кодирования данных счета (base58, base64, json)
    </ResponseField>

    <ResponseField name="addresses" type="array" optional>
      Массив адресов счетов, для которых нужно вернуть данные
    </ResponseField>
  </ResponseField>

  <ResponseField name="minContextSlot" type="number" optional>
    Минимальный слот, при котором может быть оценён запрос
  </ResponseField>
</ResponseField>

## Ответ

<ResponseField name="result" type="object">
  Объект, содержащий:

  <ResponseField name="err" type="string | null">
    Ошибка, если симуляция транзакции не удалась, null если симуляция прошла успешно
  </ResponseField>

  <ResponseField name="logs" type="array">
    Массив сообщений журнала, выводимых инструкциями транзакции во время выполнения
  </ResponseField>

  <ResponseField name="accounts" type="array" optional>
    Массив счетов с их данными (если запрошено)
  </ResponseField>

  <ResponseField name="unitsConsumed" type="number" optional>
    Количество вычислительных единиц, потреблённых транзакцией
  </ResponseField>

  <ResponseField name="returnData" type="object" optional>
    Возвращаемые данные программы из симуляции
  </ResponseField>
</ResponseField>

## Примеры кода

### Базовый запрос

```bash theme={null}
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "simulateTransaction",
  "params": [
    "4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTFNhyKNMr3WNFCrXgDS7uV7u",
    {
      "sigVerify": false,
      "commitment": "confirmed",
      "encoding": "base64"
    }
  ]
}'
```

### Использование web3.js

```typescript theme={null}
import { Connection, Transaction, PublicKey, SystemProgram } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

// Create and simulate transaction
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey('83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri'),
    toPubkey: new PublicKey('J7rBdM6AecPDEZp8aPq5tPmsPzPhQG4HD6YtAcQBDfJj'),
    lamports: 1000000000
  })
);

const simulation = await connection.simulateTransaction(transaction);
console.log('Simulation result:', simulation);

// Simulate transaction with analysis
async function simulateTransactionWithAnalysis(
  transaction: Transaction,
  config: { 
    sigVerify?: boolean;
    commitment?: string;
    replaceRecentBlockhash?: boolean;
  }
) {
  const simulation = await connection.simulateTransaction(transaction, config);
  
  return {
    simulation: {
      success: !simulation.value.err,
      error: simulation.value.err,
      logs: simulation.value.logs,
      unitsConsumed: simulation.value.unitsConsumed
    },
    transaction: {
      recentBlockhash: transaction.recentBlockhash,
      feePayer: transaction.feePayer?.toBase58(),
      instructions: transaction.instructions.length
    },
    metadata: {
      timestamp: Date.now(),
      commitment: config.commitment
    }
  };
}
```

## Примечания

1. Симулирует отправку транзакции без фактической её отправки
2. Ответ содержит журналы выполнения и ошибки
3. Симуляция выполняется на текущем состоянии
4. Изменения состояния не сохраняются
5. Полезно для тестирования и отладки транзакций

## Рекомендации

1. Используйте симуляцию перед отправкой реальных транзакций
2. Проверяйте потребление вычислительных единиц
3. Анализируйте журналы программы на предмет ошибок
4. Проверяйте состояния счетов после симуляции
5. Обрабатывайте ошибки симуляции должным образом

## Распространённые ошибки

| Код    | Сообщение                     | Решение                                            |
| ------ | ----------------------------- | -------------------------------------------------- |
| -32601 | Method not found              | Убедитесь, что вы подключены к узлу Solana RPC     |
| -32602 | Invalid params                | Проверьте формат транзакции и кодирование          |
| -32003 | Transaction simulation failed | Проверьте корректность транзакции и балансы счетов |
| -32004 | Blockhash not found           | Используйте более актуальный blockhash             |
| -32005 | Node is behind                | Попробуйте другой узел RPC                         |

## Сценарии использования

1. **Анализ транзакций**
   ```typescript theme={null}
   interface TransactionAnalysis {
     transaction: {
       instructions: number;
       signers: number;
       estimatedUnits: number;
     };
     simulation: {
       success: boolean;
       error: string | null;
       logs: string[];
       unitsConsumed: number;
     };
     analysis: {
       programInvocations: number;
       accountAccesses: number;
       errorAnalysis?: string;
     };
     metadata: {
       timestamp: number;
       commitment?: string;
     };
   }

   class TransactionAnalyzer {
     async analyzeTransaction(
       transaction: Transaction,
       config: { 
         sigVerify?: boolean;
         commitment?: string;
       }
     ): Promise<TransactionAnalysis> {
       const simulation = await connection.simulateTransaction(transaction, config);
       
       const logs = simulation.value.logs || [];
       const programInvocations = logs.filter(log => 
         log.includes('Program') && log.includes('invoke')
       ).length;
       
       const accountAccesses = logs.filter(log =>
         log.includes('Account') || log.includes('Token')
       ).length;
       
       let errorAnalysis;
       if (simulation.value.err) {
         errorAnalysis = this.analyzeError(simulation.value.err);
       }
       
       return {
         transaction: {
           instructions: transaction.instructions.length,
           signers: transaction.signatures.length,
           estimatedUnits: simulation.value.unitsConsumed || 0
         },
         simulation: {
           success: !simulation.value.err,
           error: simulation.value.err,
           logs,
           unitsConsumed: simulation.value.unitsConsumed || 0
         },
         analysis: {
           programInvocations,
           accountAccesses,
           errorAnalysis
         },
         metadata: {
           timestamp: Date.now(),
           commitment: config.commitment
         }
       };
     }
     
     private analyzeError(error: any): string {
       if (typeof error === 'string') {
         if (error.includes('insufficient funds')) {
           return 'Transaction failed due to insufficient funds';
         }
         if (error.includes('invalid account owner')) {
           return 'Transaction failed due to invalid account ownership';
         }
         if (error.includes('account not found')) {
           return 'Transaction failed due to missing account';
         }
       }
       return 'Unknown error occurred during simulation';
     }
   }
   ```

2. **Валидация транзакций**
   ```typescript theme={null}
   interface TransactionValidation {
     transaction: {
       signature: string;
       blockhash: string;
       feePayer: string;
     };
     checks: Array<{
       name: string;
       passed: boolean;
       details?: string;
     }>;
     recommendations: Array<{
       type: 'fix' | 'warning' | 'info';
       message: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class TransactionValidator {
     private readonly maxUnits = 200000;
     private readonly minAccountRent = 890880;
     
     async validateTransaction(
       transaction: Transaction,
       config: { 
         sigVerify?: boolean;
         commitment?: string;
       }
     ): Promise<TransactionValidation> {
       const simulation = await connection.simulateTransaction(transaction, config);
       
       const checks: Array<{
         name: string;
         passed: boolean;
         details?: string;
       }> = [];
       
       const recommendations: Array<{
         type: 'fix' | 'warning' | 'info';
         message: string;
       }> = [];
       
       // Check compute units
       const unitsConsumed = simulation.value.unitsConsumed || 0;
       checks.push({
         name: 'Compute Units',
         passed: unitsConsumed <= this.maxUnits,
         details: `${unitsConsumed} units consumed`
       });
       
       if (unitsConsumed > this.maxUnits) {
         recommendations.push({
           type: 'fix',
           message: 'Transaction exceeds compute unit limit'
         });
       }
       
       // Check for errors
       checks.push({
         name: 'Simulation',
         passed: !simulation.value.err,
         details: simulation.value.err?.toString()
       });
       
       if (simulation.value.err) {
         recommendations.push({
           type: 'fix',
           message: `Fix simulation error: ${simulation.value.err}`
         });
       }
       
       // Analyze logs
       const logs = simulation.value.logs || [];
       checks.push({
         name: 'Program Execution',
         passed: logs.some(log => log.includes('Program log:')),
         details: 'Program execution logs present'
       });
       
       // Check account rent
       const rentWarnings = logs.filter(log => 
         log.includes('insufficient lamports for rent')
       );
       
       if (rentWarnings.length > 0) {
         checks.push({
           name: 'Account Rent',
           passed: false,
           details: 'Insufficient lamports for rent'
         });
         
         recommendations.push({
           type: 'fix',
           message: `Ensure accounts have minimum rent: ${this.minAccountRent} lamports`
         });
       }
       
       return {
         transaction: {
           signature: transaction.signatures[0]?.signature?.toString() || '',
           blockhash: transaction.recentBlockhash || '',
           feePayer: transaction.feePayer?.toBase58() || ''
         },
         checks,
         recommendations,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
   }
   ```

3. **Оптимизация транзакций**
   ```typescript theme={null}
   interface TransactionOptimization {
     original: {
       instructions: number;
       unitsConsumed: number;
     };
     optimized: {
       instructions: number;
       unitsConsumed: number;
       savings: number;
     };
     changes: Array<{
       type: 'merge' | 'remove' | 'reorder';
       description: string;
       impact: number;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class TransactionOptimizer {
     async optimizeTransaction(
       transaction: Transaction
     ): Promise<TransactionOptimization> {
       // Simulate original transaction
       const originalSimulation = await connection.simulateTransaction(transaction);
       const originalUnits = originalSimulation.value.unitsConsumed || 0;
       
       const changes: Array<{
         type: 'merge' | 'remove' | 'reorder';
         description: string;
         impact: number;
       }> = [];
       
       // Create optimized transaction
       const optimizedTransaction = new Transaction();
       const instructions = [...transaction.instructions];
       
       // Analyze and merge similar instructions
       const mergedInstructions = this.mergeInstructions(instructions);
       if (mergedInstructions.length < instructions.length) {
         changes.push({
           type: 'merge',
           description: `Merged ${instructions.length - mergedInstructions.length} similar instructions`,
           impact: 0 // Will be updated after simulation
         });
       }
       
       // Remove redundant instructions
       const cleanedInstructions = this.removeRedundantInstructions(mergedInstructions);
       if (cleanedInstructions.length < mergedInstructions.length) {
         changes.push({
           type: 'remove',
           description: `Removed ${mergedInstructions.length - cleanedInstructions.length} redundant instructions`,
           impact: 0
         });
       }
       
       // Reorder instructions for optimal execution
       const orderedInstructions = this.reorderInstructions(cleanedInstructions);
       changes.push({
         type: 'reorder',
         description: 'Reordered instructions for optimal execution',
         impact: 0
       });
       
       // Add optimized instructions
       orderedInstructions.forEach(instruction => {
         optimizedTransaction.add(instruction);
       });
       
       // Simulate optimized transaction
       const optimizedSimulation = await connection.simulateTransaction(optimizedTransaction);
       const optimizedUnits = optimizedSimulation.value.unitsConsumed || 0;
       
       // Calculate impacts
       const totalSavings = originalUnits - optimizedUnits;
       changes.forEach(change => {
         change.impact = Math.floor(totalSavings / changes.length);
       });
       
       return {
         original: {
           instructions: instructions.length,
           unitsConsumed: originalUnits
         },
         optimized: {
           instructions: orderedInstructions.length,
           unitsConsumed: optimizedUnits,
           savings: totalSavings
         },
         changes,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
     
     private mergeInstructions(
       instructions: Array<any>
     ): Array<any> {
       // Implementation would analyze and merge similar instructions
       // This is a placeholder that returns the original instructions
       return instructions;
     }
     
     private removeRedundantInstructions(
       instructions: Array<any>
     ): Array<any> {
       // Implementation would identify and remove redundant instructions
       // This is a placeholder that returns the original instructions
       return instructions;
     }
     
     private reorderInstructions(
       instructions: Array<any>
     ): Array<any> {
       // Implementation would reorder instructions for optimal execution
       // This is a placeholder that returns the original instructions
       return instructions;
     }
   }
   ```
