Skip to main content

Overview

Transaction subscriptions deliver execution results as they are confirmed by the network. You can filter by which accounts are involved, exclude vote transactions, and choose whether to include failed transactions.

Filter Parameters

ParameterTypeDescription
votebooleanInclude (true) or exclude (false) vote transactions. Default: include all.
failedbooleanInclude (true) or exclude (false) failed transactions. Default: include all.
signaturestringMonitor a single specific transaction signature.
accountIncludestring[]Only include transactions that involve any of these accounts (logical OR).
accountExcludestring[]Exclude transactions that involve any of these accounts.
accountRequiredstring[]Only include transactions that involve all of these accounts (logical AND).
accountInclude and accountRequired work together: accountInclude allows any match, while accountRequired enforces that every listed account is present. Combine them to build precise filters.

Example: Monitor a Specific Program

import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";

const GRPC_URL = "https://your-endpoint.grpc.orbitflare.com";
const X_TOKEN = "YOUR_GRPC_TOKEN";
const PING_INTERVAL_MS = 30_000;

const client = new Client(GRPC_URL, X_TOKEN, {
  "grpc.max_receive_message_length": 64 * 1024 * 1024,
});

async function main() {
  const stream = await client.subscribe();

  const streamClosed = new Promise<void>((resolve, reject) => {
    stream.on("error", (error) => { reject(error); stream.end(); });
    stream.on("end", () => resolve());
    stream.on("close", () => resolve());
  });

  stream.on("data", (data) => {
    if (data.transaction) {
      const { transaction, slot } = data.transaction;
      const sig = Buffer.from(transaction.signature).toString("base64");
      const failed = transaction.meta?.err != null;
      console.log(`[slot ${slot}] ${failed ? "FAILED" : "OK"} tx: ${sig}`);
    } else if (data.pong) {
      console.log("Pong received");
    }
  });

  const request: SubscribeRequest = {
    transactions: {
      raydiumSwaps: {
        vote: false,
        failed: false,
        accountInclude: [
          "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", // Raydium AMM v4
        ],
        accountExclude: [],
        accountRequired: [],
      },
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {},
    accountsDataSlice: [],
    slots: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    ping: { id: 1 },
  };

  await new Promise<void>((resolve, reject) => {
    stream.write(request, (err) => {
      if (err == null) resolve(); else reject(err);
    });
  });

  setInterval(() => {
    stream.write({ ping: { id: 1 }, accounts: {}, accountsDataSlice: [], transactions: {}, transactionsStatus: {}, slots: {}, blocks: {}, blocksMeta: {}, entry: {} }, () => {});
  }, PING_INTERVAL_MS);

  await streamClosed;
}

main();

Example: Monitor Token Program Transfers with Parsed Output

This example parses the raw buffer fields into readable strings using bs58:
import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";
import bs58 from "bs58";

const GRPC_URL = "https://your-endpoint.grpc.orbitflare.com";
const X_TOKEN = "YOUR_GRPC_TOKEN";

function toBase58(buf: Buffer | Uint8Array | null | undefined): string {
  if (!buf || buf.length === 0) return "";
  return bs58.encode(buf instanceof Buffer ? buf : Buffer.from(buf));
}

const client = new Client(GRPC_URL, X_TOKEN, {
  "grpc.max_receive_message_length": 1024 * 1024 * 1024, // 1 GiB
});

async function main() {
  const stream = await client.subscribe();

  stream.on("data", (data) => {
    if (!data.transaction) return;
    const tx = data.transaction.transaction;
    const sig = toBase58(tx.signature);
    const accounts = tx.transaction?.message?.accountKeys?.map(toBase58) ?? [];
    console.log(`Tx: ${sig}`);
    console.log(`Accounts: ${accounts.join(", ")}`);
  });

  const request: SubscribeRequest = {
    transactions: {
      tokenTransfers: {
        vote: false,
        failed: false,
        accountInclude: [
          "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // SPL Token
        ],
        accountExclude: [],
        accountRequired: [],
      },
    },
    commitment: CommitmentLevel.PROCESSED,
    accounts: {},
    accountsDataSlice: [],
    slots: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
  };

  await new Promise<void>((resolve, reject) => {
    stream.write(request, (err) => {
      if (err == null) resolve(); else reject(err);
    });
  });

  const streamClosed = new Promise<void>((resolve, reject) => {
    stream.on("error", (e) => { reject(e); stream.end(); });
    stream.on("end", () => resolve());
    stream.on("close", () => resolve());
  });

  await streamClosed;
}

main();

Common Use Cases

Use CaseFilter Strategy
Monitor a DEX for swapsaccountInclude: [dexProgramId], vote: false
Detect wallet activityaccountInclude: [walletPubkey], vote: false, failed: false
Watch a specific token mintaccountInclude: [mintAddress]
Track all non-vote, successful txsvote: false, failed: false, no account filter
Monitor a single transactionsignature: "txSignatureHere"