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
Variable | Description | Example |
---|---|---|
RECIPIENT_ADDRESS | The Solana address that will receive the transferred SOL | 7x...Xyz |
TIP_ADDRESS | Required tip address for using Payload's service | AdVacgHPGM8aUne1ExfApBz52LcJczVJzJmhhzdEWqmh |
TRANSFER_LAMPORTS | Amount of SOL to transfer in lamports (1 SOL = 1,000,000,000 lamports) | 1000000000 |
TIP_LAMPORTS | Amount of SOL to tip in lamports (minimum 10,000 lamports) | 10000 |
PAYLOAD_URL | Payload's API endpoint | https://api.payload.wtf |
RPC_URL | Your Solana RPC endpoint for initial connection | https://api.mainnet-beta.solana.com |
SEND_MODE | Choose between "quicknode" or "helius" RPC providers | quicknode |
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
- Load Environment Variables
Set up your configuration including recipient address, tip amount, and provider mode.
- Load Sender's Keypair
Load your sender's keypair from a JSON file for transaction signing.
- Initialize Connection
Create a connection to the Solana network and get the latest blockhash.
- Parse Amounts
Convert string amounts to integers for the transaction.
- Validate Tip Amount
Ensure the tip meets the minimum requirement of 10,000 lamports.
- Create Transfer Instruction
Set up the main transfer instruction for your transaction.
- Create Tip Instruction
Add the tip instruction to the transaction.
- Create and Sign Transaction
Combine instructions and sign the transaction.
- Serialize Transaction
Convert the transaction to base64 for API submission.
- Log Transaction Details
Print transaction information for debugging.
- Send to Payload
Submit the transaction to Payload's API.
- Handle Response
Process and log the API response.
- 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 →