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

# sendTransaction

> Submits a signed transaction to the cluster for processing

## Parameters

<ResponseField name="transaction" type="string" required>
  Fully-signed transaction as a base-64 encoded string
</ResponseField>

<ResponseField name="config" type="object" optional>
  Configuration object containing:

  <ResponseField name="encoding" type="string" optional>
    Encoding format for the transaction (base58, base64, json)
  </ResponseField>

  <ResponseField name="commitment" type="string" optional>
    Commitment level (processed, confirmed, finalized)
  </ResponseField>

  <ResponseField name="preflightCommitment" type="string" optional>
    Commitment level for preflight (processed, confirmed, finalized)
  </ResponseField>

  <ResponseField name="skipPreflight" type="boolean" optional>
    If true, skip the preflight transaction checks
  </ResponseField>

  <ResponseField name="maxRetries" type="number" optional>
    Maximum number of times for the RPC node to retry sending the transaction to the leader
  </ResponseField>

  <ResponseField name="minContextSlot" type="number" optional>
    The minimum slot that the request can be evaluated at
  </ResponseField>
</ResponseField>

## Response

<ResponseField name="result" type="string">
  First transaction signature embedded in the transaction (base-58 encoded)
</ResponseField>

## Code Examples

### Basic Request

```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": "sendTransaction",
  "params": [
    "4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTFNhyKNMr3WNFCrXgDS7uV7u",
    {
      "encoding": "base64",
      "commitment": "confirmed"
    }
  ]
}'
```

### Using 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 send transaction
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey('83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri'),
    toPubkey: new PublicKey('J7rBdM6AecPDEZp8aPq5tPmsPzPhQG4HD6YtAcQBDfJj'),
    lamports: 1000000000
  })
);

const signature = await connection.sendTransaction(transaction, [signer]);
console.log('Transaction signature:', signature);

// Send transaction with confirmation
async function sendTransactionWithConfirmation(
  transaction: Transaction,
  signers: Array<Signer>,
  config: { 
    commitment?: string;
    preflightCommitment?: string;
    skipPreflight?: boolean;
    maxRetries?: number;
  }
) {
  const signature = await connection.sendTransaction(
    transaction,
    signers,
    config
  );
  
  // Wait for confirmation
  const confirmation = await connection.confirmTransaction(signature, config.commitment);
  
  return {
    signature,
    confirmation: {
      status: confirmation.value.err ? 'failed' : 'success',
      slot: confirmation.context.slot
    },
    transaction: {
      recentBlockhash: transaction.recentBlockhash,
      feePayer: transaction.feePayer?.toBase58(),
      instructions: transaction.instructions.length
    },
    metadata: {
      timestamp: Date.now(),
      commitment: config.commitment
    }
  };
}
```

## Notes

1. Submits a signed transaction to the cluster
2. The transaction must be fully signed
3. The response is the transaction signature
4. The transaction must be confirmed before changes are applied
5. The transaction must include a recent blockhash

## Best Practices

1. Use appropriate commitment level based on your needs
2. Wait for transaction confirmation before proceeding
3. Handle rate limits and network errors
4. Monitor transaction status for failures
5. Consider using preflight checks for validation

## Common Errors

| Code   | Message                                   | Solution                                         |
| ------ | ----------------------------------------- | ------------------------------------------------ |
| -32601 | Method not found                          | Verify you're connected to a Solana RPC node     |
| -32602 | Invalid params                            | Check transaction format and encoding            |
| -32003 | Transaction simulation failed             | Verify transaction validity and account balances |
| -32004 | Blockhash not found                       | Use a more recent blockhash                      |
| -32005 | Node is behind                            | Try a different RPC node                         |
| -32006 | Transaction already processed             | Transaction was already submitted                |
| -32007 | Transaction signature verification failed | Check transaction signatures                     |

## Use Cases

1. **Transaction Management**
   ```typescript theme={null}
   interface TransactionRequest {
     transaction: {
       signature: string;
       blockhash: string;
       feePayer: string;
       instructions: number;
     };
     status: {
       state: 'pending' | 'success' | 'failed';
       confirmations: number;
       slot?: number;
       error?: string;
     };
     metadata: {
       timestamp: number;
       commitment?: string;
       retries: number;
     };
   }

   class TransactionManager {
     private readonly maxRetries = 3;
     private readonly confirmationTimeout = 30000; // 30 seconds
     
     async sendTransaction(
       transaction: Transaction,
       signers: Array<Signer>,
       config: { 
         commitment?: string;
         preflightCommitment?: string;
         skipPreflight?: boolean;
       }
     ): Promise<TransactionRequest> {
       let retries = 0;
       let signature: string;
       
       while (retries < this.maxRetries) {
         try {
           // Get a new blockhash if retrying
           if (retries > 0) {
             const { blockhash } = await connection.getRecentBlockhash();
             transaction.recentBlockhash = blockhash;
           }
           
           signature = await connection.sendTransaction(
             transaction,
             signers,
             config
           );
           
           // Wait for confirmation
           const confirmation = await connection.confirmTransaction(signature, config.commitment);
           
           if (!confirmation.value.err) {
             return {
               transaction: {
                 signature,
                 blockhash: transaction.recentBlockhash,
                 feePayer: transaction.feePayer?.toBase58(),
                 instructions: transaction.instructions.length
               },
               status: {
                 state: 'success',
                 confirmations: 1,
                 slot: confirmation.context.slot
               },
               metadata: {
                 timestamp: Date.now(),
                 commitment: config.commitment,
                 retries
               }
             };
           }
           
           throw new Error(confirmation.value.err.toString());
         } catch (error) {
           retries++;
           if (retries === this.maxRetries) {
             return {
               transaction: {
                 signature,
                 blockhash: transaction.recentBlockhash,
                 feePayer: transaction.feePayer?.toBase58(),
                 instructions: transaction.instructions.length
               },
               status: {
                 state: 'failed',
                 confirmations: 0,
                 error: error.message
               },
               metadata: {
                 timestamp: Date.now(),
                 commitment: config.commitment,
                 retries
               }
             };
           }
           await new Promise(resolve => setTimeout(resolve, 1000));
         }
       }
     }
   }
   ```

2. **Transaction Monitoring**
   ```typescript theme={null}
   interface TransactionStatus {
     transaction: {
       signature: string;
       slot?: number;
     };
     status: {
       confirmations: number;
       err: any;
     };
     history: Array<{
       timestamp: number;
       confirmations: number;
       error?: string;
     }>;
   }

   class TransactionMonitor {
     private transactions: Map<string, TransactionStatus> = new Map();
     
     async monitorTransaction(
       signature: string
     ): Promise<TransactionStatus> {
       let status = this.transactions.get(signature);
       const now = Date.now();
       
       const confirmation = await connection.getSignatureStatus(signature);
       
       if (!status) {
         status = {
           transaction: {
             signature,
             slot: confirmation?.slot
           },
           status: {
             confirmations: confirmation?.confirmations || 0,
             err: confirmation?.err
           },
           history: [{
             timestamp: now,
             confirmations: confirmation?.confirmations || 0,
             error: confirmation?.err?.toString()
           }]
         };
       } else {
         status.status.confirmations = confirmation?.confirmations || 0;
         status.status.err = confirmation?.err;
         status.history.push({
           timestamp: now,
           confirmations: confirmation?.confirmations || 0,
           error: confirmation?.err?.toString()
         });
       }
       
       this.transactions.set(signature, status);
       return status;
     }
   }
   ```

3. **Transaction Planning**
   ```typescript theme={null}
   interface TransactionPlan {
     transaction: {
       instructions: number;
       signers: number;
       estimatedFee: number;
     };
     recommendations: Array<{
       type: 'proceed' | 'split' | 'abort';
       reason: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class TransactionPlanner {
     private readonly maxInstructions = 10;
     private readonly maxSigners = 8;
     
     async planTransaction(
       transaction: Transaction
     ): Promise<TransactionPlan> {
       const { feeCalculator } = await connection.getRecentBlockhash();
       const estimatedFee = feeCalculator.lamportsPerSignature * transaction.signatures.length;
       
       const recommendations: Array<{
         type: 'proceed' | 'split' | 'abort';
         reason: string;
       }> = [];
       
       if (transaction.instructions.length > this.maxInstructions) {
         recommendations.push({
           type: 'split',
           reason: `Transaction has ${transaction.instructions.length} instructions, exceeding maximum of ${this.maxInstructions}`
         });
       }
       
       if (transaction.signatures.length > this.maxSigners) {
         recommendations.push({
           type: 'split',
           reason: `Transaction has ${transaction.signatures.length} signers, exceeding maximum of ${this.maxSigners}`
         });
       }
       
       if (recommendations.length === 0) {
         recommendations.push({
           type: 'proceed',
           reason: 'Transaction is within limits'
         });
       }
       
       return {
         transaction: {
           instructions: transaction.instructions.length,
           signers: transaction.signatures.length,
           estimatedFee
         },
         recommendations,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
     
     async splitTransaction(
       transaction: Transaction
     ): Promise<Array<{
       transaction: Transaction;
       signers: Array<PublicKey>;
     }>> {
       const chunks: Array<{
         transaction: Transaction;
         signers: Array<PublicKey>;
       }> = [];
       
       let currentChunk = new Transaction();
       let currentSigners: Array<PublicKey> = [];
       
       for (let i = 0; i < transaction.instructions.length; i++) {
         const instruction = transaction.instructions[i];
         
         if (currentChunk.instructions.length >= this.maxInstructions) {
           chunks.push({
             transaction: currentChunk,
             signers: currentSigners
           });
           
           currentChunk = new Transaction();
           currentSigners = [];
         }
         
         currentChunk.add(instruction);
         
         // Add unique signers
         instruction.keys
           .filter(key => key.isSigner)
           .forEach(key => {
             if (!currentSigners.find(signer => signer.equals(key.pubkey))) {
               currentSigners.push(key.pubkey);
             }
           });
       }
       
       if (currentChunk.instructions.length > 0) {
         chunks.push({
           transaction: currentChunk,
           signers: currentSigners
         });
       }
       
       return chunks;
     }
   }
   ```
