npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

solana-transaction-optimizer

v1.0.0

Published

Optimize Solana transactions by chunking large transactions into smaller batches. Supports multiple signers, complex instructions, and adaptive sizing.

Readme

Solana Transaction Optimizer

Optimize Solana transactions by chunking large transactions into smaller batches. Supports multiple signers, complex instructions, and adaptive sizing.

Installation

npm install solana-transaction-optimizer
# or
yarn add solana-transaction-optimizer
# or
pnpm add solana-transaction-optimizer

Overview

This 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.

Problems Solved

  • 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

Features

  • ✅ 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

Quick Start

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
});

API Reference

Chunking Functions

buildTxChunkManySigners

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[]>

buildTxChunkSingleSigner

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[]>

buildTxChunkByInstruction

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[]>

buildTxChunkSmart

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 → uses buildTxChunkManySigners
  • If signers.length === 1 → uses buildTxChunkSingleSigner

buildTxChunkDynamic

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[]>

streamTxChunksGenerator

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>

Utility Functions

sendTxParallel

Send multiple transactions in parallel.

sendTxParallel({
  txList: VersionedTransaction[],
  connection: Connection
}): Promise<string[]>

estimateGasCost

Calculate fee based on compute units and price.

estimateGasCost({
  computeUnitLimit: number,
  computeUnitPriceMicroLamports: number
}): number

calculateTxSize

Calculate transaction size in bytes.

calculateTxSize(tx: VersionedTransaction): number

Examples

Example 1: Bundle Wallet Sweeping

import { 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;
}

Example 2: Dynamic Chunking with Adaptive Sizing

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;
}

Example 3: Streaming for Large Batches

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);
    }
  }
}

Chunking Strategy Guide

| 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 |

Recommended Chunk Sizes

  • 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

Performance Tips

  1. Use ALT (Address Lookup Table): ALT can significantly reduce transaction size
  2. Batch Blockhash Requests: Reuse blockhash for multiple transactions when possible
  3. Parallel Sending: Use sendTxParallel to send multiple transactions at once
  4. Streaming for Large Batches: Use streamTxChunksGenerator for thousands of transactions
  5. Monitor Transaction Size: Use calculateTxSize to monitor transaction sizes

Requirements

  • Node.js >= 16.0.0
  • @solana/web3.js ^1.95.0

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions, please open an issue on GitHub.