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

# Surveillance des Slots et Blocs avec LaserStream

> Surveillez le consensus réseau Solana, la production de blocs et les changements d'état du réseau avec LaserStream — synchronisation des slots, métadonnées des blocs, et blocs complets filtrés.

La surveillance des slots et blocs vous offre une vue sur le consensus du réseau Solana, le timing de production des blocs, et la santé globale. Avec LaserStream, vous pouvez suivre la progression des slots, la finalisation des blocs, et les métriques de performance du réseau en temps réel en utilisant le SDK [`helius-laserstream`](/docs/fr/laserstream/clients).

<Info>
  **Prérequis :** Ce guide suppose que vous avez terminé le [Quickstart LaserStream gRPC](/docs/fr/laserstream/grpc) et que vous possédez une clé API.
</Info>

***

## Types de Surveillance

<Tabs>
  <Tab title="Mises à jour des Slots">
    **Suivez la progression du consensus réseau**

    Surveillez l'avancement des slots à travers les niveaux d'engagement :

    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';

    const subscriptionRequest: SubscribeRequest = {
      slots: {
        slotSubscribe: {
          filterByCommitment: false // Receive all commitment levels
        }
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, transactions: {}, transactionsStatus: {},
      blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
    };
    ```

    **Les données de slot incluent :** numéro de slot, slot parent, statut d'engagement (`processed` / `confirmed` / `finalized`), et informations sur le leader.

    <Note>
      **Idéal pour :** Surveillance de la santé du réseau, analyse de synchronisation des slots, suivi du consensus.
    </Note>
  </Tab>

  <Tab title="Données des Blocs">
    **Surveillez les informations complètes des blocs**

    Diffusez des blocs complets avec transactions et mises à jour de comptes :

    ```typescript theme={"system"}
    const subscriptionRequest: SubscribeRequest = {
      blocks: {
        blockSubscribe: {
          accountInclude: [], // All accounts
          includeTransactions: true,
          includeAccounts: true,
          includeEntries: false
        }
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, transactions: {}, transactionsStatus: {},
      slots: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
    };
    ```

    **Les données des blocs incluent :** métadonnées du bloc, transactions, mises à jour de comptes, synchronisation des blocs.

    <Warning>
      **Volume élevé :** Les flux de blocs complets génèrent beaucoup de données. Utilisez des filtres `accountInclude` pour réduire le volume.
    </Warning>
  </Tab>

  <Tab title="Métadonnées des Blocs">
    **Informations sur les blocs légers**

    Obtenez les métadonnées des blocs sans détails de transaction :

    ```typescript theme={"system"}
    const subscriptionRequest: SubscribeRequest = {
      blocksMeta: {
        blockMetaSubscribe: {}
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, transactions: {}, transactionsStatus: {},
      slots: {}, blocks: {}, entry: {}, accountsDataSlice: [],
    };
    ```

    **Les métadonnées incluent :** hash du bloc, hash parent, slot, hauteur, nombre de transactions, récompenses.

    <Tip>
      **Efficace :** Alternative à faible bande passante à la diffusion complète des blocs.
    </Tip>
  </Tab>
</Tabs>

***

## Exemples Pratiques

### Exemple 1 : Surveillance de la Santé du Réseau

Suivez la progression des slots et identifiez les problèmes du réseau :

```typescript [expandable] theme={"system"}
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';

let lastSlot = 0;
let lastTimestamp = Date.now();
const slotTimes: number[] = [];

// CommitmentLevel only ships the forward (name → number) mapping, so we keep
// a small reverse lookup for the numeric status the SDK returns on slot updates.
const STATUS_NAMES = ['PROCESSED', 'CONFIRMED', 'FINALIZED'] as const;

async function monitorNetworkHealth() {
  const subscriptionRequest: SubscribeRequest = {
    slots: {
      slotSubscribe: {
        filterByCommitment: true // Track processed commitment levels
      }
    },
    commitment: CommitmentLevel.PROCESSED,
    accounts: {}, transactions: {}, transactionsStatus: {},
    blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
  };

  const config: LaserstreamConfig = {
    apiKey: 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  };

  await subscribe(config, subscriptionRequest, async (data) => {
    if (!data.slot) return;
    const slot = data.slot;
    // The SDK returns u64 fields as strings to preserve precision.
    const currentSlot = Number(slot.slot);
    const currentTime = Date.now();

    console.log(`\n📊 Slot Update:`);
    console.log(`  Slot: ${currentSlot}`);
    console.log(`  Parent: ${slot.parent}`);
    // slot.status is a numeric enum (0=processed, 1=confirmed, 2=finalized).
    console.log(`  Status: ${STATUS_NAMES[slot.status] ?? slot.status}`);

    if (lastSlot > 0) {
      const slotDiff = currentSlot - lastSlot;
      const timeDiff = currentTime - lastTimestamp;

      if (slotDiff === 1) {
        slotTimes.push(timeDiff);
        if (slotTimes.length > 100) slotTimes.shift();

        const avg = slotTimes.reduce((a, b) => a + b, 0) / slotTimes.length;
        console.log(`  Slot Time: ${timeDiff}ms`);
        console.log(`  Avg Slot Time: ${avg.toFixed(1)}ms`);

        if (timeDiff > 800) {
          console.log(`  ⚠️  SLOW SLOT: ${timeDiff}ms (normal ~400ms)`);
        }
      } else if (slotDiff > 1) {
        console.log(`  ⚠️  SKIPPED ${slotDiff - 1} SLOTS`);
      }
    }

    lastSlot = currentSlot;
    lastTimestamp = currentTime;
  }, async (error) => {
    console.error('Stream error:', error);
  });
}

monitorNetworkHealth().catch(console.error);
```

### Exemple 2 : Surveillance de la Production des Blocs

Suivez la production des blocs et le volume des transactions :

```typescript [expandable] theme={"system"}
async function monitorBlockProduction() {
  const subscriptionRequest: SubscribeRequest = {
    blocksMeta: {
      blockMetaSubscribe: {}
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {}, transactions: {}, transactionsStatus: {},
    slots: {}, blocks: {}, entry: {}, accountsDataSlice: [],
  };

  const config: LaserstreamConfig = {
    apiKey: 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  };

  await subscribe(config, subscriptionRequest, async (data) => {
    if (!data.blockMeta) return;
    const blockMeta = data.blockMeta;

    console.log(`\n🧱 Block Produced:`);
    console.log(`  Slot: ${blockMeta.slot}`);
    // blockHeight is a wrapper object: { blockHeight: '397657352' }
    console.log(`  Block Height: ${blockMeta.blockHeight?.blockHeight}`);
    console.log(`  Block Hash: ${blockMeta.blockhash}`);
    console.log(`  Parent Slot: ${blockMeta.parentSlot}`);
    console.log(`  Parent Hash: ${blockMeta.parentBlockhash}`);
    console.log(`  Transactions: ${blockMeta.executedTransactionCount}`);
    console.log(`  Entries: ${blockMeta.entriesCount}`);
    if (blockMeta.blockTime?.timestamp) {
      // blockTime.timestamp is a u64 as a string (Unix seconds).
      console.log(`  Block Time: ${new Date(Number(blockMeta.blockTime.timestamp) * 1000).toISOString()}`);
    }

    // rewards is a wrapper object: { rewards: [...], numPartitions: number | null }
    if (blockMeta.rewards?.rewards?.length > 0) {
      console.log(`  Rewards:`);
      blockMeta.rewards.rewards.forEach((r: any) => {
        console.log(`    ${r.pubkey}: ${r.lamports} lamports (${r.rewardType})`);
      });
    }

    if (Number(blockMeta.executedTransactionCount) > 3000) {
      console.log(`  🔥 HIGH ACTIVITY: ${blockMeta.executedTransactionCount} transactions`);
    }
  }, async (error) => {
    console.error('Stream error:', error);
  });
}
```

### Exemple 3 : Surveillance Filtrée des Blocs

Surveillez les blocs contenant une activité de programme spécifique :

```typescript [expandable] theme={"system"}
async function monitorDEXBlocks() {
  const subscriptionRequest: SubscribeRequest = {
    blocks: {
      blockSubscribe: {
        accountInclude: [
          "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", // Raydium
          "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK", // Raydium CLMM
          "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"   // Jupiter
        ],
        includeTransactions: true,
        includeAccounts: false,
        includeEntries: false
      }
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {}, transactions: {}, transactionsStatus: {},
    slots: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
  };

  const config: LaserstreamConfig = {
    apiKey: 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  };

  await subscribe(config, subscriptionRequest, async (data) => {
    if (!data.block) return;
    const block = data.block;

    let successfulDexTx = 0;
    let totalFees = 0; // lamports
    block.transactions?.forEach((tx: any) => {
      if (tx.meta && !tx.meta.err) {
        successfulDexTx++;
        // tx.meta.fee is a u64 string — coerce before adding.
        totalFees += Number(tx.meta.fee ?? 0);
      }
    });

    console.log(`\n🔄 DEX Activity Block:`);
    console.log(`  Slot: ${block.slot}`);
    console.log(`  Block Height: ${block.blockHeight?.blockHeight}`);
    console.log(`  Block Hash: ${block.blockhash}`);
    console.log(`  Total transactions in block: ${block.executedTransactionCount}`);
    console.log(`  Matched DEX transactions: ${block.transactions?.length ?? 0}`);
    console.log(`  Successful DEX transactions: ${successfulDexTx}`);
    if (successfulDexTx > 0) {
      console.log(`  Total Fees: ${(totalFees / 1e9).toFixed(4)} SOL`);
      console.log(`  Avg Fee: ${(totalFees / successfulDexTx / 1e9).toFixed(6)} SOL`);
    }
  }, async (error) => {
    console.error('Stream error:', error);
  });
}
```

***

## Structures de Données

<Accordion title="Structure des Données des Slots">
  ```typescript theme={"system"}
  {
    slot: string;     // Current slot number (u64 as string)
    parent: string;   // Parent slot number (u64 as string)
    status: number;   // CommitmentLevel enum: 0 = processed, 1 = confirmed, 2 = finalized
  }
  ```

  Chaque slot représente environ 400ms de temps réseau. Les trois niveaux d'engagement reflètent des garanties progressivement plus fortes : `processed` (initial), `confirmed` (supermajorité votée), `finalized` (irréversible).

  <Tip>
    Les champs u64 (slot, parent) arrivent sous forme de chaînes pour préserver la précision au-delà de `Number.MAX_SAFE_INTEGER`. Convertissez avec `Number(slot.slot)` lorsque vous avez besoin d'arithmétique. `status` est une enum numérique — utilisez `CommitmentLevel[slot.status]` pour le nom lisible.
  </Tip>
</Accordion>

<Accordion title="Structure des Métadonnées des Blocs">
  ```typescript theme={"system"}
  {
    slot: string;                                  // u64 as string
    blockhash: string;
    rewards: {
      rewards: Array<{
        pubkey: string;
        lamports: string;                          // u64 as string
        rewardType: string;                        // "fee" | "rent" | "voting" | "staking"
      }>;
      numPartitions: number | null;
    };
    blockTime: { timestamp: string };              // Unix seconds as a u64 string
    blockHeight: { blockHeight: string };          // u64 as string, wrapped
    parentSlot: string;                            // u64 as string
    parentBlockhash: string;
    executedTransactionCount: string;              // u64 as string
    entriesCount: string;                          // u64 as string
  }
  ```

  <Tip>
    Les champs numériques (slot, parentSlot, executedTransactionCount, entriesCount, les valeurs à l'intérieur de `blockHeight` et `blockTime`) sont émis sous forme de chaînes car ils sont u64 dans le proto sous-jacent. Enveloppez-les dans `Number(...)` pour l'arithmétique ou les comparaisons.
  </Tip>
</Accordion>

<Accordion title="Structure Complète des Blocs">
  ```typescript theme={"system"}
  {
    slot: string;                                  // u64 as string
    blockhash: string;
    rewards: {
      rewards: Array<{
        pubkey: string;
        lamports: string;                          // u64 as string
        rewardType: string;
      }>;
      numPartitions: number | null;
    };
    blockTime: { timestamp: string };              // Unix seconds (u64 string)
    blockHeight: { blockHeight: string };          // u64 as string, wrapped
    parentSlot: string;                            // u64 as string
    parentBlockhash: string;
    executedTransactionCount: string;              // total executed tx in the block (u64 as string)
    updatedAccountCount: string;                   // total account updates in the block (u64 as string)
    entriesCount: string;                          // u64 as string
    transactions: Array<{
      signature: Buffer;                           // base58-encode for display
      isVote: boolean;
      transaction: TransactionMessage;             // full transaction payload
      meta: TransactionMeta;                       // execution metadata (fee, err, balances, …)
      index: string;                               // u64 as string
    }>;
    accounts: AccountUpdate[];                     // populated when includeAccounts: true
    entries: Entry[];                              // populated when includeEntries: true
  }
  ```

  Les blocs complets peuvent atteindre plusieurs Mo avec toutes les transactions et comptes. La même convention u64-as-string s'applique — enveloppez les champs numériques avec `Number(...)` pour l'arithmétique. À l'intérieur de chaque transaction, `meta.fee`, `meta.preBalances`, `meta.postBalances`, etc. sont également des chaînes.
</Accordion>

***

## Considérations de Performance

<CardGroup cols={2}>
  <Card title="Surveillance des Slots" icon="clock">
    Léger : très faible bande passante, surcharge de traitement minimale. Idéal pour les tableaux de bord de surveillance.
  </Card>

  <Card title="Métadonnées des Blocs" icon="info">
    Équilibré : bande passante modérée, insights de niveau bloc sans données complètes. Convient pour l'analytique.
  </Card>

  <Card title="Blocs Complets" icon="database">
    Volume élevé : données complètes de transactions, nécessite un traitement robuste. Toujours associer avec des filtres.
  </Card>

  <Card title="Blocs Filtrés" icon="filter">
    Optimisé : utilisez `accountInclude`, désactivez `includeAccounts`/`includeEntries` dont vous n'avez pas besoin.
  </Card>
</CardGroup>

***

## Cas d'Utilisation

<Tabs>
  <Tab title="Surveillance du Réseau">
    Suivez la santé et la performance du réseau — synchronisation des slots, congestion, consensus.

    ```typescript theme={"system"}
    const targetSlotTime = 400; // ms
    const tolerance = 200; // ms
    if (Math.abs(slotTime - targetSlotTime) > tolerance) {
      console.log(`Network performance issue detected`);
    }
    ```
  </Tab>

  <Tab title="Analyse & Mètres">
    Collectez des données analytiques de la blockchain — volume des transactions, analyse des frais, taille des blocs, motifs d'activité.

    ```typescript theme={"system"}
    const dailyStats = {
      date: new Date().toDateString(),
      totalTransactions: 0,
      totalFees: 0,
      blockCount: 0
    };
    ```
  </Tab>

  <Tab title="Synchronisation des Applications">
    Maintenez les applications synchronisées avec le réseau — mises à jour basées sur les slots, confirmations de blocs.

    ```typescript theme={"system"}
    if (data.slot && data.slot.status === 'finalized') {
      updateApplicationState(data.slot.slot);
    }
    ```
  </Tab>
</Tabs>

***

## Gestion des Erreurs

<Accordion title="Slots Manquants">
  **Symptôme :** Lacunes dans la progression des slots.

  **Causes :** Problèmes de connectivité réseau, indisponibilité du validateur, délais de traitement du client.

  **Solutions :** Suivez les lacunes des slots et alertez ; implémentez une logique de rattrapage via [relecture historique](/docs/fr/laserstream/historical-replay) ; surveillez la santé de la connexion.
</Accordion>

<Accordion title="Volume Élevé">
  **Symptôme :** Trop de données de blocs.

  **Solutions :** Utilisez les métadonnées des blocs au lieu des blocs complets ; appliquez des filtres de compte ; désactivez les inclusions inutiles (entrées, comptes) ; traitez de manière asynchrone.
</Accordion>

<Accordion title="Problèmes de Timing">
  **Symptôme :** Synchronisation des slots incohérente.

  **Analyse :** Calculez des moyennes mobiles ; suivez les écarts ; surveillez les métriques de santé du réseau ; corrélez avec les performances du validateur.
</Accordion>

***

## Meilleures Pratiques

<Note>
  **Directives de Production :**

  * **Commencez avec les métadonnées** — utilisez les métadonnées de bloc avant de vous abonner aux blocs complets
  * **Appliquez des filtres** — utilisez `accountInclude` pour éliminer les données non pertinentes
  * **Surveillez le timing** — suivez la progression des slots comme un canari de santé du réseau
  * **Gérez les lacunes** — combinez avec [relecture historique](/docs/fr/laserstream/historical-replay) pour que les slots manquants soient automatiquement complétés lors de la reconnexion
  * **Traitez de manière asynchrone** — ne bloquez pas le traitement des flux avec des calculs lourds
  * **Adaptez l'engagement à vos besoins** — `processed` pour les UI à faible latence, `confirmed`/`finalized` pour les écritures d'état
</Note>

***

## Étapes Suivantes

<CardGroup cols={2}>
  <Card title="Surveillance des Transactions" icon="receipt" href="/docs/fr/laserstream/guides/transaction-monitoring">
    Filtrez les transactions par programme, compte, vote ou statut d'échec.
  </Card>

  <Card title="Diffusez les Données Pump AMM" icon="chart-line" href="/docs/fr/laserstream/guides/stream-pump-amm-data">
    Exemple réel : surveillez les transactions Pump AMM.
  </Card>

  <Card title="Décodage des Données de Transaction" icon="binary" href="/docs/fr/laserstream/guides/decoding-transaction-data">
    Analysez les charges utiles `transactionUpdate` en transactions Solana lisibles.
  </Card>

  <Card title="Référence du protocole Yellowstone" icon="book" href="/docs/fr/grpc/slot-and-block-monitoring">
    Le même workflow avec le protocole gRPC Yellowstone brut.
  </Card>
</CardGroup>
