> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Wie man transactionSubscribe verwendet

> Streamen Sie Echtzeit-Updates zu Solana-Transaktionen mit `transactionSubscribe`. Überwachen Sie Blockchain-Aktivitäten, filtern Sie nach Konten und erhalten Sie sofortige Benachrichtigungen.

## Was ist `transactionSubscribe`?

Die `transactionSubscribe` WebSocket-Methode (eine Helius-Erweiterung der standardmäßigen Solana WebSocket API) ermöglicht Echtzeit-Transaktionsereignisse.

Um sie zu verwenden, geben Sie eine `TransactionSubscribeFilter` an und fügen Sie optional `TransactionSubscribeOptions` für weitere Anpassungen hinzu.

`transactionSubscribe` befindet sich auf denselben einheitlichen `wss://mainnet.helius-rpc.com` und `wss://devnet.helius-rpc.com` [Endpoints](https://www.helius.dev/docs/api-reference/endpoints) wie die standardmäßigen Solana-Subscription-Methoden.

### `TransactionSubscribeFilter`

* `vote`: Boolean-Flag zum Ein-/Ausschließen von wahlbezogenen Transaktionen
* `failed`: Boolean-Flag zum Ein-/Ausschließen von fehlgeschlagenen Transaktionen
* `signature`: filtert Updates zu einer bestimmten Transaktion basierend auf ihrer Signatur
* `accountInclude`: Liste von Konten, für die Sie Transaktionsupdates erhalten möchten. Nur eines der Konten muss in den Transaktionsupdates enthalten sein (z.B. Konto 1 ODER 2).
* `accountExclude`: Liste von Konten, die Sie von Transaktionsupdates ausschließen möchten
* `accountRequired`: Transaktionen müssen alle angegebenen Konten enthalten, um in Updates eingeschlossen zu werden (z.B. Konto 1 UND 2)
* `tokenAccounts`: Opt-in-Erweiterung des zugeordneten Token-Kontos (ATA) (`balanceChanged`, `all`, oder `none`). Siehe [Ein Wallet beobachten, einschließlich Token-Transfers](#ein-wallet-beobachten-einschließlich-token-transfers) unten.

<Tip>
  Sie können bis zu 50.000 Adressen in den `accountInclude`, `accountExclude` und `accountRequired` Arrays einschließen.
</Tip>

### TransactionSubscribeOptions (Optional)

* `commitment`: Commitment-Level zum Abrufen von Daten (`processed`, `confirmed`, oder `finalized`)
* `encoding`: Kodierungsformat der zurückgegebenen Daten (`base58`, `base64`, oder `jsonParsed`)
* `transactionDetails`: Detaillierungsgrad der zurückgegebenen Daten (`full`, `signatures`, `accounts` und `none`)
* `showRewards`: Boolean-Flag, das angibt, ob Belohnungsdaten in den Updates enthalten sein sollen
* `maxSupportedTransactionVersion`: gibt die höchste Version von Transaktionen an, von der Sie Updates erhalten möchten. Setzen Sie den Wert auf `1`, um Legacy-, v0- und v1-Transaktionen zu erhalten. Siehe [Unterstützung für Transaktionen v1](/docs/de/rpc/transaction-v1).

<Info>
  `maxSupportedTransactionVersion` ist erforderlich, um die Konten und vollständigen Details einer bestimmten Transaktion zurückzugeben (d.h. `transactionDetails: "accounts" | "full"`).
</Info>

## Transaktionsabonnement-Beispiel

In diesem Beispiel abonnieren wir Transaktionen, die das Raydium-Konto `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` enthalten.

Wenn eine Transaktion auftritt, die das `675k...1Mp8` Konto in der `accountKeys` der Transaktion enthält, erhalten wir eine WSS-Benachrichtigung.

Basierend auf den Abonnementoptionen wird die Transaktionsbenachrichtigung auf dem `processed` Commitment-Level, `jsonParsed` Kodierung, `full` Transaktionsdetails gesendet und zeigt Belohnungen an.

<CodeGroup>
  ```javascript theme={"system"}
  const WebSocket = require('ws');

  // Create a WebSocket connection
  const ws = new WebSocket('wss://mainnet.helius-rpc.com/?api-key=<API_KEY>');

  // Function to send a request to the WebSocket server
  function sendRequest(ws) {
      const request = {
          jsonrpc: "2.0",
          id: 420,
          method: "transactionSubscribe",
          params: [
              {
                  accountInclude: ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"]
              },
              {
                  commitment: "processed",
                  encoding: "jsonParsed",
                  transactionDetails: "full",
                  showRewards: true,
                  maxSupportedTransactionVersion: 1
              }
          ]
      };
      ws.send(JSON.stringify(request));
  }

  // Function to send a ping to the WebSocket server
  function startPing(ws) {
      setInterval(() => {
          if (ws.readyState === WebSocket.OPEN) {
              ws.ping();
              console.log('Ping sent');
          }
      }, 30000); // Ping every 30 seconds
  }

  // Define WebSocket event handlers

  ws.on('open', function open() {
      console.log('WebSocket is open');
      sendRequest(ws);  // Send a request once the WebSocket is open
      startPing(ws);    // Start sending pings
  });

  ws.on('message', function incoming(data) {
      const messageStr = data.toString('utf8');
      try {
          const messageObj = JSON.parse(messageStr);
          console.log('Received:', messageObj);
      } catch (e) {
          console.error('Failed to parse JSON:', e);
      }
  });

  ws.on('error', function error(err) {
      console.error('WebSocket error:', err);
  });

  ws.on('close', function close() {
      console.log('WebSocket is closed');
  });
  ```
</CodeGroup>

### Beispielbenachrichtigung

<CodeGroup>
  ```json theme={"system"}
  {
      "jsonrpc": "2.0",
      "method": "transactionNotification",
      "params": {
          "subscription": 4743323479349712,
          "result": {
              "transaction": {
                  "transaction": [
                      "Ae6zfSExLsJ/E1+q0jI+3ueAtSoW+6HnuDohmuFwagUo2BU4OpkSdUKYNI1dJfMOonWvjaumf4Vv1ghn9f3Avg0BAAEDGycH0OcYRpfnPNuu0DBQxTYPWpmwHdXPjb8y2P200JgK3hGiC2JyC9qjTd2lrug7O4cvSRUVWgwohbbefNgKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0HcpwKokfYDDAJTaF/TWRFWm0Gz5/me17PRnnywHurMBAgIAAQwCAAAAoIYBAAAAAAA=",
                      "base64"
                  ],
                  "meta": {
                      "err": null,
                      "status": {
                          "Ok": null
                      },
                      "fee": 5000,
                      "preBalances": [
                          28279852264,
                          158122684,
                          1
                      ],
                      "postBalances": [
                          28279747264,
                          158222684,
                          1
                      ],
                      "innerInstructions": [],
                      "logMessages": [
                          "Program 11111111111111111111111111111111 invoke [1]",
                          "Program 11111111111111111111111111111111 success"
                      ],
                      "preTokenBalances": [],
                      "postTokenBalances": [],
                      "rewards": null,
                      "loadedAddresses": {
                          "writable": [],
                          "readonly": []
                      },
                      "computeUnitsConsumed": 0
                  }
              },
              "signature": "5moMXe6VW7L7aQZskcAkKGQ1y19qqUT1teQKBNAAmipzdxdqVLAdG47WrsByFYNJSAGa9TByv15oygnqYvP6Hn2p",
              "slot": 224341380,
              "transactionIndex": 42
          }
      }
  }
  ```
</CodeGroup>

## Ein Wallet beobachten, einschließlich Token-Transfers

Wenn Sie ein Wallet mit `accountInclude` beobachten, stimmen Sie nur Transaktionen zu, bei denen der Wallet-Pubkey direkt in den Kontoschlüsseln erscheint. Ein häufiger Fall rutscht durch: Wenn jemand dem Wallet ein SPL-Token (z.B. USDC) sendet, berührt der Transfer das **zugeordnete Token-Konto (ATA)** des Wallets, nicht den Wallet-Pubkey — daher sieht ein einfaches `accountInclude: [wallet]` Abonnement es nie.

Setzen Sie das `tokenAccounts` Feld, um das Matching zu erweitern, sodass das beobachtete Konto auch Transaktionen zugeordnet wird, bei denen es **einen Token-Saldo** besitzt:

* `balanceChanged`: passt, wenn das Wallet einen Token-Saldo besitzt, dessen Betrag sich geändert hat (oder dessen Token-Konto geschlossen wurde) in der Transaktion. Verwenden Sie dies für "Sag mir, wann tatsächlich Geld bewegt wurde." Dies ist die engere, volumenärmere und häufigste Wahl.
* `all`: passt auf jede Transaktion, die sich auf einen Token-Saldo bezieht, den das Wallet besitzt, auch wenn er unverändert ist. Höheres Volumen.
* `none`: keine Erweiterung. Gleich wie das Weglassen des Feldes (der Standard).

Das Matching basiert auf dem Eigentümer: Es erfasst jedes Token-Konto, das das Wallet besitzt, einschließlich nicht-kanonischer, nicht nur der abgeleiteten ATA-Adresse. Ein ungültiger Wert gibt den JSON-RPC-Fehler `-32602` zurück. Abonnements, die `tokenAccounts` weglassen, verhalten sich genau wie zuvor. Für einen vollständigen Überblick darüber, wie ATA-Erweiterung funktioniert, siehe [Token-Konto-(ATA)-Filterung über WebSocket](/docs/de/rpc/websocket/token-account-filtering).

```javascript theme={"system"}
const ws = new WebSocket('wss://mainnet.helius-rpc.com/?api-key=<API_KEY>');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'transactionSubscribe',
    params: [
      {
        accountInclude: ['<WALLET_PUBKEY>'],
        tokenAccounts: 'balanceChanged' // also match the wallet's ATAs
      },
      { commitment: 'confirmed', encoding: 'jsonParsed', maxSupportedTransactionVersion: 1 }
    ]
  }));
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  const result = msg.params?.result;
  if (!result) return;
  // Token balances this wallet owns that changed in the tx
  const owned = (result.transaction.meta.postTokenBalances || [])
    .filter((b) => b.owner === '<WALLET_PUBKEY>');
  console.log(result.signature, owned);
});
```

## Überwachung neuer Jupiter-DCA

Jupiter DCA oder Dollar-Cost-Averaging ist eine Möglichkeit, wiederkehrende Trades auf Solana zu planen. Da diese geplanten Kauf-/Verkaufsaufträge on-chain erfasst werden, können Trader die Methode `transactionSubscribe` und [`getAsset`](/docs/de/api-reference/das/getasset) verwenden, um auf neue Aufträge zu hören.

<CodeGroup>
  ```javascript theme={"system"}
  const WebSocket = require('ws');   
  const bs58      = require('bs58').default;

  /* ───────────────────── 1.  CONFIG ──────────────────────────── */
  const API_KEY   = process.env.HELIUS_API_KEY || (() => { throw new Error('Set HELIUS_API_KEY'); })();
  const HELIUS_WS  = `wss://mainnet.helius-rpc.com?api-key=${API_KEY}`;
  const HELIUS_RPC = `https://mainnet.helius-rpc.com/?api-key=${API_KEY}`;
  const DCA_PROGRAM_ID = 'DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M';

  /* ───────────────────── 2.  BINARY DECODER ──────────────────── */
  function decodeOpenDcaV2(base58Data) {
    const buf = Buffer.from(bs58.decode(base58Data));
    return {
      appIdx:    buf.readBigUInt64LE(8), // Application Index
      inAmount:  buf.readBigUInt64LE(16), // Input Amount
      perCycle:  buf.readBigUInt64LE(24), // Per Cycle
      interval:  buf.readBigUInt64LE(32) // Interval
    };
  }

  const TOKEN_META = new Map();   // mint → { symbol, decimals }
  /**
   * Fetch symbol & decimals for a mint once then cache.
   * Uses Helius getAsset DAS method: https://www.helius.dev/docs/api-reference/das/getasset
   */
  async function getMeta(mint) {
    if (TOKEN_META.has(mint)) return TOKEN_META.get(mint);

    const body = {
      jsonrpc: '2.0',
      id:      'meow',
      method:  'getAsset',
      params:  { id: mint, displayOptions: { showFungible: true } }
    };

    const { result } = await fetch(HELIUS_RPC, {
      method:  'POST',
      headers: { 'Content-Type': 'application/json' },
      body:    JSON.stringify(body)
    }).then(r => r.json());

    const tokenInfo = result.token_info || {};
    const metadata = { symbol: tokenInfo.symbol || '?', decimals: tokenInfo.decimals ?? 0 };
    TOKEN_META.set(mint, metadata);
    return metadata;
  }

  /* ───────────────────── 4.  PRETTY HELPERS ──────────────────── */
  function formatTimestamp(unixSeconds) {
      return new Date(Number(unixSeconds) * 1_000)
               .toISOString()
               .replace('T', ' ')
               .replace('.000Z', ' UTC');
  }
  function formatInterval(seconds) {
      if (seconds % 86_400 === 0) return `every ${seconds / 86_400}d`;
      if (seconds %  3_600 === 0) return `every ${seconds /  3_600}h`;
      if (seconds %     60 === 0) return `every ${seconds /     60}m`;
      return `every ${seconds}s`;
    }

    function formatAmount(raw, decimals, symbol) {
      const ui = Number(raw) / 10 ** decimals;
      return `${ui} ${symbol}`;
    }
  /* ───────────────────── 5.  WEBSOCKET SETUP ─────────────────── */
  const ws = new WebSocket(HELIUS_WS);

  ws.on('open', () => {
    ws.send(JSON.stringify({
      jsonrpc: '2.0',
      id:      1,
      method:  'transactionSubscribe',
      params: [
        { failed: false, accountInclude: [DCA_PROGRAM_ID] },
        {
          commitment: 'confirmed',
          encoding:   'jsonParsed',
          transactionDetails: 'full',
          maxSupportedTransactionVersion: 1
        }
      ]
    }));

    setInterval(() => ws.ping(), 10_000);
  });

  /* ───────────────────── 6.  MAIN MESSAGE HANDLER ────────────── */
  ws.on('message', async raw => {
    const payload = JSON.parse(raw);
    const result  = payload.params?.result;
    if (!result) return;

    // Look for the `OpenDcaV2` log message
    const logs = result.transaction.meta.logMessages || [];
    if (!logs.some(l => l.includes('OpenDcaV2'))) return;

    // loop through all instructions in the transaction to find the DCA instruction
    for (const ix of result.transaction.transaction.message.instructions) {
      if (ix.programId !== DCA_PROGRAM_ID) continue;

      try {
        // 1) decode binary payload
        const d = decodeOpenDcaV2(ix.data);

        // 2) fetch token symbols / decimals (cached)
        const [inMeta, outMeta] = await Promise.all([
          getMeta(ix.accounts[3]),   // input mint
          getMeta(ix.accounts[4])    // output mint
        ]);

        // 3) create a nice looking table
        console.table({
          user:        ix.accounts[2],
          pair:        `${inMeta.symbol} → ${outMeta.symbol}`,
          opened:      formatTimestamp(d.appIdx),
          'total in':  formatAmount(d.inAmount,  inMeta.decimals, inMeta.symbol),
          'per cycle': formatAmount(d.perCycle,  inMeta.decimals, inMeta.symbol),
          interval:    formatInterval(Number(d.interval))
        });
      } catch (e) {}
    }
  });

  ws.on('error', console.error);

  ws.on('close', () => process.exit(1));
  ```
</CodeGroup>

### Beispielbenachrichtigung

<Frame>
  <img src="https://mintcdn.com/helius/RGuN9Tphu9J_7kRM/images/enhanced-websockets-example-1.png?fit=max&auto=format&n=RGuN9Tphu9J_7kRM&q=85&s=0cbc0eb2c0eecf83b37217011cb9e3c7" alt="Terminal-Tabellen neuer Jupiter-DCA-Aufträge, die das Benutzer-Wallet, das Token-Paar, die Öffnungszeit, die Gesamteingabe, den Betrag pro Zyklus und das Intervall zeigen" width="566" height="622" data-path="images/enhanced-websockets-example-1.png" />
</Frame>

## Überwachung neuer pump.fun-Token

<CodeGroup>
  ```javascript theme={"system"}
  const WebSocket = require('ws');

  const KEY    = process.env.HELIUS_API_KEY ?? (() => { throw new Error('Set HELIUS_API_KEY'); })();
  const WS_URL = `wss://mainnet.helius-rpc.com?api-key=${KEY}`;
  const PUMP_FUN_PROG = '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P';

  /* ────────── 2.  OPEN WEBSOCKET & SUBSCRIBE ──────────────────── */
  const ws = new WebSocket(WS_URL);

  ws.on('open', () => {
    ws.send(JSON.stringify({
      jsonrpc : '2.0',
      id      : 1,
      method  : 'transactionSubscribe',
      params  : [
        { failed:false, accountInclude:[PUMP_FUN_PROG] },
        { commitment:'confirmed', encoding:'jsonParsed',
          transactionDetails:'full', maxSupportedTransactionVersion:1 }
      ]
    }));
    // ping every 10 s so we don't get dropped
    setInterval(() => ws.ping(), 10_000);
  });

  /* ────────── 3.  MESSAGE HANDLER ─────────────────────────────── */
  ws.on('message', raw => {
    const payload = JSON.parse(raw);
    const result  = payload.params?.result;
    if (!result) return;

    const logs = result.transaction.meta.logMessages || [];
    // filter for the pump.fun "InitializeMint2" log
    if (!logs.some(l => l.includes('Instruction: InitializeMint2'))) return;

    const sig   = result.signature;    // transaction signature
    const keys  = result.transaction.transaction.message.accountKeys
                               .map(k => k.pubkey);
    //   keys[0] → creator wallet
    //   keys[1] → the new token
    console.table({
      tx:      sig,
      creator: keys[0],
      token:   keys[1]
    });
  });

  ws.on('error', console.error);
  ws.on('close', () => process.exit(1));  
  ```
</CodeGroup>

### Beispielbenachrichtigung

<Frame>
  <img src="https://mintcdn.com/helius/RGuN9Tphu9J_7kRM/images/enhanced-websockets-example-2.png?fit=max&auto=format&n=RGuN9Tphu9J_7kRM&q=85&s=8febc28503381b0da3cd0f1bb40459cb" alt="Terminal-Tabellen neu erstellter pump.fun-Token, die die Transaktionssignatur, das Ersteller-Wallet und die Token-Mint-Adresse zeigen" width="738" height="355" data-path="images/enhanced-websockets-example-2.png" />
</Frame>

## Verwaltung von Abonnements

### Abonnement-IDs

Wenn `transactionSubscribe` erfolgreich ist, gibt der Server eine Abonnement-ID im `result` Feld zurück. Dies ist die gleiche Nummer, die in `params.subscription` bei jeder Benachrichtigung von diesem Abonnement erscheint:

<CodeGroup>
  ```json Subscribe Response theme={"system"}
  {
    "jsonrpc": "2.0",
    "result": 4743323479349712,
    "id": 420
  }
  ```

  ```json Notification theme={"system"}
  {
    "jsonrpc": "2.0",
    "method": "transactionNotification",
    "params": {
      "subscription": 4743323479349712,
      "result": {}
    }
  }
  ```
</CodeGroup>

Speichern Sie die Abonnement-ID aus der Antwort. Sie benötigen sie, um das Abonnement zu beenden.

### Abbestellen

Um keine Benachrichtigungen mehr zu erhalten, rufen Sie `transactionUnsubscribe` mit der Abonnement-ID auf. Jeder `transactionSubscribe` Aufruf auf derselben Verbindung erstellt ein separates Abonnement mit eigener ID, also stellen Sie sicher, dass Sie sich abmelden, bevor Sie sich erneut anmelden, um doppelte Benachrichtigungen zu vermeiden.

<CodeGroup>
  ```json Request theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 421,
    "method": "transactionUnsubscribe",
    "params": [4743323479349712]
  }
  ```

  ```json Response theme={"system"}
  {
    "jsonrpc": "2.0",
    "result": true,
    "id": 421
  }
  ```
</CodeGroup>

In diesem Beispiel abonnieren wir Raydium-Transaktionen, erfassen die Abonnement-ID aus der Serverantwort und melden uns dann mit dieser ID ab. Einige in-flight Nachrichten können immer noch kurz nach dem Aufruf von `transactionUnsubscribe` ankommen. Dies ist das erwartete Verhalten.

<CodeGroup>
  ```javascript theme={"system"}
  const WebSocket = require('ws');

  const ws = new WebSocket('wss://mainnet.helius-rpc.com/?api-key=<API_KEY>');
  let subscriptionId = null;

  ws.on('open', () => {
      ws.send(JSON.stringify({
          jsonrpc: '2.0',
          id: 420,
          method: 'transactionSubscribe',
          params: [
              { accountInclude: ['675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'] },
              {
                  commitment: 'processed',
                  encoding: 'jsonParsed',
                  transactionDetails: 'full',
                  maxSupportedTransactionVersion: 1,
              },
          ],
      }));
      setInterval(() => ws.ping(), 30000);
  });

  ws.on('message', (data) => {
      const msg = JSON.parse(data.toString());

      // Capture the subscription ID from the subscribe response
      if (msg.id === 420 && msg.result !== undefined) {
          subscriptionId = msg.result;
          console.log('Subscribed, ID:', subscriptionId);
          return;
      }

      // Handle transaction notifications
      if (msg.method === 'transactionNotification') {
          console.log('Received:', msg.params.result.signature);
      }
  });

  function unsubscribe() {
      if (subscriptionId !== null) {
          ws.send(JSON.stringify({
              jsonrpc: '2.0',
              id: 421,
              method: 'transactionUnsubscribe',
              params: [subscriptionId],
          }));
          subscriptionId = null;
      }
  }
  ```
</CodeGroup>
