Home/Docs/Send Transactions

Sending Transactions

Learn how to send Solana transactions using web3.js and Payload's optimized RPC network.

Required Environment Variables

Create a .env file with these variables:

RECIPIENT_ADDRESS=your_recipient_address
TIP_ADDRESS=AdVacgHPGM8aUne1ExfApBz52LcJczVJzJmhhzdEWqmh
TRANSFER_LAMPORTS=amount_in_lamports
TIP_LAMPORTS=10000  # Minimum 10,000 lamports
PAYLOAD_URL=https://api.payload.wtf
RPC_URL=your_rpc_url
SEND_MODE=quicknode  # or helius
VariableDescriptionExample
RECIPIENT_ADDRESSThe Solana address that will receive the transferred SOL7x...Xyz
TIP_ADDRESSRequired tip address for using Payload's serviceAdVacgHPGM8aUne1ExfApBz52LcJczVJzJmhhzdEWqmh
TRANSFER_LAMPORTSAmount of SOL to transfer in lamports (1 SOL = 1,000,000,000 lamports)1000000000
TIP_LAMPORTSAmount of SOL to tip in lamports (minimum 10,000 lamports)10000
PAYLOAD_URLPayload's API endpointhttps://api.payload.wtf
RPC_URLYour Solana RPC endpoint for initial connectionhttps://api.mainnet-beta.solana.com
SEND_MODEChoose between "quicknode" or "helius" RPC providersquicknode

Complete Example

Here's a complete example of sending a transaction with Payload. The code includes detailed logging and error handling:

const {
    Connection,
    PublicKey,
    Keypair,
    SystemProgram,
    Transaction,
} = require("@solana/web3.js");
const axios = require("axios");
const fs = require("fs");
require("dotenv").config();

// 1. Load environment variables
const {
    RECIPIENT_ADDRESS,
    TIP_ADDRESS,      // Required tip address
    TRANSFER_LAMPORTS,
    TIP_LAMPORTS,     // Tip amount from env
    PAYLOAD_URL,
    RPC_URL,
    SEND_MODE,        // Send mode from env
} = process.env;

const MINIMUM_TIP = 10000; // 0.00001 SOL in lamports

// 2. Load sender's keypair
const senderSecret = Uint8Array.from(JSON.parse(fs.readFileSync("./sender.json", "utf-8")));
const sender = Keypair.fromSecretKey(senderSecret);

// Create connection and get blockhash
async function sendTransaction() {
    try {
        // 3. Initialize connection and get blockhash
        const connection = new Connection(RPC_URL, {
            commitment: "confirmed",
            skipPreflight: true
        });
        const { blockhash } = await connection.getLatestBlockhash();

        // 4. Parse amounts
        const transferAmount = parseInt(TRANSFER_LAMPORTS, 10);
        const tipAmount = parseInt(TIP_LAMPORTS, 10);

        // 5. Validate minimum tip amount
        if (tipAmount < MINIMUM_TIP) {
            throw new Error(`Tip amount must be at least ${MINIMUM_TIP} lamports`);
        }

        // 6. Create main transfer instruction
        const transferIx = SystemProgram.transfer({
            fromPubkey: sender.publicKey,
            toPubkey: new PublicKey(RECIPIENT_ADDRESS),
            lamports: transferAmount,
        });

        // 7. Create tip instruction
        const tipIx = SystemProgram.transfer({
            fromPubkey: sender.publicKey,
            toPubkey: new PublicKey(TIP_ADDRESS),
            lamports: tipAmount,
        });

        // 8. Create and sign transaction
        const tx = new Transaction()
            .add(transferIx)  // Main transfer
            .add(tipIx);     // Required tip transfer
        
        tx.recentBlockhash = blockhash;
        tx.feePayer = sender.publicKey;
        tx.sign(sender);

        // Add skipPreflight to transaction
        const options = {
            skipPreflight: true
        };

        // 9. Serialize transaction to base64
        const base64Tx = tx.serialize().toString("base64");

        // 10. Log transaction details
        console.log("\n--- Transaction Details ---");
        console.log("From:", sender.publicKey.toBase58());
        console.log("To:", RECIPIENT_ADDRESS);
        console.log("Amount:", transferAmount, "lamports");
        console.log("Tip to:", TIP_ADDRESS);
        console.log("Tip amount:", tipAmount, "lamports");

        // 11. Send to payload.wtf
        console.log("\nSending to payload.wtf...");
        const res = await axios.post(`${PAYLOAD_URL}/sendTransaction`, base64Tx, {
            headers: {
                "Content-Type": "text/plain",
                "x-mode": SEND_MODE
            }
        });

        // 12. Handle response
        console.log("\nAPI Response Status:", res.status);
        console.log("API Response Data:", JSON.stringify(res.data, null, 2));

        if (res.data?.signature) {
            console.log("\n✅ Transaction submitted successfully!");
            console.log("Signature:", res.data.signature);
            console.log(`View on Solscan: https://solscan.io/tx/${res.data.signature}`);
        } else {
            console.log("\n❌ Transaction failed - no signature received");
            console.log("Full response:", res.data);
        }

    } catch (error) {
        console.error("❌ Error:", error.message);
    }
}

// 13. Execute the transaction
sendTransaction();

Step-by-Step Explanation

  1. Load Environment Variables

    Set up your configuration including recipient address, tip amount, and provider mode.

  2. Load Sender's Keypair

    Load your sender's keypair from a JSON file for transaction signing.

  3. Initialize Connection

    Create a connection to the Solana network and get the latest blockhash.

  4. Parse Amounts

    Convert string amounts to integers for the transaction.

  5. Validate Tip Amount

    Ensure the tip meets the minimum requirement of 10,000 lamports.

  6. Create Transfer Instruction

    Set up the main transfer instruction for your transaction.

  7. Create Tip Instruction

    Add the tip instruction to the transaction.

  8. Create and Sign Transaction

    Combine instructions and sign the transaction.

  9. Serialize Transaction

    Convert the transaction to base64 for API submission.

  10. Log Transaction Details

    Print transaction information for debugging.

  11. Send to Payload

    Submit the transaction to Payload's API.

  12. Handle Response

    Process and log the API response.

  13. Execute Transaction

    Run the transaction sending process.

Requirements

  • Minimum tip amount: 10,000 lamports (0.00001 SOL)
  • Valid sender keypair with sufficient SOL balance
  • Recent blockhash (within last 150 blocks)
  • Required environment variables set

Next Steps

Ready to start sending transactions? Check out our tips and best practices:

Tips & Best Practices