GRPC

Carbium is the high-performance Layer 2 streaming service for Solana, providing the fastest Full Block gRPC data in the industry.

Built upon the open-source Yellowstone protocol (Layer 1), Carbium optimizes the delivery pipeline to serve comprehensive, atomic block data with industry-leading latency (~22ms). While other providers prioritize raw "shreds" for marginal speed gains, Carbium focuses on data fidelity and parsing efficiency, offering a gold standard stream for sophisticated trading, indexing, and analytics.

The Carbium Difference

In the Solana ecosystem, gRPC providers generally fall into two categories: those who stream Shreds (raw data fragments) and those who stream Full Blocks (complete ledger units).

1. The "Latency Trap"

A common marketing tactic is to advertise "Shred" latency (8–11ms) as superior to "Full Block" latency (22ms). However, this metric is often misleading when viewed against the actual Solana network speed.

MetricLatencyContext
Solana Slot Resolution~400msThe window in which a block is produced
Competitor "Shreds"~9msFragmented data requiring reassembly
Carbium Full Blocks~22msAtomic, complete data ready for use

The Reality: Because Solana slots occur every ~400ms, the 13ms difference between receiving a shred and a full block effectively changes nothing regarding transaction inclusion or execution. You cannot "beat" the slot significantly faster with shreds.

2. Why We Choose Full Blocks (The Gold Standard)

Carbium prioritizes Full Block delivery to provide a robust engineering solution:

  • Atomic Integrity: Receive the complete state update in one go. No partial failures or missing fragments.
  • Parsing Efficiency: Ideal for complex database indexing (Postgres/RocksDB) where data completeness is critical.
  • Simplicity: Reduces the overhead of reassembling shreds on the client side.

Note: We understand some legacy systems prefer shreds. Carbium will be adding a Shreds (Layer 2 Complete) tier soon for users who require that specific ingestion method.


Architecture: From L1 to L2

Carbium is not just a host; it is an optimization layer.

  • Layer 1 (Yellowstone): We utilize the standard, open-source Rust implementation used to interface with Solana's RocksDB.
  • Layer 2 (Carbium): We apply a proprietary optimization pipeline that aggregates shreds into atomic blocks server-side, ensuring maximum fidelity before the data ever reaches your application.

Connection Details

Carbium exposes a WebSocket endpoint that uses JSON-RPC 2.0 protocol with Yellowstone-compatible subscription methods.

Endpoint

wss://grpc.carbium.io

Authentication

MethodFormatUse Case
Query Parameterwss://grpc.carbium.io/?apiKey=YOUR_API_KEYRecommended for WebSocket clients
Headerx-token: YOUR_API_KEYFor HTTP-based connections

Protocol

Carbium uses JSON-RPC 2.0 over WebSocket. Messages are sent as JSON text frames.

Available Methods

MethodDescription
transactionSubscribeSubscribe to real-time transactions with filters
transactionUnsubscribeUnsubscribe from transaction stream

Code Examples

TypeScript / Node.js

import WebSocket from "ws";

const API_KEY = "YOUR_API_KEY";
const PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; // Example: Pump.fun

async function main() {
  const ws = new WebSocket(`wss://grpc.carbium.io/?apiKey=${API_KEY}`);

  ws.on("open", () => {
    console.log("Connected to Carbium");

    // Subscribe to transactions for a specific program
    const request = {
      jsonrpc: "2.0",
      id: 1,
      method: "transactionSubscribe",
      params: [
        {
          // Filter configuration
          vote: false,                        // Exclude vote transactions
          failed: false,                      // Exclude failed transactions
          accountInclude: [PROGRAM_ID],       // Programs to include
          accountExclude: [],                 // Programs to exclude
          accountRequired: [],                // All listed accounts must be present
        },
        {
          // Subscription options
          commitment: "confirmed",            // confirmed | finalized | processed
          encoding: "base64",                 // base64 | base58 | jsonParsed
          transactionDetails: "full",         // full | signatures | none
          showRewards: false,
          maxSupportedTransactionVersion: 0,
        },
      ],
    };

    ws.send(JSON.stringify(request));
  });

  ws.on("message", (data) => {
    const message = JSON.parse(data.toString());

    // Subscription confirmation
    if (message.result !== undefined) {
      console.log(`Subscribed with ID: ${message.result}`);
      return;
    }

    // Transaction notification
    if (message.method === "transactionNotification") {
      const { signature, slot, transaction } = message.params.result;
      console.log(`Transaction: ${signature} (slot ${slot})`);

      // transaction.transaction[0] contains base64-encoded transaction data
      // transaction.meta contains execution metadata
    }
  });

  ws.on("error", (error) => {
    console.error("WebSocket error:", error.message);
  });

  ws.on("close", (code, reason) => {
    console.log(`Disconnected: ${code} - ${reason}`);
  });
}

main();

Transaction Filter Options

The first parameter of transactionSubscribe accepts these filter options:

FieldTypeDescription
votebooleanInclude vote transactions
failedbooleanInclude failed transactions
accountIncludestring[]Include transactions involving ANY of these accounts
accountExcludestring[]Exclude transactions involving these accounts
accountRequiredstring[]Only include transactions involving ALL of these accounts

Important: At least one of accountInclude or accountRequired must contain values.

Subscription Options

The second parameter configures the response format:

FieldTypeDescription
commitmentstringprocessed, confirmed, or finalized
encodingstringbase64, base58, or jsonParsed
transactionDetailsstringfull, signatures, or none
showRewardsbooleanInclude reward information
maxSupportedTransactionVersionnumberMax transaction version (0 for legacy + v0)

Response Format

Subscription Confirmation

{
  "jsonrpc": "2.0",
  "result": 1234567890,
  "id": 1
}

The result is your subscription ID, used for unsubscribing.

Transaction Notification

{
  "jsonrpc": "2.0",
  "method": "transactionNotification",
  "params": {
    "result": {
      "signature": "5VERv8NMvzbJM...",
      "slot": 123456789,
      "transaction": {
        "transaction": ["base64_encoded_data", "base64"],
        "meta": {
          "err": null,
          "fee": 5000,
          "preBalances": [...],
          "postBalances": [...],
          "logMessages": [...]
        }
      }
    },
    "subscription": 1234567890
  }
}

Rust

Using the standard yellowstone-grpc-client crate with HTTP/2 gRPC:

use yellowstone_grpc_client::GeyserGrpcClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let endpoint = "https://grpc.carbium.io";
    let x_token = "YOUR_API_KEY";

    let mut client = GeyserGrpcClient::connect(endpoint, x_token, None)?;
    let (mut subscribe_tx, mut stream) = client.subscribe().await?;

    // Define your subscription filters...

    Ok(())
}

Python

import asyncio
import websockets
import json

API_KEY = "YOUR_API_KEY"
PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"

async def subscribe():
    uri = f"wss://grpc.carbium.io/?apiKey={API_KEY}"

    async with websockets.connect(uri) as ws:
        # Subscribe to transactions
        request = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "transactionSubscribe",
            "params": [
                {
                    "vote": False,
                    "failed": False,
                    "accountInclude": [PROGRAM_ID],
                    "accountExclude": [],
                    "accountRequired": [],
                },
                {
                    "commitment": "confirmed",
                    "encoding": "base64",
                    "transactionDetails": "full",
                    "showRewards": False,
                    "maxSupportedTransactionVersion": 0,
                },
            ],
        }

        await ws.send(json.dumps(request))

        async for message in ws:
            data = json.loads(message)

            if "result" in data:
                print(f"Subscribed: {data['result']}")
            elif data.get("method") == "transactionNotification":
                sig = data["params"]["result"]["signature"]
                print(f"Transaction: {sig[:20]}...")

asyncio.run(subscribe())

Unsubscribing

To unsubscribe, send:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "transactionUnsubscribe",
  "params": [SUBSCRIPTION_ID]
}

Pricing

Carbium gRPC is included in plans $320 and above.


FAQ

Q: Is Carbium compatible with standard Yellowstone clients?

A: Yes for Rust clients using HTTP/2 gRPC. For TypeScript/JavaScript/Python, use the WebSocket JSON-RPC interface as shown in the examples above. The subscription filters and data format follow Yellowstone conventions.

Q: Why is your "Full Block" stream 22ms when others claim 10ms?

A: Those claims usually refer to "shreds" (partial data). Carbium delivers the entire block in 22ms. We are the fastest Full Block provider in the industry.

Q: Does the extra 12ms latency matter for trading?

A: Generally, no. With Solana's slot times averaging 400ms, a 12ms delta is negligible for execution. However, the data quality difference is massive. Full Blocks allow for robust, error-free parsing that shreds cannot match.

Q: What's the difference between accountInclude and accountRequired?

A:

  • accountInclude: Transaction must involve at least one of the listed accounts
  • accountRequired: Transaction must involve all of the listed accounts

For example, to get only token creation transactions for Pump.fun, you might use:

{
  "accountRequired": ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P", "TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM"]
}

Q: Why do I get "Invalid params" errors?

A: Ensure at least one of accountInclude or accountRequired contains values. Empty arrays for both will return an error.


Support


What’s Next