in-solana by Supanode

sendTransaction — Solana RPC Method

sendTransaction submits a fully signed, serialized transaction to the Solana cluster. The RPC node performs a preflight simulation by default, then forwards the transaction to the current leader for inclusion in a block.

Parameters

NameTypeRequiredDescription
transactionstringYesFully signed transaction, base-58 or base-64 encoded.
encodingstringNobase58 or base64. Default: base58. Use base64 for better performance.
skipPreflightboolNoSkip preflight simulation. Default: false.
preflightCommitmentstringNoCommitment for preflight simulation. Default: finalized.
maxRetriesu64NoMaximum retries by the RPC node before giving up.
minContextSlotnumberNoMinimum slot for preflight evaluation.

Request

curl -X POST https://api.mainnet-beta.solana.com \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "sendTransaction",
    "params": [
      "4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTBU6EhdB4RD8CP2xUxr2u3d6fos36PD98XS6oX8TQjLpsMwncs5DAMiD4nNnR8NBfyghGCWvCVifVwvA8B8TJxE1aiyiv2L429BCWfyzAme5sZW8rDb14NeCQHhZbtNqfXhcp2tAnaAT",
      {"encoding": "base58"}
    ]
  }'

TypeScript (@solana/kit)

import {
  createSolanaRpc,
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstruction,
  signTransactionMessageWithSigners,
  getBase64EncodedWireTransaction,
} from "@solana/kit";

const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");

// After building and signing the transaction:
const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction);

const signature = await rpc
  .sendTransaction(encodedTransaction, {
    encoding: "base64",
    skipPreflight: false,
  })
  .send();

console.log(`Transaction sent: ${signature}`);

Response

{
  "jsonrpc": "2.0",
  "result": "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW",
  "id": 1
}
FieldTypeDescription
resultstringThe first transaction signature (base-58 encoded). Use this to track the transaction status.

A successful response means the transaction was accepted by the RPC node, not that it was confirmed on-chain. Use getSignatureStatuses to check for confirmation.

Common errors

  • Blockhash not found / expired — the blockhash has expired. Fetch a new one with getLatestBlockhash and re-sign.
  • Insufficient funds — the fee payer does not have enough SOL for the transaction fee plus the transaction cost.
  • Simulation failed — preflight simulation detected an error. The logs in the error response explain what went wrong.
  • Transaction already processed — the same transaction was already submitted and confirmed.
  • Node behind — the RPC node is behind the cluster. Try a different node or set minContextSlot.

Performance

Use base64 encoding — it is faster to decode than base58. Setting skipPreflight: true saves one simulation round but means errors are only caught after the transaction lands (or fails) on-chain. For time-sensitive transactions (arbitrage, liquidations), skipping preflight and sending to multiple RPC endpoints can reduce latency.

The RPC node automatically retries forwarding the transaction to the leader. The maxRetries parameter controls this. For critical transactions, implement your own retry logic: re-send the same signed transaction until either the signature appears on-chain or the blockhash expires.

FAQ

Does a successful response mean the transaction is confirmed? No. The response only means the RPC node accepted the transaction. The transaction can still fail during execution or be dropped. Always check with getSignatureStatuses.

Should I skip preflight? For most applications, keep preflight enabled — it catches errors early. Skip it only when latency matters more than early error detection (e.g., trading bots, liquidation keepers).

How do I handle blockhash expiry? Fetch a blockhash with getLatestBlockhash, note the lastValidBlockHeight, and if the transaction has not confirmed by that block height, rebuild and re-sign with a fresh blockhash.

Why does my transaction keep getting dropped? Common causes: insufficient priority fee during congestion, expired blockhash, or the leader did not receive the transaction. Increase the priority fee and retry from multiple RPC nodes.

What encoding should I use? Use base64. It is more efficient than base58 for serialization and deserialization.

Parameters

ParameterTypeRequiredDescriptionDefault
transactionstringYesFully signed transaction as a base-58 or base-64 encoded string.—
encodingstringNoEncoding of the transaction data: base58 or base64.base58
skipPreflightboolNoSkip preflight transaction simulation.false
preflightCommitmentstringNoCommitment level for the preflight simulation.finalized
maxRetriesu64NoMaximum number of times the RPC node retries sending the transaction to the leader.—
minContextSlotnumberNoMinimum slot at which the preflight can be evaluated.—

Updated: