gRPC connection guide

Subglow speaks the Yellowstone Geyser gRPC protocol. Any client written against yellowstone-grpc-proto or @triton-one/yellowstone-grpc works unchanged — swap your endpoint and API key.

Endpoint
grpc.subglow.io:443 (TLS)
Auth
x-api-key: <YOUR_API_KEY> (per-request metadata)

Stream quotas

Paid plans bundle JSON-RPC on the same API key. See /docs/rpc.

Sniper · $99/mo
2 concurrent streams · 50,000 RPC/day bundled
Pro · $249/mo
10 concurrent streams · 500,000 RPC/day bundled

TypeScript / @triton-one/yellowstone-grpc

import Client, {
  CommitmentLevel,
  SubscribeRequest,
} from "@triton-one/yellowstone-grpc";

const client = new Client(
  "https://grpc.subglow.io:443",
  process.env.SUBGLOW_API_KEY!,
  { "grpc.max_receive_message_length": 64 * 1024 * 1024 },
);

const stream = await client.subscribe();

const req: SubscribeRequest = {
  commitment: CommitmentLevel.PROCESSED,
  transactions: {
    pumpfun: {
      accountInclude: ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"], // pump.fun program
      accountExclude: [],
      accountRequired: [],
      vote: false,
      failed: false,
    },
  },
  accounts: {},
  slots: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  transactionsStatus: {},
  accountsDataSlice: [],
};

stream.on("data", (msg) => {
  if (msg.transaction) {
    console.log("tx", msg.transaction.transaction.signature);
  }
});

await new Promise<void>((resolve, reject) => {
  stream.write(req, (err: Error | null) => (err ? reject(err) : resolve()));
});

Rust / yellowstone-grpc-client

use std::{collections::HashMap, env};

use futures::StreamExt;
use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::{
    subscribe_request_filter_transactions::*, CommitmentLevel, SubscribeRequest,
    SubscribeRequestFilterTransactions,
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mut client = GeyserGrpcClient::build_from_shared("https://grpc.subglow.io:443")?
        .x_token(Some(env::var("SUBGLOW_API_KEY")?))?
        .connect()
        .await?;

    let mut txs = HashMap::new();
    txs.insert(
        "pumpfun".to_string(),
        SubscribeRequestFilterTransactions {
            vote: Some(false),
            failed: Some(false),
            signature: None,
            account_include: vec!["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P".into()],
            account_exclude: vec![],
            account_required: vec![],
        },
    );

    let req = SubscribeRequest {
        commitment: Some(CommitmentLevel::Processed as i32),
        transactions: txs,
        ..Default::default()
    };

    let (_sink, mut stream) = client.subscribe_with_request(Some(req)).await?;
    while let Some(update) = stream.next().await {
        let update = update?;
        if let Some(tx) = update.update_oneof {
            println!("{:?}", tx);
        }
    }
    Ok(())
}

Python / grpclib + yellowstone-grpc-proto

import asyncio, os
import grpc
import yellowstone_grpc_proto.geyser_pb2 as g
import yellowstone_grpc_proto.geyser_pb2_grpc as gs

async def main():
    creds = grpc.ssl_channel_credentials()
    call_creds = grpc.metadata_call_credentials(
        lambda ctx, cb: cb([("x-api-key", os.environ["SUBGLOW_API_KEY"])], None)
    )
    composite = grpc.composite_channel_credentials(creds, call_creds)

    async with grpc.aio.secure_channel("grpc.subglow.io:443", composite) as chan:
        stub = gs.GeyserStub(chan)

        req = g.SubscribeRequest(
            commitment=g.PROCESSED,
            transactions={
                "pumpfun": g.SubscribeRequestFilterTransactions(
                    vote=False,
                    failed=False,
                    account_include=["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"],
                )
            },
        )

        async def gen():
            yield req
            while True:
                await asyncio.sleep(3600)

        async for update in stub.Subscribe(gen()):
            if update.HasField("transaction"):
                print(update.transaction.transaction.signature.hex())

asyncio.run(main())

Filter reference

Error codes you should handle

Need plain JSON-RPC too?

The same API key works at rpc.subglow.io for getAccountInfo, sendTransaction, and the rest of Solana's RPC surface.

JSON-RPC connection docs