Optimize Solana transactions by chunking large transactions into smaller batches. Supports multiple signers, complex instructions, and adaptive sizing.
npm install solana-transaction-optimizer
# or
yarn add solana-transaction-optimizer
# or
pnpm add solana-transaction-optimizerThis library helps you optimize Solana transactions by splitting large transactions into smaller chunks. It's designed to handle Solana's transaction size limit (~1232 bytes) and optimize performance when dealing with many transactions.
- Transaction Size: Solana has a maximum limit of ~1232 bytes per transaction
- Multiple Signers: Transactions with many signers require more space
- Many Instructions: Transactions with many instructions can exceed size limits
- Memory Efficiency: Avoid excessive memory usage when processing thousands of transactions
- ✅ Multiple chunking strategies for different use cases
- ✅ Support for multiple signers
- ✅ Adaptive sizing with automatic chunk size adjustment
- ✅ Streaming support for memory-efficient processing
- ✅ Parallel transaction sending
- ✅ TypeScript support with full type definitions
import { buildTxChunkSmart, sendTxParallel } from 'solana-transaction-optimizer';
import { Connection, Keypair, SystemProgram, PublicKey } from '@solana/web3.js';
// Build transaction chunks
const txList = await buildTxChunkSmart(
10, // chunkSize
priorityFeeIx,
transferInstructions,
signers,
payerKeypair,
lookupTableAccount,
connection
);
// Send transactions in parallel
const signatures = await sendTxParallel({
txList,
connection
});Split transactions with multiple signers into batches.
Use when:
- Bundle wallet sweeping
- Multi-wallet draining
- Transactions with multiple signers (> 1)
buildTxChunkManySigners(
chunkSize: number,
priorityFeeIx: TransactionInstruction[],
transferInstructions: TransactionInstruction[],
bundlerSigners: Keypair[],
payerKeypair: Keypair,
lookupTableAccount: AddressLookupTableAccount,
connection: Connection
): Promise<VersionedTransaction[]>Split transactions with many instructions but only 1 signer.
Use when:
- Sweeping many transfers from one wallet
- Large transactions with ALT
- Single wallet with many instructions
buildTxChunkSingleSigner(
chunkSize: number,
priorityFeeIx: TransactionInstruction[],
transferInstructions: TransactionInstruction[],
payerKeypair: Keypair,
lookupTableAccount: AddressLookupTableAccount,
connection: Connection
): Promise<VersionedTransaction[]>Split transactions based on instruction count (can have multiple signers).
Use when:
- Batch token payments
- Multi-token transfers
- Complex SPL instructions
- Many CPI calls
buildTxChunkByInstruction(
chunkSize: number,
priorityFeeIx: TransactionInstruction[],
transferInstructions: TransactionInstruction[],
signers: Keypair[],
payerKeypair: Keypair,
lookupTableAccount: AddressLookupTableAccount,
connection: Connection
): Promise<VersionedTransaction[]>Automatic builder that chooses chunking strategy based on signer count.
Use when:
- General purpose use cases
- Dynamic use cases with varying signer counts
- Quick implementation without thinking about strategy
buildTxChunkSmart(
chunkSize: number,
priorityFeeIx: TransactionInstruction[],
transferInstructions: TransactionInstruction[],
signers: Keypair[],
payerKeypair: Keypair,
lookupTableAccount: AddressLookupTableAccount,
connection: Connection
): Promise<VersionedTransaction[]>Logic:
- If
signers.length > 1→ usesbuildTxChunkManySigners - If
signers.length === 1→ usesbuildTxChunkSingleSigner
Builder with adaptive sizing that automatically adjusts chunk size based on transaction size.
Use when:
- Instruction sizes vary
- Unsure about optimal chunk size
- Need automatic optimization based on actual size
buildTxChunkDynamic({
instructions: TransactionInstruction[],
signers: Keypair[],
payer: Keypair,
alts?: AddressLookupTableAccount[],
priorityFeeIx?: TransactionInstruction[],
connection: Connection,
maxBytes?: number, // default: 1232
initialChunkSize?: number // default: 10
}): Promise<VersionedTransaction[]>Async generator for streaming transactions (lazy evaluation).
Use when:
- Processing thousands of transactions
- Memory-constrained environments
- Streaming processing pattern
- Don't need all transactions in memory at once
streamTxChunksGenerator({
chunkSize: number,
instructions: TransactionInstruction[],
signers: Keypair[],
payer: Keypair,
alts?: AddressLookupTableAccount[],
priorityFeeIx?: TransactionInstruction[],
connection: Connection
}): AsyncGenerator<VersionedTransaction, void, unknown>Send multiple transactions in parallel.
sendTxParallel({
txList: VersionedTransaction[],
connection: Connection
}): Promise<string[]>Calculate fee based on compute units and price.
estimateGasCost({
computeUnitLimit: number,
computeUnitPriceMicroLamports: number
}): numberCalculate transaction size in bytes.
calculateTxSize(tx: VersionedTransaction): numberimport { buildTxChunkManySigners, sendTxParallel } from 'solana-transaction-optimizer';
import { Connection, Keypair, SystemProgram, PublicKey, ComputeBudgetProgram } from '@solana/web3.js';
async function sweepBundleWallets(
bundleWallets: Keypair[],
payerKeypair: Keypair,
destinationAddress: string,
connection: Connection,
lookupTableAccount: AddressLookupTableAccount
) {
// Create transfer instructions for each wallet
const transferInstructions = bundleWallets.map(wallet =>
SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: new PublicKey(destinationAddress),
lamports: // calculate amount
})
);
// Priority fee instructions
const priorityFeeIx = [
ComputeBudgetProgram.setComputeUnitLimit({ units: 250_000 }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 4 })
];
// Build chunks with 10 signers per batch
const txList = await buildTxChunkManySigners(
10, // chunkSize
priorityFeeIx,
transferInstructions,
bundleWallets, // bundlerSigners
payerKeypair,
lookupTableAccount,
connection
);
// Send all transactions in parallel
const signatures = await sendTxParallel({
txList,
connection
});
console.log(`Sent ${signatures.length} transactions`);
return signatures;
}import { buildTxChunkDynamic } from 'solana-transaction-optimizer';
async function adaptiveChunking(
instructions: TransactionInstruction[],
signers: Keypair[],
payer: Keypair,
connection: Connection,
alts: AddressLookupTableAccount[]
) {
// Automatically adjust chunk size
const txList = await buildTxChunkDynamic({
instructions,
signers,
payer,
alts,
connection,
maxBytes: 1232, // Maximum limit
initialChunkSize: 15 // Start with 15 instructions
});
// If chunk is too large, it will automatically reduce
// until it finds the right size
return txList;
}import { streamTxChunksGenerator } from 'solana-transaction-optimizer';
async function processLargeBatch(
instructions: TransactionInstruction[],
signers: Keypair[],
payer: Keypair,
connection: Connection
) {
// Generator for streaming (doesn't load all into memory)
const generator = streamTxChunksGenerator({
chunkSize: 10,
instructions,
signers,
payer,
connection
});
// Process one by one
for await (const tx of generator) {
try {
const signature = await connection.sendTransaction(tx);
console.log(`Sent: ${signature}`);
} catch (error) {
console.error('Failed to send transaction:', error);
}
}
}| Strategy | Signers | Instructions | Use Case |
|---|---|---|---|
buildTxChunkManySigners |
> 1 | Medium | Bundle wallet sweeping |
buildTxChunkSingleSigner |
1 | Many | Single wallet distribution |
buildTxChunkByInstruction |
1 or more | Many & Complex | Token batch payments |
buildTxChunkSmart |
Dynamic | Dynamic | General purpose |
buildTxChunkDynamic |
Dynamic | Dynamic & Varied | Adaptive sizing |
streamTxChunksGenerator |
Dynamic | Very Many | Memory-efficient streaming |
- SOL Transfer: 15-25 instructions per batch
- SPL Token Transfer: 5-10 instructions per batch
- Multiple Signers: 5-10 signers per batch
- Complex Instructions: 3-5 instructions per batch
- Use ALT (Address Lookup Table): ALT can significantly reduce transaction size
- Batch Blockhash Requests: Reuse blockhash for multiple transactions when possible
- Parallel Sending: Use
sendTxParallelto send multiple transactions at once - Streaming for Large Batches: Use
streamTxChunksGeneratorfor thousands of transactions - Monitor Transaction Size: Use
calculateTxSizeto monitor transaction sizes
- Node.js >= 16.0.0
@solana/web3.js^1.95.0
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions, please open an issue on GitHub.