# Yellowstone gRPC Overview

> High-performance gRPC interface overview, connection setup, and subscription patterns for Yellowstone Dragon's Mouth.

Canonical: https://nolimitnodes.com/docs/api-reference/grpc/overview

NoLimitNodes provides access to the [Yellowstone Dragon's Mouth](https://github.com/rpcpool/yellowstone-grpc) gRPC interface - a high-performance streaming API built on Solana's Geyser plugin architecture.

Yellowstone gRPC enables real-time streaming of accounts, transactions, slots, blocks, and entries with advanced filtering, significantly outperforming traditional WebSocket and polling-based approaches.

## Endpoint

```
grpc.nln.clr3.org:443
```

Authenticate with the `x-api-key` header on every request.

## Key Advantages

- **Low latency** - direct Geyser plugin access, data arrives before RPC processing
- **Rich filtering** - filter by account, owner, program, transaction participants, and more
- **Bidirectional streaming** - update subscription filters without reconnecting
- **Typed data** - Protocol Buffers provide strict typing and efficient serialization

## Service Definition

The Geyser service exposes two bidirectional streaming RPCs and several unary methods:

```protobuf
service Geyser {
  // Bidirectional streaming subscriptions
  rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate) {}
  rpc SubscribeDeshred(stream SubscribeDeshredRequest) returns (stream SubscribeUpdateDeshred) {}

  // Unary methods
  rpc SubscribeReplayInfo(SubscribeReplayInfoRequest) returns (SubscribeReplayInfoResponse) {}
  rpc Ping(PingRequest) returns (PongResponse) {}
  rpc GetLatestBlockhash(GetLatestBlockhashRequest) returns (GetLatestBlockhashResponse) {}
  rpc GetBlockHeight(GetBlockHeightRequest) returns (GetBlockHeightResponse) {}
  rpc GetSlot(GetSlotRequest) returns (GetSlotResponse) {}
  rpc IsBlockhashValid(IsBlockhashValidRequest) returns (IsBlockhashValidResponse) {}
  rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {}
}
```

## Commitment Levels

```protobuf
enum CommitmentLevel {
  PROCESSED = 0;
  CONFIRMED = 1;
  FINALIZED = 2;
}
```

| Level | Value | Description |
|---|---|---|
| `PROCESSED` | 0 | Processed by the connected node (fastest, may be reverted) |
| `CONFIRMED` | 1 | Confirmed by supermajority vote |
| `FINALIZED` | 2 | Finalized by supermajority (most reliable) |

## Connection Keep-Alive

> Note: Some load balancers terminate gRPC connections if the client is idle. The server sends `Ping` messages every 15 seconds - reply with a `SubscribeRequest` containing a `ping` message with an `id` field (any `int32` value) to keep the connection alive.

## Subscribe

The `Subscribe` RPC is a bidirectional stream. The client sends `SubscribeRequest` messages to set or update filters, and the server responds with a continuous stream of `SubscribeUpdate` messages.

```protobuf
rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate) {}
```

## SubscribeRequest

### `accounts`

">
  Named account subscription filters. See [Account Filters](/docs/api-reference/grpc/accounts#subscriberequestfilteraccounts).

### `slots`

">
  Named slot subscription filters. See [Slot Filters](/docs/api-reference/grpc/transactions-slots-blocks#subscriberequestfilterslots).

### `transactions`

">
  Named transaction subscription filters. See [Transaction Filters](/docs/api-reference/grpc/transactions-slots-blocks#subscriberequestfiltertransactions).

### `transactions_status`

">
  Same filters as `transactions`, but only returns status (no full transaction data).

### `blocks`

">
  Named block subscription filters. See [Block Filters](/docs/api-reference/grpc/transactions-slots-blocks#subscriberequestfilterblocks).

### `blocks_meta`

">
  Block metadata filters. See [Block Metadata Filters](/docs/api-reference/grpc/transactions-slots-blocks#subscriberequestfilterblocksmeta).

### `entry`

">
  Entry subscription filters. See [Entry Filters](/docs/api-reference/grpc/transactions-slots-blocks#subscriberequestfilterentry).

### `commitment`, CommitmentLevel

Commitment level: `PROCESSED` (0), `CONFIRMED` (1), `FINALIZED` (2).

### `accounts_data_slice`, array

Array of `{ offset: uint64, length: uint64 }` objects to receive only specific slices of account data.

### `ping`, SubscribeRequestPing

Send a ping to keep the connection alive. Contains a single field: `id` (`int32`) - set to any integer value. The server responds with a `Pong` echoing the same `id`.

### `from_slot`, uint64

Start streaming from this slot (replay support).

## SubscribeUpdate

Each update contains the matched filter names and exactly one update type:

### `filters`, array

Names of the filters that matched this update.

### `update_oneof`, oneof

### Update types

Account data change.

    ### `slot`, SubscribeUpdateSlot

Slot status change.

    ### `transaction`, SubscribeUpdateTransaction

Full transaction data.

    ### `transaction_status`, SubscribeUpdateTransactionStatus

Transaction status only.

    ### `block`, SubscribeUpdateBlock

Full block data.

    ### `block_meta`, SubscribeUpdateBlockMeta

Block metadata only.

    ### `entry`, SubscribeUpdateEntry

Ledger entry.

    ### `ping`, SubscribeUpdatePing

Server ping.

    ### `pong`, SubscribeUpdatePong

Pong response to client ping.

### `created_at`, Timestamp

Server-side timestamp when the update was created.

## Example: Subscribe to All Slots

```typescript TypeScript

// The SDK sends its token argument through x-token metadata
const client = new Client("grpc.nln.clr3.org:443", "YOUR_API_KEY", {
  grpcMaxDecodingMessageSize: 64 * 1024 * 1024,
});

await client.connect();
const stream = await client.subscribe();

stream.on("data", (data) => {
  if (data.slot) {
    console.log(`Slot: ${data.slot.slot}, Status: ${data.slot.status}`);
  }
});

// Send subscription request
const request = {
  slots: {
    mySlots: { filterByCommitment: true },
  },
  commitment: CommitmentLevel.CONFIRMED,
  accounts: {},
  transactions: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
};

stream.write(request);
```

```python Python

# Auth plugin - sends x-api-key as gRPC metadata
class NLNAuth(grpc.AuthMetadataPlugin):
    def __init__(self, api_key):
        self.api_key = api_key
    def __call__(self, context, callback):
        callback([("x-api-key", self.api_key)], None)

ssl_creds = grpc.ssl_channel_credentials()
call_creds = grpc.metadata_call_credentials(NLNAuth("YOUR_API_KEY"))
combined_creds = grpc.composite_channel_credentials(ssl_creds, call_creds)

channel = grpc.secure_channel("grpc.nln.clr3.org:443", credentials=combined_creds)
stub = geyser_pb2_grpc.GeyserStub(channel)

# Create subscription request
request = geyser_pb2.SubscribeRequest(
    slots={"mySlots": geyser_pb2.SubscribeRequestFilterSlots(
        filter_by_commitment=True
    )},
    commitment=geyser_pb2.CONFIRMED,
)

# Subscribe and process updates
for update in stub.Subscribe(iter([request])):
    if update.HasField("slot"):
        print(f"Slot: {update.slot.slot}, Status: {update.slot.status}")
```

## Updating Filters

Since `Subscribe` is bidirectional, you can send a new `SubscribeRequest` at any time to update your filters without reconnecting:

```typescript
// Initial subscription for slots
stream.write({
  slots: { mySlots: {} },
  accounts: {},
  transactions: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.CONFIRMED,
});

// Later: add account subscription without reconnecting
stream.write({
  slots: { mySlots: {} },
  accounts: {
    myAccounts: {
      account: ["vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"],
    },
  },
  transactions: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.CONFIRMED,
});
```

> Warning: Each new `SubscribeRequest` completely replaces the previous filters. Include all desired filters in every request.
