> For the complete documentation index, see [llms.txt](https://docs.shyft.to/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shyft.to/solana-yellowstone-grpc/docs/account-streaming/account-updates-using-memcmp.md).

# Account updates using memcmp

`memcmp` filters allow you to <mark style="color:yellow;">match</mark> specific portions of <mark style="color:yellow;">binary data</mark> within accounts, helping you include only those account updates that <mark style="color:yellow;">meet specific criteria</mark>. 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.

{% tabs %}
{% tab title="TypeScript" %}
{% code overflow="wrap" %}

```typescript
import Client, {
  CommitmentLevel,
  SubscribeRequestAccountsDataSlice,
  SubscribeRequestFilterAccounts,
  SubscribeRequestFilterBlocks,
  SubscribeRequestFilterBlocksMeta,
  SubscribeRequestFilterEntry,
  SubscribeRequestFilterSlots,
  SubscribeRequestFilterTransactions,
} from "@triton-one/yellowstone-grpc";
import { SubscribeRequestPing } from "@triton-one/yellowstone-grpc/dist/grpc/geyser";
import { LIQUIDITY_STATE_LAYOUT_V4 } from "@raydium-io/raydium-sdk";
import bs58 from "bs58";

// Interface for the subscription request structure
interface SubscribeRequest {
  accounts: { [key: string]: SubscribeRequestFilterAccounts };
  slots: { [key: string]: SubscribeRequestFilterSlots };
  transactions: { [key: string]: SubscribeRequestFilterTransactions };
  transactionsStatus: { [key: string]: SubscribeRequestFilterTransactions };
  blocks: { [key: string]: SubscribeRequestFilterBlocks };
  blocksMeta: { [key: string]: SubscribeRequestFilterBlocksMeta };
  entry: { [key: string]: SubscribeRequestFilterEntry };
  commitment?: CommitmentLevel;
  accountsDataSlice: SubscribeRequestAccountsDataSlice[];
  ping?: SubscribeRequestPing;
}

/**
 * Subscribes to the gRPC stream and handles incoming data.
 *
 * @param client - Yellowstone gRPC client
 * @param args - The Subscription request which specifies what data to stream
 */
async function handleStream(client: Client, args: SubscribeRequest) {
  const stream = await client.subscribe();

  // Promise that resolves when the stream ends or errors out
  const streamClosed = new Promise<void>((resolve, reject) => {
    stream.on("error", (error) => {
      console.error("Stream error:", error);
      reject(error);
      stream.end();
    });

    stream.on("end", resolve);
    stream.on("close", resolve);
  });

  // Handle incoming transaction data
  stream.on("data", (data) => {
    if (data?.account) {
      console.log("\nReceived Account Update for:");
      console.log(bs58.encode(data?.account?.account?.pubkey));
      console.log("\n");
      console.log(data?.account);
    }
  });

  // Send the subscription request
  await new Promise<void>((resolve, reject) => {
    stream.write(args, (err: any) => {
      err ? reject(err) : resolve();
    });
  }).catch((err) => {
    console.error("Failed to send subscription request:", err);
    throw err;
  });

  // Wait for the stream to close
  await streamClosed;
}

/**
 * Entry point to start the subscription stream.
 *
 */
async function subscribeCommand(client: Client, args: SubscribeRequest) {
  while (true) {
    try {
      await handleStream(client, args);
    } catch (error) {
      console.error("Stream error, retrying in 1 second...", error);
      await new Promise((resolve) => setTimeout(resolve, 1000));
    }
  }
}

// Instantiate Yellowstone gRPC client with .env credentials
const client = new Client(
  "YOUR-GRPC-ENDPOINT", //Your Region specific gRPC URL
  "YOUR-ACCESS-TOKEN", // your Access Token
  undefined,
);

/**
 * Subscribe Request: The `account` field is for streaming account updates. The `filters` 
 * specify the conditions for the accounts to be streamed. The `owner` field specifies the
 * that involve the specified address in `accountInclude`.
 */
const req: SubscribeRequest = {
  slots: {},
  accounts: {
    sol_usdc: {
      account: [],
      filters: [
        {
          memcmp: {
            offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('marketProgramId').toString(), 
            base58: "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"
          }
        }
      ],
      owner: ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"]
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED, // Subscribe to processed blocks for the fastest updates
  entry: {},
  transactionsStatus: {},
};

// Start the subscription
subscribeCommand(client, req);
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="success" %}
You can copy and paste this code on replit to see it in action, or simply remix [<mark style="color:yellow;">this code</mark>](https://replit.com/@shyft-to/streaming-account-updates-with-filter?v=1) on Replit.
{% endhint %}

For instance, this subscribe request streams updates for Raydium pool accounts with a `marketProgramId` equal to *<mark style="color:yellow;">serum</mark>*. The filter targets the `marketProgramId` field of the account, ensuring updates are streamed only for <mark style="color:yellow;">matching accounts</mark>.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.shyft.to/solana-yellowstone-grpc/docs/account-streaming/account-updates-using-memcmp.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
