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

@nvana-dharma/sol-tx-tools

v0.1.0

Published

A comprehensive TypeScript library and CLI for working with Solana transaction signatures and data. Features rate-limited RPC calls, streaming capabilities, and robust error handling.

Readme

sol-tx-tools

A comprehensive TypeScript library and CLI for working with Solana transaction signatures and data. Features rate-limited RPC calls, streaming capabilities, and robust error handling.

Installation

npm install @nvana-dharma/sol-tx-tools
# or
pnpm add @nvana-dharma/sol-tx-tools

Features

  • 🚀 Efficient signature fetching with automatic pagination
  • 📡 Real-time signature streaming for monitoring accounts
  • Rate-limited transaction fetching with configurable RPS
  • 🔄 Automatic retry logic with exponential backoff
  • 💪 TypeScript support with full type definitions
  • 🛠️ CLI tools for command-line usage
  • 🎯 Order preservation for batch operations

CLI Usage

The package includes a powerful CLI tool for working with Solana signatures.

Global Options

  • -r, --rpc <url> - RPC endpoint URL (required)
  • -c, --commitment <level> - Commitment level: confirmed or finalized (default: finalized)

Commands

get-sigs - Fetch Historical Signatures

Get all signatures for an account with optional bounds:

# Get all signatures for an account
sol-tx-tools --rpc https://api.mainnet-beta.solana.com get-sigs \
  --account EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

# Get signatures within a range
sol-tx-tools --rpc <RPC_URL> get-sigs \
  --account <ADDRESS> \
  --lookforward <NEWEST_SIG> \
  --lookback <OLDEST_SIG>

# Filter out failed transactions
sol-tx-tools --rpc <RPC_URL> get-sigs \
  --account <ADDRESS> \
  --filter-failed

Options:

  • -a, --account <address> - Account address (required)
  • -b, --lookback <signature> - Stop before this signature (exclusive oldest boundary)
  • -f, --lookforward <signature> - Start from this signature (newest boundary)
  • --filter-failed - Filter out failed transactions

stream-sigs - Stream Real-time Signatures

Monitor an account for new transactions in real-time:

# Stream new signatures as they arrive
sol-tx-tools --rpc https://api.mainnet-beta.solana.com stream-sigs \
  --account <ADDRESS>

# With custom poll interval (in seconds)
sol-tx-tools --rpc <RPC_URL> stream-sigs \
  --account <ADDRESS> \
  --poll-interval 5

# With verbose logging
sol-tx-tools --rpc <RPC_URL> stream-sigs \
  --account <ADDRESS> \
  --verbose

Options:

  • -a, --account <address> - Account address to monitor (required)
  • -p, --poll-interval <seconds> - Poll interval in seconds (default: 10)
  • --filter-failed - Filter out failed transactions
  • -v, --verbose - Enable verbose debug logging

The stream runs indefinitely until interrupted (Ctrl+C). It starts from the most recent signature and only looks forward for new transactions.

get-tx - Fetch Transaction Data

Fetch full transaction data for signatures provided via stdin. Reads signatures continuously from stdin and fetches transactions with rate limiting:

# Fetch transactions for specific signatures
echo "signature1" | sol-tx-tools --rpc <RPC_URL> get-tx

# Pipe signatures from get-sigs to get-tx
sol-tx-tools --rpc <RPC_URL> get-sigs -a <ADDRESS> | \
  sol-tx-tools --rpc <RPC_URL> get-tx --rps 20

# Stream transactions in real-time
sol-tx-tools --rpc <RPC_URL> stream-sigs -a <ADDRESS> | \
  sol-tx-tools --rpc <RPC_URL> get-tx --verbose

# Custom rate limiting and retries
sol-tx-tools --rpc <RPC_URL> get-tx \
  --rps 50 \
  --max-retries 5 \
  --retry-delay 2000

# Output as base64 encoded
echo "sig1" | sol-tx-tools --rpc <RPC_URL> get-tx --output-format base64

Options:

  • -s, --rps <number> - Requests per second (default: 10)
  • --max-retries <number> - Maximum retries per signature (default: 3)
  • --retry-delay <ms> - Base retry delay in milliseconds (default: 1000)
  • --max-queue <number> - Maximum queue size (default: 10000)
  • --output-format <format> - Output format: json or base64 (default: json)
  • -v, --verbose - Enable verbose debug logging

The command reads signatures from stdin (one per line) and outputs JSON for each transaction. Results are returned in the same order as the input signatures. The command will continue reading until stdin is closed or interrupted.

Piping and Integration

All commands output signatures to stdout (one per line), making them perfect for piping:

# Save to file
sol-tx-tools --rpc <RPC> get-sigs -a <ADDR> > signatures.txt

# Process each signature
sol-tx-tools --rpc <RPC> stream-sigs -a <ADDR> | while read sig; do
  echo "Processing $sig"
  # Your processing logic here
done

# Count signatures
sol-tx-tools --rpc <RPC> get-sigs -a <ADDR> | wc -l

Library Usage

Connection Provider Setup

The library uses an abstraction layer (IConnectionProvider) for RPC operations, allowing you to use simple connections, RPC pools, or custom implementations:

import { SimpleConnectionProvider, RpcPoolConnectionProvider } from '@nvana-dharma/sol-tx-tools'
import { Connection } from '@solana/web3.js'

// Simple connection provider (with built-in retry logic)
const connection = new Connection('https://api.mainnet-beta.solana.com')
const provider = new SimpleConnectionProvider(connection, 'finalized')

// Or use with RPC pool for better reliability (requires @nvana-dharma/rpc-pooler)
import { ExponentialBackoffRpcPool } from '@nvana-dharma/rpc-pooler'

const pool = new ExponentialBackoffRpcPool({
  urls: ['rpc1', 'rpc2', 'rpc3'],
  maxRetries: 3
})
const poolProvider = new RpcPoolConnectionProvider(pool, 'finalized')

Fetching Signatures

import { getSignaturesForAccountAddress, SimpleConnectionProvider } from '@nvana-dharma/sol-tx-tools'
import { PublicKey, Connection } from '@solana/web3.js'

// Create connection provider
const connection = new Connection('https://api.mainnet-beta.solana.com')
const provider = new SimpleConnectionProvider(connection, 'finalized')

// Fetch all signatures for an account
for await (const sig of getSignaturesForAccountAddress({
  accountAddress: new PublicKey('...'),
  connectionProvider: provider,
  commitment: 'finalized',
  filterOutFailed: true
})) {
  console.log(`Signature: ${sig.signature}, Slot: ${sig.slot}`)
}

// Fetch with bounds
for await (const sig of getSignaturesForAccountAddress({
  accountAddress: new PublicKey('...'),
  connectionProvider: provider,
  lookForwardLimit: 'newestSig123', // Start from here
  lookBackLimit: 'oldestSig456'     // Stop before this (exclusive)
})) {
  // Process signatures
}

Streaming Signatures

import { streamSignaturesWithSignalHandling, SignatureStreamer, SimpleConnectionProvider } from '@nvana-dharma/sol-tx-tools'
import { PublicKey, Connection } from '@solana/web3.js'

// Create connection provider
const connection = new Connection('https://api.mainnet-beta.solana.com')
const provider = new SimpleConnectionProvider(connection, 'finalized')

// Simple streaming with automatic signal handling
for await (const sig of streamSignaturesWithSignalHandling({
  accountAddress: new PublicKey('...'),
  connectionProvider: provider,
  pollIntervalMs: 5000,
  filterOutFailed: true,
  onError: (err) => console.error('Error:', err),
  onDebug: (msg) => console.log('Debug:', msg)
})) {
  console.log(`New transaction: ${sig.signature}`)
}

// Using the SignatureStreamer class for more control
const streamer = new SignatureStreamer({
  accountAddress: new PublicKey('...'),
  connectionProvider: provider,
  pollIntervalMs: 5000
})

for await (const sig of streamer.start()) {
  console.log(`New signature: ${sig.signature}`)

  // Stop streaming based on condition
  if (someCondition) {
    streamer.stop()
  }
}

Fetching Transactions with Rate Limiting (Batch)

For fetching a fixed list of transactions with rate limiting:

import { getTransactionsBySigs, SimpleConnectionProvider } from '@nvana-dharma/sol-tx-tools'
import { Connection } from '@solana/web3.js'

const connection = new Connection('https://api.mainnet-beta.solana.com')
const provider = new SimpleConnectionProvider(connection, 'finalized')
const signatures = ['sig1', 'sig2', 'sig3', ...]

// Fetch transactions with rate limiting (10 RPS default)
for await (const result of getTransactionsBySigs(provider, signatures)) {
  if (result.ok) {
    console.log('Transaction:', result.value)
  } else {
    console.error('Failed to fetch:', result.signature, result.error)
  }
}

// Custom rate limit
for await (const result of getTransactionsBySigs(provider, signatures, 'finalized', 20)) {
  // Process at 20 requests per second
}

Fetching Transactions with Producer-Consumer Pattern

The TransactionFetcher class provides a producer-consumer pattern for fetching transactions, perfect for integration with message queues, event streams, or other data sources:

import { TransactionFetcher } from '@nvana-dharma/sol-tx-tools'
import { Connection } from '@solana/web3.js'

const connection = new Connection('https://api.mainnet-beta.solana.com')

// Create a fetcher instance
const fetcher = new TransactionFetcher({
  provider,
  commitment: 'finalized',
  requestsPerSecond: 20,
  maxQueueSize: 10000,
  batchSize: 100,
  onError: (sig, error) => {
    console.error(`Failed to fetch ${sig}:`, error)
  },
  onDebug: (msg) => console.log('Debug:', msg)
})

// Start consuming transactions (in a separate async context)
const consumer = (async () => {
  for await (const result of fetcher.fetch()) {
    if (result.transaction) {
      console.log(`Got transaction: ${result.signature}`)
      // Process transaction data
    }
  }
})()

// Producer: enqueue signatures as they arrive
// For example, from a Kafka consumer:
kafkaConsumer.on('message', (message) => {
  const signature = message.value.toString()

  // Enqueue returns false if queue is full
  if (!fetcher.enqueue(signature)) {
    // Handle backpressure
    console.warn('Queue full, waiting...')
  }
})

// When done, stop the fetcher
fetcher.stop() // Will process remaining queue before stopping
await consumer // Wait for all transactions to be processed

Fetching Transactions from stdin

import { fetchTransactionsFromStdin, SimpleConnectionProvider } from '@nvana-dharma/sol-tx-tools'
import { Connection } from '@solana/web3.js'

const connection = new Connection('https://api.mainnet-beta.solana.com')
const provider = new SimpleConnectionProvider(connection, 'finalized')

// Read signatures from stdin and fetch transactions
for await (const result of fetchTransactionsFromStdin(provider, {
  commitment: 'finalized',
  requestsPerSecond: 20,
  maxRetries: 5
})) {
  if (result.transaction) {
    console.log('Transaction:', result.transaction)
  } else {
    console.error('Error:', result.error)
  }
}

Generic Rate Limiting

Use the rate limiter for any async operations:

import { rateLimitedMapOrdered } from '@nvana-dharma/sol-tx-tools'

const urls = ['url1', 'url2', 'url3', ...]

// Rate limit any async operation
for await (const result of rateLimitedMapOrdered(
  urls,
  async (url) => fetch(url),
  {
    requestsPerSecond: 5,
    maxRetries: 3,
    retryDelayMs: 1000
  }
)) {
  if (result.ok) {
    console.log('Success:', result.value)
  } else {
    console.error('Failed:', result.error)
  }
}

Utility Functions

import {
  calculateExponentialBackoff,
  sleep,
  isRetryableError,
  withRetry
} from '@nvana-dharma/sol-tx-tools'

// Calculate backoff delay
const delay = calculateExponentialBackoff(attemptNumber, 1000, 30000)

// Sleep with promise
await sleep(1000)

// Check if error is retryable
if (isRetryableError(error)) {
  // Retry logic
}

// Wrap any function with retry logic
const result = await withRetry(
  async () => someUnreliableOperation(),
  {
    maxRetries: 5,
    baseDelayMs: 500,
    onRetry: (attempt, error) => {
      console.log(`Retry ${attempt + 1}:`, error)
    }
  }
)

Key Features

Automatic Retry Logic

All RPC calls include built-in retry logic with exponential backoff:

  • Retries on 429, 500, 502, 503, 504 errors
  • Retries on network timeouts and connection errors
  • Configurable max retries and delays
  • Preserves request parameters across retries

Rate Limiting

The transaction fetcher uses a token bucket algorithm for smooth rate limiting:

  • Configurable requests per second
  • Burst capacity support
  • Order preservation
  • Memory efficient streaming

Signal Handling

The streaming functionality includes graceful shutdown:

  • Handles SIGINT/SIGTERM signals
  • Drains queued signatures before exit
  • No data loss on shutdown

API Reference

Types

interface SignatureDatum {
  signature: string
  slot: number
}

interface StreamSignaturesOptions {
  accountAddress: PublicKey
  rpcUrl: string
  commitment?: Finality
  pollIntervalMs?: number
  filterOutFailed?: boolean
  onError?: (error: Error) => void
  onDebug?: (message: string) => void
  signal?: AbortSignal
}

interface TransactionFetcherOptions {
  provider: IConnectionProvider
  commitment?: Finality
  requestsPerSecond?: number
  maxQueueSize?: number
  batchSize?: number
  maxRetries?: number
  retryDelayMs?: number
  onError?: (signature: string, error: unknown) => void
  onDebug?: (message: string) => void
}

interface TransactionResult {
  signature: string
  transaction?: VersionedTransactionResponse | null
  error?: unknown
}

type Settled<T> =
  | { ok: true; value: T; index: number }
  | { ok: false; error: unknown; index: number }

Error Handling

The library includes sophisticated error handling:

  • Automatic retries on transient failures
  • Exponential backoff to prevent thundering herd
  • Graceful degradation on persistent errors
  • Detailed error reporting

Performance

  • Streaming: Minimal memory footprint with async generators
  • Pagination: Efficient handling of large signature lists
  • Rate Limiting: Smooth request distribution
  • Parallel Processing: Sliding window for concurrent operations

Development

# Install dependencies
pnpm install

# Build the project
pnpm build

# Run tests
pnpm test

# Run the CLI locally
node build/cli.js --help

License

UNLICENSED (private package)

Contributing

This is a private package in the nvana-dharma monorepo.