> 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>.
