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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@igroza/yellowstone-grpc-client

v1.1.2

Published

Solana Yellowstone Geyser gRPC client

Readme

Yellowstone Geyser gRPC Client

A fully-typed TypeScript client for the Solana Yellowstone Geyser gRPC service, providing real-time access to Solana blockchain data with complete type safety and @solana/web3.js compatibility.

Installation

npm install @igroza/yellowstone-grpc-client

Proto Files

Copy the gRPC proto files to your project's proto folder:

cp ./node_modules/@igroza/yellowstone-grpc-client/proto/* ./proto/

This will copy the required .proto files (geyser.proto and solana-storage.proto) to your project for gRPC connection.

Dependency Security

Production dependencies

These dependencies will not be installed in your project, but are included in the release bundle file via esbuild.

Dependency graph:

Production dependency graph

Development dependencies

These dependencies used for building the package.

Quick Start

Run example from repository

  • Clone the repository:

      git clone https://github.com/igroza/yellowstone-grpc-client.git
      cd yellowstone-grpc-client
  • replace grpc-url.com:10101 with your actual gRPC endpoint in the example/example.ts file

  • Install dependencies:

    npm install
  • Run example code:

    npm run example

Example code

import { YellowstoneGeyserClient, CommitmentLevel, TransactionFormatter } from '@igroza/yellowstone-grpc-client';

// Create client
const client = new YellowstoneGeyserClient({
  endpoint: 'grpc-url.com:10101',
  credentials: 'your-api-token' // optional
});

// Connect to server
await client.connect();

// Subscribe to transactions
const stream = client.createSubscription(
  {
    transactions: {
      'my_filter': {
        vote: false,
        failed: false,
        account_include: ['YourAccountAddressHere']
      }
    },
    commitment: CommitmentLevel.PROCESSED
  },
  (update) => {
    if (update.transaction) {
      const tx = TransactionFormatter.formTransactionFromJson(update);
      console.log('Transaction:', tx.transaction.signatures[0]);
    }
  },
  (error) => console.error('Error:', error),
  () => console.log('Stream ended')
);

API Reference

YellowstoneGeyserClient

Constructor

const client = new YellowstoneGeyserClient(config: YellowstoneGeyserClientConfig);

Configuration:

interface YellowstoneGeyserClientConfig {
  endpoint: string;              // gRPC endpoint
  credentials?: string;          // Optional authentication token (added to 'x-token' header)
  options?: grpc.ChannelOptions; // Optional gRPC channel options
}

Example with authentication:

const client = new YellowstoneGeyserClient({
  endpoint: 'grpc-url.com:10101',
  credentials: 'your-api-token-here'
});

Methods

connect(): Promise<void>

Establishes connection to the gRPC server.

await client.connect();
createSubscription(request, onData, onError?, onEnd?)

Creates a subscription with callback handlers for data, errors, and stream end.

const stream = client.createSubscription(
  { transactions: { 'filter': { vote: false } }, commitment: CommitmentLevel.PROCESSED },
  (update) => console.log('Update:', update),
  (error) => console.error('Error:', error),
  () => console.log('Stream ended')
);
subscribe(request: SubscribeRequest, options?: grpc.CallOptions)

Low-level method that creates a bidirectional streaming subscription. Returns a gRPC stream object.

const stream = client.subscribe({
  transactions: { 'filter': { vote: false } },
  commitment: CommitmentLevel.PROCESSED
});
getVersion(): Promise<GetVersionResponse>

Retrieves the Geyser server version information.

const version = await client.getVersion();
console.log('Version:', version.version);
getSlot(request?: GetSlotRequest): Promise<GetSlotResponse>

Gets the current slot number.

const slot = await client.getSlot();
console.log('Current slot:', slot.slot);
getBlockHeight(request?: GetBlockHeightRequest): Promise<GetBlockHeightResponse>

Gets the current block height.

const blockHeight = await client.getBlockHeight();
console.log('Block height:', blockHeight.block_height);
getLatestBlockhash(request?: GetLatestBlockhashRequest): Promise<GetLatestBlockhashResponse>

Gets the latest blockhash.

const { blockhash, slot, last_valid_block_height } = await client.getLatestBlockhash();
isBlockhashValid(request: IsBlockhashValidRequest): Promise<IsBlockhashValidResponse>

Checks if a blockhash is still valid.

const { valid } = await client.isBlockhashValid({ blockhash: 'your-blockhash' });
ping(request: PingRequest): Promise<PongResponse>

Sends a ping to test connectivity.

const response = await client.ping({ count: 1 });
sendPing(stream, id: number): void

Sends a ping through an existing subscription stream to keep the connection alive.

client.sendPing(stream, Date.now());
close(): void

Closes the gRPC client connection.

client.close();

Subscription Types

Account Subscriptions

Subscribe to account updates with flexible filtering options.

client.createSubscription(
  {
    accounts: {
      'my_accounts': {
        account: ['AccountPubkey1', 'AccountPubkey2'],
        owner: ['ProgramId1', 'ProgramId2'],
        filters: [
          { memcmp: { offset: 0, base58: 'SomeData' } },
          { datasize: 165 },
          { token_account_state: true },
          { lamports: { gt: 1000000 } }
        ],
        nonempty_txn_signature: true
      }
    },
    commitment: CommitmentLevel.CONFIRMED
  },
  (update) => {
    if (update.account) {
      const { account, slot } = update.account;
      console.log('Account updated:', {
        pubkey: Buffer.from(account.pubkey).toString('base64'),
        lamports: account.lamports,
        slot: slot
      });
    }
  }
);

Transaction Subscriptions

Subscribe to transactions with filtering options.

client.createSubscription(
  {
    transactions: {
      'my_transactions': {
        vote: false,
        failed: false,
        account_include: ['Account1', 'Account2'],
        account_exclude: ['Account3'],
        account_required: ['Account4']
      }
    },
    commitment: CommitmentLevel.PROCESSED,
    from_slot: 100000000
  },
  (update) => {
    if (update.transaction) {
      const tx = TransactionFormatter.formTransactionFromJson(update);
      console.log('Transaction:', {
        signature: tx.transaction.signatures[0],
        slot: tx.slot,
        success: tx.meta?.err === null
      });
    }
  }
);

Slot Subscriptions

Subscribe to slot status updates.

client.createSubscription(
  {
    slots: {
      'my_slots': {
        filter_by_commitment: true,
        interslot_updates: true
      }
    },
    commitment: CommitmentLevel.FINALIZED
  },
  (update) => {
    if (update.slot) {
      console.log('Slot:', update.slot.slot, 'Status:', update.slot.status);
    }
  }
);

Block Subscriptions

Subscribe to complete block data.

client.createSubscription(
  {
    blocks: {
      'my_blocks': {
        account_include: ['AccountToMonitor'],
        include_transactions: true,
        include_accounts: true,
        include_entries: true
      }
    },
    commitment: CommitmentLevel.CONFIRMED
  },
  (update) => {
    if (update.block) {
      console.log('Block:', update.block.slot, 'Txs:', update.block.executed_transaction_count);
    }
  }
);

Block Meta Subscriptions

Subscribe to lightweight block metadata.

client.createSubscription(
  {
    blocks_meta: { 'my_block_meta': {} },
    commitment: CommitmentLevel.FINALIZED
  },
  (update) => {
    if (update.block_meta) {
      console.log('Block:', update.block_meta.slot, update.block_meta.blockhash);
    }
  }
);

Entry Subscriptions

Subscribe to entry updates.

client.createSubscription(
  { entry: { 'my_entries': {} } },
  (update) => {
    if (update.entry) {
      console.log('Entry:', update.entry.slot, update.entry.index);
    }
  }
);

Transaction Status Subscriptions

Subscribe to lightweight transaction status updates.

client.createSubscription(
  {
    transactions_status: {
      'my_tx_status': {
        vote: false,
        failed: false
      }
    }
  },
  (update) => {
    if (update.transaction_status) {
      console.log('Status:', update.transaction_status.slot);
    }
  }
);

TransactionFormatter

Utility class for converting between Yellowstone transaction data and Solana web3.js compatible formats.

formTransactionFromJson(update: SubscribeUpdate): VersionedTransactionResponse

Converts raw Yellowstone transaction data into Solana web3.js VersionedTransactionResponse format.

import { TransactionFormatter } from '@igroza/yellowstone-grpc-client';

const tx = TransactionFormatter.formTransactionFromJson(update);
console.log('Signature:', tx.transaction.signatures[0]);
console.log('Fee:', tx.meta.fee);
console.log('Success:', tx.meta.err === null);
console.log('Slot:', tx.slot);
console.log('Block Time:', tx.blockTime);

toJSON(transaction: VersionedTransactionResponse): any

Converts a VersionedTransactionResponse to plain JSON format for serialization or storage.

import { TransactionFormatter } from '@igroza/yellowstone-grpc-client';

const tx = TransactionFormatter.formTransactionFromJson(update);
const json = TransactionFormatter.toJSON(tx);

// Store or transmit as JSON
console.log(JSON.stringify(json, null, 2));

// Save to file or database
fs.writeFileSync('transaction.json', JSON.stringify(json));

Update Types

Check the update_oneof field to determine update type:

import { UpdateType } from '@igroza/yellowstone-grpc-client';

client.createSubscription(request, (update) => {
  switch (update.update_oneof) {
    case UpdateType.ACCOUNT:
      console.log('Account:', update.account);
      break;
    case UpdateType.TRANSACTION:
      const tx = TransactionFormatter.formTransactionFromJson(update);
      console.log('Transaction:', tx);
      break;
    case UpdateType.SLOT:
      console.log('Slot:', update.slot);
      break;
    case UpdateType.PING:
      client.sendPing(stream, Date.now());
      break;
    case UpdateType.PONG:
      console.log('Pong:', update.pong?.id);
      break;
  }
});

Filtering

Memory Compare

filters: [{ memcmp: { offset: 32, base58: 'YourMintAddress' } }]

Data Size

filters: [{ datasize: 165 }]

Lamports

filters: [{ lamports: { gt: 1000000 } }] // gt, lt, eq, ne

Data Slicing

accounts_data_slice: [{ offset: 0, length: 32 }]

Commitment Levels

CommitmentLevel.PROCESSED  // Fastest, may be rolled back
CommitmentLevel.CONFIRMED  // Confirmed by supermajority
CommitmentLevel.FINALIZED  // Finalized, cannot be rolled back

Error Handling

client.createSubscription(
  request,
  (update) => { /* handle data */ },
  (error) => {
    console.error('Error:', error.message, error.code);
    // Common codes: 14 (UNAVAILABLE), 4 (DEADLINE_EXCEEDED), 13 (INTERNAL)
  },
  () => console.log('Stream ended')
);

// Graceful shutdown
process.on('SIGINT', () => {
  client.close();
  process.exit(0);
});

Event Handling

The client extends EventEmitter and emits various events during its lifecycle. Use the YellowstoneGeyserClientEvents enum for type-safe event handling:

import { YellowstoneGeyserClient, YellowstoneGeyserClientEvents } from '@igroza/yellowstone-grpc-client';

const client = new YellowstoneGeyserClient({ endpoint: 'grpc-url.com:10101' });

// Listen to lifecycle events
client.on(YellowstoneGeyserClientEvents.INITIALIZED, () => {
  console.log('Client initialized');
});

client.on(YellowstoneGeyserClientEvents.CONNECTED, () => {
  console.log('Connected to server');
});

client.on(YellowstoneGeyserClientEvents.SUBSCRIBED, (request) => {
  console.log('Subscription created:', request);
});

client.on(YellowstoneGeyserClientEvents.ERROR, (error) => {
  console.error('Error occurred:', error);
});

client.on(YellowstoneGeyserClientEvents.STREAM_ENDED, () => {
  console.log('Stream ended');
});

client.on(YellowstoneGeyserClientEvents.CLOSED, () => {
  console.log('Client closed');
});

client.on(YellowstoneGeyserClientEvents.STATUS, (status) => {
  console.log('Status update:', status);
});

Available Events:

  • INITIALIZED - Client has been initialized
  • CONNECTED - Successfully connected to the gRPC server
  • SUBSCRIBED - Subscription has been created
  • ERROR - An error occurred
  • STREAM_ENDED - Subscription stream has ended
  • CLOSED - Client connection has been closed
  • STATUS - gRPC status update received

License

MIT