Skip to main content

What is Yellowstone gRPC?

Yellowstone gRPC provides direct access to Solana blockchain data through high-performance streaming. Unlike traditional RPC polling, gRPC delivers real-time updates with minimal latency, making it ideal for:
  • Trading Bots - Execute trades faster with real-time data
  • DeFi Applications - Monitor liquidity pools and token swaps instantly
  • Analytics Platforms - Track on-chain activity as it happens
  • Arbitrage Systems - Detect opportunities with millisecond precision

Quick Start

1

Subscribe to Yellowstone gRPC

Subscribe to the gRPC service at $247/month:Subscribe to Yellowstone gRPCWhat you get:
  • Two Regional Endpoints:
    • EU Region: https://grpc.solanatracker.io
    • US Region: https://grpc-us.solanatracker.io
  • Jito Shreds - 50-100ms faster data delivery
  • No Bandwidth Charges - Unlimited data streaming
  • 24/7 Uptime - Automatic failover and monitoring
Choose the endpoint closest to your infrastructure for optimal performance. Co-locate in the same data center for sub-millisecond latency.
2

Get Your API Credentials

After subscribing, retrieve your authentication credentials:Get Your API TokenYou’ll receive:
  • x-token - Your authentication token for gRPC requests
  • Endpoint URLs - Both EU and US regions
  • Configuration Guidelines - Recommended settings
Keep your token secure!
  • Never commit tokens to version control
  • Use environment variables
  • Rotate tokens periodically
3

Install Dependencies

Install the Yellowstone gRPC client:
npm install @triton-one/yellowstone-grpc

Complete Working Example

Here’s a complete, production-ready example that monitors transactions:
const Client = require("@triton-one/yellowstone-grpc").default;
const { CommitmentLevel } = require("@triton-one/yellowstone-grpc");

// Initialize and connect to Yellowstone gRPC
const getClient = async () => {
  let client = false;
  try {
    client = new Client(
      "https://grpc.solanatracker.io",
      "your-api-key-here",
      {
        "grpc.max_receive_message_length": 100 * 1024 * 1024,
      }
    );
    const version = await client.getVersion();
    if (version) {
      console.log("Connected! Version:", version);
      return client;
    }
  } catch (e) {
    console.error("Failed to connect:", e);
  }
  if (!client) {
    throw new Error("Failed to connect!");
  }
};

(async () => {
  const client = await getClient();
  const stream = await client.subscribe();

  // Handle stream lifecycle
  const streamClosed = new Promise((resolve, reject) => {
    stream.on("error", (error) => {
      console.error("Stream error:", error);
      reject(error);
    });
    stream.on("end", () => {
      console.log("Stream ended");
      resolve();
    });
    stream.on("close", () => {
      console.log("Stream closed");
      resolve();
    });
  });

  // Handle incoming data
  stream.on("data", (data) => {
    if (data?.transaction) {
      const tx = data.transaction.transaction;
      console.log("\n[Transaction]");
      console.log("  Signature:", tx.signature);
      console.log("  Slot:", data.transaction.slot);
      console.log("  Success:", !tx.meta?.err);
      if (tx.meta?.fee) {
        console.log("  Fee:", (tx.meta.fee / 1e9).toFixed(6), "SOL");
      }
    }
  });

  // Subscribe to Token Program transactions
  const request = {
    accounts: {},
    slots: {},
    transactions: {
      tokenTransactions: {
        vote: false,
        failed: false,
        signature: undefined,
        accountInclude: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
        accountExclude: [],
        accountRequired: [],
      },
    },
    transactionsStatus: {},
    entry: {},
    blocks: {},
    blocksMeta: {},
    accountsDataSlice: [],
    ping: undefined,
    commitment: CommitmentLevel.CONFIRMED,
  };

  // Send subscribe request
  await new Promise((resolve, reject) => {
    stream.write(request, (err) => {
      if (err === null || err === undefined) {
        console.log("Subscribed to Token Program transactions");
        resolve();
      } else {
        reject(err);
      }
    });
  }).catch((reason) => {
    console.error("Subscribe failed:", reason);
    throw reason;
  });

  await streamClosed;
})();

What This Example Does

  1. Connects to Yellowstone gRPC with proper error handling
  2. Creates a stream with lifecycle event handlers
  3. Subscribes to transactions involving the Token Program
  4. Processes each transaction and logs key details
  5. Handles errors gracefully with proper cleanup

Monitoring Different Data Types

  • Account Updates
  • Slot Updates
  • Block Data
Monitor account changes:
const request = {
  accounts: {
    myAccounts: {
      account: ["YourAccountAddress"],
      owner: [],
      filters: []
    }
  },
  slots: {},
  transactions: {},
  transactionsStatus: {},
  entry: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  ping: undefined,
  commitment: CommitmentLevel.CONFIRMED,
};

stream.on("data", (data) => {
  if (data?.account) {
    const account = data.account.account;
    console.log("Account Update:", account.pubkey);
    console.log("Lamports:", account.lamports);
  }
});

Environment Variables

Store your credentials securely:
# .env file
GRPC_ENDPOINT=https://grpc.solanatracker.io
GRPC_API_KEY=your-api-key-here
require('dotenv').config();

const client = new Client(
  process.env.GRPC_ENDPOINT,
  process.env.GRPC_API_KEY,
  {
    "grpc.max_receive_message_length": 100 * 1024 * 1024,
  }
);

What’s Next?

Common Questions

Which endpoint should I use?

Choose based on your location:
  • Europe/Global: https://grpc.solanatracker.io
  • North America: https://grpc-us.solanatracker.io
Test both endpoints and use the one with lower latency from your deployment region. Aim for ~1ms latency by co-locating in the same data center.

How do I handle reconnections?

Wrap your connection logic in a retry function:
async function connectWithRetry(maxRetries = 5) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await getClient();
    } catch (e) {
      console.log(`Retry ${i + 1}/${maxRetries}...`);
      await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
    }
  }
  throw new Error("Max retries exceeded");
}

What commitment level should I use?

Commitment levels:
  • PROCESSED - Fastest, but can be rolled back
  • CONFIRMED - Balanced speed and finality (recommended)
  • FINALIZED - Slowest, but guaranteed finalized
For most applications, CONFIRMED is the best choice.

How do I filter transactions?

Use the filter fields in your subscribe request:
transactions: {
  myTransactions: {
    vote: false,                    // Exclude vote transactions
    failed: false,                  // Exclude failed transactions
    accountInclude: ["Address1"],   // Must include any of these (OR)
    accountRequired: ["Address2"],  // Must include all of these (AND)
    accountExclude: ["Address3"],   // Must not include any of these
  }
}

Support & Resources

Support

Get help with your implementation[email protected]

Yellowstone gRPC Source

Complete protobuf definitions and protocol specsView Repository
I