Skip to content

Instantly share code, notes, and snippets.

@ngundotra
Created July 24, 2025 19:40
Show Gist options
  • Save ngundotra/91ed675009b36eb7ea1aa333d9a16b1d to your computer and use it in GitHub Desktop.
Save ngundotra/91ed675009b36eb7ea1aa333d9a16b1d to your computer and use it in GitHub Desktop.
Solana Transfer Test (Priority Fee)
import {
Connection,
Keypair,
PublicKey,
Transaction,
ComputeBudgetProgram,
sendAndConfirmTransaction,
VersionedTransaction,
TransactionMessage
} from '@solana/web3.js';
import {
createTransferInstruction,
getAssociatedTokenAddress,
getAccount,
TOKEN_PROGRAM_ID
} from '@solana/spl-token';
import fs from 'fs';
import path from 'path';
import os from 'os';
const USDC_MINT_MAINNET = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
const USDC_DECIMALS = 6;
const BASE_TRANSFER_AMOUNT = 0.001; // 0.001 USDC base amount
const TRANSACTIONS_PER_PRIORITY = 10;
interface TransferResult {
signature: string;
priorityFee: number;
landed: boolean;
error?: string;
timestamp: number;
amount: number;
confirmationTime?: number;
}
interface PriorityStats {
priorityFee: number;
sent: number;
landed: number;
landingRate: number;
avgConfirmationTime: number;
}
async function loadKeypair(): Promise<Keypair> {
const keypairPath = path.join(os.homedir(), '.config', 'solana', 'id.json');
const keypairData = JSON.parse(fs.readFileSync(keypairPath, 'utf-8'));
return Keypair.fromSecretKey(new Uint8Array(keypairData));
}
async function createTransferTransaction(
connection: Connection,
payer: Keypair,
sourceAta: PublicKey,
destinationAta: PublicKey,
priorityFeePerCu: number,
transferAmount: number
): Promise<Transaction> {
const transaction = new Transaction();
// Add compute budget instructions if priority fee > 0
if (priorityFeePerCu > 0) {
transaction.add(
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: priorityFeePerCu
})
);
transaction.add(
ComputeBudgetProgram.setComputeUnitLimit({
units: 7000
})
);
}
// Add transfer instruction
transaction.add(
createTransferInstruction(
sourceAta,
destinationAta,
payer.publicKey,
Math.floor(transferAmount * Math.pow(10, USDC_DECIMALS)),
[],
TOKEN_PROGRAM_ID
)
);
// Get recent blockhash
const { blockhash } = await connection.getLatestBlockhash();
transaction.recentBlockhash = blockhash;
transaction.feePayer = payer.publicKey;
return transaction;
}
async function sendTransactionAsync(
connection: Connection,
transaction: Transaction,
payer: Keypair,
priorityFee: number,
transferAmount: number
): Promise<TransferResult> {
const startTime = Date.now();
try {
// Sign and send the transaction
transaction.sign(payer);
const signature = await connection.sendRawTransaction(transaction.serialize(), {
skipPreflight: false,
preflightCommitment: 'processed'
});
// Wait for confirmation
const confirmation = await connection.confirmTransaction(signature, 'confirmed');
const confirmationTime = Date.now() - startTime;
if (confirmation.value.err) {
return {
signature,
priorityFee,
landed: false,
error: JSON.stringify(confirmation.value.err),
timestamp: Date.now(),
amount: transferAmount
};
}
return {
signature,
priorityFee,
landed: true,
timestamp: Date.now(),
amount: transferAmount,
confirmationTime
};
} catch (error: any) {
return {
signature: '',
priorityFee,
landed: false,
error: error.message || 'Unknown error',
timestamp: Date.now(),
amount: transferAmount
};
}
}
async function main() {
console.log('πŸš€ Starting USDC transfer comparison with different priority fees...');
console.log('πŸ“Š Testing 0 vs 500 vs 1000 microlamports/CU with simultaneous sends\n');
const connection = new Connection('https://api.mainnet-beta.solana.com/6da7c9d2-7d3d-4f7f-8302-97f5fadb58a8', 'confirmed');
const payer = await loadKeypair();
console.log(`Wallet: ${payer.publicKey.toBase58()}`);
// Get token accounts
const sourceAta = await getAssociatedTokenAddress(
USDC_MINT_MAINNET,
payer.publicKey
);
// Check balance
try {
const tokenAccount = await getAccount(connection, sourceAta);
const balance = Number(tokenAccount.amount) / Math.pow(10, USDC_DECIMALS);
console.log(`USDC Balance: ${balance} USDC`);
const maxTransferAmount = BASE_TRANSFER_AMOUNT * 1.1; // Max is 10% more than base
const requiredBalance = maxTransferAmount * TRANSACTIONS_PER_PRIORITY * 3; // 3 priority levels
if (balance < requiredBalance) {
console.error(`Insufficient balance. Need at least ${requiredBalance.toFixed(4)} USDC`);
return;
}
} catch (error) {
console.error('Failed to get USDC balance. Make sure you have USDC in your wallet.');
return;
}
const priorityFees = [0, 500, 1000]; // microlamports per CU
const results: TransferResult[] = [];
console.log('\n🏁 Starting simultaneous transfers...\n');
for (let i = 0; i < TRANSACTIONS_PER_PRIORITY; i++) {
console.log(`Round ${i + 1}/${TRANSACTIONS_PER_PRIORITY}:`);
// Create transactions for both priority levels
const transactionPromises = priorityFees.map(async (priorityFee) => {
// Generate random transfer amount (0.0009 to 0.0011 USDC)
const randomVariation = (Math.random() * 0.2 - 0.1) * BASE_TRANSFER_AMOUNT;
const transferAmount = BASE_TRANSFER_AMOUNT + randomVariation;
// Create transaction
const transaction = await createTransferTransaction(
connection,
payer,
sourceAta,
sourceAta, // Self-transfer
priorityFee,
transferAmount
);
// Send transaction asynchronously
return sendTransactionAsync(connection, transaction, payer, priorityFee, transferAmount);
});
// Send both transactions simultaneously
const roundResults = await Promise.all(transactionPromises);
results.push(...roundResults);
// Log results for this round
roundResults.forEach(result => {
if (result.landed) {
console.log(` βœ… ${result.priorityFee} microlamports: ${result.signature} (${result.confirmationTime}ms)`);
} else {
console.log(` ❌ ${result.priorityFee} microlamports: Failed - ${result.error}`);
}
});
console.log('');
// Small delay between rounds
await new Promise(resolve => setTimeout(resolve, 1000));
}
// Calculate and display statistics
console.log('\nπŸ“ˆ RESULTS SUMMARY\n' + '='.repeat(50));
const stats: PriorityStats[] = priorityFees.map(fee => {
const feeResults = results.filter(r => r.priorityFee === fee);
const landed = feeResults.filter(r => r.landed);
const avgTime = landed.length > 0
? landed.reduce((sum, r) => sum + (r.confirmationTime || 0), 0) / landed.length
: 0;
return {
priorityFee: fee,
sent: feeResults.length,
landed: landed.length,
landingRate: (landed.length / feeResults.length) * 100,
avgConfirmationTime: avgTime / 1000 // Convert to seconds
};
});
stats.forEach(stat => {
console.log(`\nPriority Fee: ${stat.priorityFee} microlamports/CU`);
console.log(` Sent: ${stat.sent}`);
console.log(` Landed: ${stat.landed}`);
console.log(` Landing Rate: ${stat.landingRate.toFixed(2)}%`);
console.log(` Avg Confirmation Time: ${stat.avgConfirmationTime.toFixed(2)}s`);
});
// Save detailed results
const resultsFile = 'transfer-results.json';
fs.writeFileSync(resultsFile, JSON.stringify({ stats, results }, null, 2));
console.log(`\nπŸ’Ύ Detailed results saved to ${resultsFile}`);
}
main().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment