# Old gRPC Docs

A gRPC plugin for Solana is a tool that allows you to get real-time updates from the Solana blockchain. **Yellowstone gRPC** is one such high-performance Solana Geyser plugin that allows you to stream real-time blockchain data via gRPC interfaces. This powerful tool enables developers to:

* **Monitor on-chain activities:** Track token mints, program interactions, and state changes.
* **Stream account states:** Efficiently retrieve account information.
* **Track transactions:** Monitor transactions with minimal latency.

In short, this can be used to build applications that can respond quickly to changes on the blockchain.

## Resources and replits on Shyft gRPCs

You can explore examples of gRPC and gRPC Subscriptions on

* Shyft [GitHub](https://github.com/Shyft-to/solana-defi)
* Shyft [Replit](https://replit.com/@shyft-to)
* Shyft [Blogs](https://blogs.shyft.to/)

You can also join [Shyft's discord](https://discord.gg/8JyZCjRPmr) for support and more resources.&#x20;

{% hint style="info" %}
Unlike regular RPCs which are used to interact with the Solana blockchain by sending HTTP POST requests, gRPCs are majorly used for streaming real-time updates on Solana with minimum latency.
{% endhint %}

## What are Subscribe Requests?&#x20;

Real-time updates in Solana’s Yellowstone gRPC plugins rely on Subscription streams. These streams let you receive updates like account changes, transactions, new blocks, or slot updates directly to your backend. To keep things focused and avoid unnecessary data, a subscription request lets you specify exactly what type of updates you need.&#x20;

Subscribe requests on gRPC look somewhat like this.

```typescript
import { CommitmentLevel } from "@triton-one/yellowstone-grpc";

const req: SubscribeRequest = {
  accounts: {},
  slots: {},
  transactions: {},
  transactionsStatus: {},
  entry: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  ping: undefined,
  commitment: CommitmentLevel.CONFIRMED,
};
```

Most of the request parameters here are self-explanatory, working exactly with what they are named,

* `accounts`**:** You can subscribe to specific accounts (e.g., SOL-USDC OpenBook) by specifying this parameter and receive updates based on commitment levels (processed, confirmed, finalized).
* `accountDataSlice`: This field helps you to filter your gRPC stream, so that you receive only the relevant portion of streamed data. For example you are streaming accounts, for which the data size is 200bytes, but you only need 40 bytes after a certain offset. This field can help you filter those 40 bytes for every update in the stream.
* `transactions` & `transactionsStatus`: You can receive updates on all transactions or filter them based on specific criteria (vote/failed transactions, including/excluding accounts). Programs can also be monitored using this.
* `slots`, `blocks` & `blocksMeta` **:** Stay informed about new blocks and slots being produced on the blockchain.
* `commitment`: This specifies the commit level for any update, either `processed`, `confirmed` or `finalized`.

## Subscribing to Transactions

A subscribe request defines the type of updates you want using filters. Filters allow you to set specific conditions—like monitoring a particular wallet, account, or transaction type—ensuring that you only receive updates relevant to your needs. We can subscribe to transactions using the transactions filter. The transactions filter has the following structure. The most important field here is the `accountInclude` **field which streams all transactions related to the account addresses specified there**.

```json
{
  "slots": {
    "slots": {}
  },
  "accounts": {},
  "transactions": {
    "transactionLabel": 
      {
          "vote": boolean | undefined, //optional
	  "failed": boolean | undefined, //optional
	  "signature": string | undefined, //optional
	  "accountInclude": string[], //updates streamed for these accounts
	  "accountExclude": string[], //updates for this will be excluded
          "accountRequired": string[] 
      }
  },
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.CONFIRMED //finalized or processed also available
}
```

### Subscribing to all transactions of a program

This request subscribes to all transactions of a program.

{% code overflow="wrap" %}

```json
{
  "slots": {
    "slots": {}
  },
  "accounts": {},
  "transactions": {
    "raydiumPoolv4": {
      "vote": false,
      "failed": false,
      "accountInclude": [
        "7cPdWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFuk" //program address for which you want to stream transaction
      ]
    }
  },
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.CONFIRMED
}
```

{% endcode %}

The transactions filter helps you focus on transactions from a specific program. The first field in the filter (e.g., `raydiumPoolv4`in the above case) is a **client-assigned label**, allowing you to easily identify updates, especially when using multiple filters. The `vote` and `failed` fields are simple true/false options: set them to true to include vote or failed transactions, or false to exclude them. Lastly, **the** `accountInclude` **field specifies the program's address, ensuring you only stream transactions related to that program**.

{% hint style="info" %}
For transactions, if all fields are empty, then all transactions are broadcasted. Otherwise, fields work as logical `AND`, and values in arrays as logical `OR`.
{% endhint %}

### Subscribing to all transactions of a Liquidity Pool

```json
{
  "slots": {
    "slots": {}
  },
  "accounts": {},
  "transactions": {
    "raydiumPoolv4": {
      "vote": false,
      "failed": false,
      "accountInclude": [
        "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin" //liquidity pool address
      ]
    }
  },
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.CONFIRMED
}
```

To receive transactions of a liquidity Pool, we have to specify the liquidity pool address in the `accountInclude` field.

### Subscribing to all transactions of multiple wallets

```json
{
  "slots": {
    "slots": {}
  },
  "accounts": {},
  "transactions": {
    "raydiumPoolv4": {
      "vote": false,
      "failed": false,
      "accountInclude": [
        "HgQy5bqJd3GcjqakukhfMpqSjF7jEYxGiqAqh4QtTuHF",
        "8pQYy5peKKqKk34BvJBuuBAfP62nTLsmT2MVSzijUgt1" //the list of wallet addresses
      ]
    }
  },
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.CONFIRMED
}
```

The `accountInclude` field is an array and can take multiple wallet addresses, and will subscribe to all transactions from them.

## Subscribing to Accounts

To receive account updates we use the accounts filter of the Subscribe request. The account filter has the following structure.

{% code overflow="wrap" %}

```json
{
  "slots": {},
  "accounts": {
      "accountLabel": {
        "account": string[], //account updates for these accounts 
        "owner": string[], //account updates for account with these owners
	"filters": {
	  "memcmp": {bytes and offset}  | undefined;
	  "datasize": string | undefined;
          "tokenAccountState": boolean | undefined;
        } 
  },
  "transactions": {},
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.CONFIRMED //commitment level, can be finalized or processed as well
}
```

{% endcode %}

Similar to the transactions filter, the first field under the accounts filter is the `accountLabel`, a user-defined label that helps you identify updates, especially when working with multiple filters. The `account` field specifies an array of account addresses for streaming account updates. The `owner` field streams updates for accounts owned by the specified addresses. Additionally, you can refine the data further by adding filters based on memcmp values, such as `bytes` and `dataSize`.

{% hint style="info" %}
The "key" at the start of all filters, (e.g. accountLabel, txnLabel) is a client-assigned label and can be set to any user-defined names.&#x20;
{% endhint %}

### Subscribe to account updates for a program

{% code overflow="wrap" %}

```json
{
  "slots": {},
  "accounts": {
    "pumpfun": {
      "owner": ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"] //account updates will be streamed for accounts with this owner
    }
  },
  "transactions": {},
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.PROCESSED
}
```

{% endcode %}

To stream all account updates for a program, use the `account` field under the accounts filter. The `owner` field should specify the program's address, as all accounts belonging to the program are owned by the program address itself.

### Subscribe to account updates of an address

{% code overflow="wrap" %}

```json
{
  "slots": {
    "slots": {}
  },
  "accounts": {
    "sol/usdc": {
      "account": ["9AnFgHoXFysVcuFFX7QztDmzuH8r5ZFvyP4sYwn1XTj9"] // pool address when streaming pool updates
    }
  },
  "transactions": {},
  "blocks": {},
  "blocksMeta": {},
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.CONFIRMED
};
```

{% endcode %}

The `account` array accepts the pool address for which updates are being streamed. This is especially useful when monitoring the state of specific accounts, such as those in liquidity pools, to track changes in real time.

### Subscribe to account updates using Memory compare (memcmp)

`memcmp` filters allow you to match specific portions of binary data within accounts, helping you include only those account updates that meet specific criteria. This makes them especially useful for targeting specific states or values in program-owned accounts. For instance, you can use a `memcmp` filter to track liquidity pool balances, monitor token ownership, or identify program-specific flags. A `memcmp` filter typically specifies three key parameters: `offset`, which defines the starting byte position in the account data to compare; `bytes`, the value to match at the specified offset; and Encoding (optional), which determines how the bytes are encoded, such as base64 or base58.

```json
{
  "slots": {},
  "accounts": {
    "raydium": {
      "account": [],
      "filters": [
        {
          "memcmp": {
            "offset": LIQUIDITY_STATE_LAYOUT_V4.offsetOf('marketProgramId').toString(), 
            "base58": "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"
          }
        }
      ],
      "owner": ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"] 
    }
  },
  "transactions": {},
  "blocks": {},
  "blocksMeta": {
    "block": []
  },
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.PROCESSED,
  "entry": {},
  "transactionsStatus": {}
}
```

For instance, this subscribe request streams updates for Raydium pool accounts with a `marketProgramId` equal to *serum*. The filter targets the `marketProgramId` field of the account, ensuring updates are streamed only for matching accounts.

## Streaming Block Updates

With gRPC, you can stream Solana blocks as they are produced. However, to reduce network load, **Shyft requires at least one filter to be added**. Only blocks matching the filter criteria will be streamed. The blocks filter has a specific structure to define these criteria.

{% hint style="info" %}
We need atleast one filter for streaming blocks with Shyft gRPCs
{% endhint %}

{% code overflow="wrap" %}

```json
{
  "slots": {},
  "accounts": {},
  "transactions": {},
  "blocks": {
    "blockLabel": {
	"accountInclude": string[],
	"includeTransactions": boolean | undefined, //optional
	"includeAccounts": boolean | undefined, //optional
	"includeEntries": boolean | undefined //optional
     }
  },
  "blocksMeta": {
    "block": []
  },
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.PROCESSED, // Subscribe to processed blocks for the fastest updates, confirmed and finalized also available
  "entry": {},
  "transactionsStatus": {}
}
```

{% endcode %}

To stream transactions or accounts involving specific accounts, you can use the `accountInclude` field to filter for those updates. `includeAccounts` and `includeTransactions` are simply *boolean* flags which work as they are named.

```json
{
  "slots": {},
  "accounts": {},
  "transactions": {},
  "blocks": {
    "blocks": {
      "accountInclude": ["So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo"]
    }
  },
  "blocksMeta": {},
  "accountsDataSlice": []
};
```

## Subscribing to BlocksMeta

The `blocksMeta` subscription is useful when you only need updates about blocks being processed, not the full block data. The blocksMeta subscription has the following request format:

```json
{
  "slots": {},
  "accounts": {},
  "transactions": {},
  "blocks": {},
  "blocksMeta": {
    "blockmetadata": {}
  },
  "accountsDataSlice": []
}
```

## **Modifying and Unsubscribing**

* **Modifying Subscriptions:** The subscription stream allows bi-directional communication. You can update your subscription filters dynamically by sending a new request string.
* **Unsubscribing:** Send an empty subscription request to stop receiving updates on all streams. This will keep the connection open for future subscriptions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.shyft.to/old-grpc-docs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
