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

# Monitoreo de slots y bloques con LaserStream

> Monitorea el consenso de la red Solana, la producción de bloques y los cambios de estado de la red con LaserStream: tiempos de slots, metadatos de bloques y bloques completos filtrados.

El monitoreo de slots y bloques te permite observar el consenso de la red Solana, los tiempos de producción de bloques y su estado general. Con LaserStream, puedes rastrear el avance de los slots, la finalización de bloques y las métricas de rendimiento de la red en tiempo real mediante el SDK de [`helius-laserstream`](/docs/es/laserstream/clients).

<Info>
  **Requisitos previos:** Esta guía supone que completaste el [inicio rápido de gRPC de LaserStream](/docs/es/laserstream/grpc) y tienes una clave de API.
</Info>

***

## Tipos de monitoreo

<Tabs>
  <Tab title="Slot Updates">
    **Rastrea el avance del consenso de la red**

    Monitorea el avance de los slots en los distintos niveles de compromiso:

    ```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: [],
    };
    ```

    **Los datos del slot incluyen:** número de slot, slot principal, estado de compromiso (`processed` / `confirmed` / `finalized`) e información del líder.

    <Note>
      **Ideal para:** monitorear el estado de la red, analizar los tiempos de los slots y rastrear el consenso.
    </Note>
  </Tab>

  <Tab title="Block Data">
    **Monitorea la información completa de los bloques**

    Transmite bloques completos con transacciones y actualizaciones de cuentas:

    ```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: [],
    };
    ```

    **Los datos del bloque incluyen:** metadatos del bloque, transacciones, actualizaciones de cuentas y tiempos del bloque.

    <Warning>
      **Volumen alto:** Los streams de bloques completos generan una cantidad considerable de datos. Usa filtros `accountInclude` para reducir el volumen.
    </Warning>
  </Tab>

  <Tab title="Block Metadata">
    **Información ligera de los bloques**

    Obtén los metadatos de los bloques sin los detalles de las transacciones:

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

    **Los metadatos incluyen:** hash del bloque, hash principal, slot, altura, cantidad de transacciones y recompensas.

    <Tip>
      **Eficiente:** Una alternativa de menor ancho de banda que transmitir bloques completos.
    </Tip>
  </Tab>
</Tabs>

***

## Ejemplos prácticos

### Ejemplo 1: Monitor del estado de la red

Rastrea el avance de los slots e identifica problemas en la red:

```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);
```

### Ejemplo 2: Monitor de producción de bloques

Rastrea la producción de bloques y el volumen de transacciones:

```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);
  });
}
```

### Ejemplo 3: Monitor de bloques filtrados

Monitorea los bloques que contienen actividad de programas específicos:

```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);
  });
}
```

***

## Estructuras de datos

<Accordion title="Slot Data Structure">
  ```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
  }
  ```

  Cada slot representa aproximadamente 400 ms de tiempo de red. Los tres niveles de compromiso reflejan garantías cada vez más sólidas: `processed` (inicial), `confirmed` (votado por una supermayoría), `finalized` (irreversible).

  <Tip>
    Los campos u64 (slot, parent) llegan como cadenas para conservar la precisión más allá de `Number.MAX_SAFE_INTEGER`. Conviértelos con `Number(slot.slot)` cuando necesites realizar operaciones aritméticas. `status` es una enumeración numérica; usa `CommitmentLevel[slot.status]` para obtener el nombre legible.
  </Tip>
</Accordion>

<Accordion title="Block Metadata Structure">
  ```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>
    Los campos numéricos (slot, parentSlot, executedTransactionCount, entriesCount y los valores dentro de `blockHeight` e `blockTime`) se emiten como cadenas porque son u64 en el proto subyacente. Envuélvelos en `Number(...)` para realizar operaciones aritméticas o comparaciones.
  </Tip>
</Accordion>

<Accordion title="Full Block Structure">
  ```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
  }
  ```

  Los bloques completos pueden ocupar varios MB con todas las transacciones y cuentas. Se aplica la misma convención de representar u64 como cadena: envuelve los campos numéricos con `Number(...)` para realizar operaciones aritméticas. Dentro de cada transacción, `meta.fee`, `meta.preBalances`, `meta.postBalances`, etc., también son cadenas.
</Accordion>

***

## Consideraciones de rendimiento

<CardGroup cols={2}>
  <Card title="Slot Monitoring" icon="clock">
    Ligero: ancho de banda muy bajo y sobrecarga de procesamiento mínima. Adecuado para paneles de monitoreo.
  </Card>

  <Card title="Block Metadata" icon="info">
    Equilibrado: ancho de banda moderado e información a nivel de bloque sin todos los datos. Adecuado para análisis.
  </Card>

  <Card title="Full Blocks" icon="database">
    Volumen alto: datos completos de las transacciones que requieren un procesamiento sólido. Úsalos siempre con filtros.
  </Card>

  <Card title="Filtered Blocks" icon="filter">
    Optimizado: usa `accountInclude` y desactiva los `includeAccounts`/`includeEntries` que no necesites.
  </Card>
</CardGroup>

***

## Casos de uso

<Tabs>
  <Tab title="Network Monitoring">
    Rastrea el estado y el rendimiento de la red: tiempos de los slots, congestión y consenso.

    ```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="Analytics & Metrics">
    Recopila datos analíticos de la blockchain: volumen de transacciones, análisis de comisiones, tamaño de los bloques y patrones de actividad.

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

  <Tab title="Application Synchronization">
    Mantén las aplicaciones sincronizadas con la red mediante actualizaciones basadas en slots y confirmaciones de bloques.

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

***

## Manejo de errores

<Accordion title="Missing Slots">
  **Síntoma:** Hay brechas en el avance de los slots.

  **Causas:** Problemas de conectividad de red, tiempo de inactividad de los validadores o retrasos en el procesamiento del cliente.

  **Soluciones:** Rastrea las brechas entre slots y genera alertas; implementa lógica de recuperación mediante la [repetición histórica](/docs/es/laserstream/historical-replay); monitorea el estado de la conexión.
</Accordion>

<Accordion title="High Volume">
  **Síntoma:** Hay demasiados datos de bloques.

  **Soluciones:** Usa metadatos de bloques en lugar de bloques completos; aplica filtros de cuentas; desactiva las inclusiones innecesarias (entradas y cuentas); procesa los datos de forma asíncrona.
</Accordion>

<Accordion title="Timing Issues">
  **Síntoma:** Los tiempos de los slots son inconsistentes.

  **Análisis:** Calcula promedios móviles; rastrea las desviaciones; monitorea las métricas de estado de la red; correlaciónalas con el rendimiento de los validadores.
</Accordion>

***

## Prácticas recomendadas

<Note>
  **Directrices para producción:**

  * **Comienza con los metadatos** — usa metadatos de bloques antes de suscribirte a bloques completos
  * **Aplica filtros** — usa `accountInclude` para descartar datos irrelevantes
  * **Monitorea los tiempos** — rastrea el avance de los slots como indicador temprano del estado de la red
  * **Maneja las brechas** — combínalo con la [repetición histórica](/docs/es/laserstream/historical-replay) para rellenar automáticamente los slots faltantes al restablecer la conexión
  * **Procesa de forma asíncrona** — no bloquees el procesamiento del stream con cálculos pesados
  * **Adapta el compromiso a tus necesidades** — `processed` para interfaces de baja latencia, `confirmed`/`finalized` para escrituras de estado
</Note>

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Transaction Monitoring" icon="receipt" href="/docs/es/laserstream/guides/transaction-monitoring">
    Filtra transacciones por programa, cuenta, voto o estado de error.
  </Card>

  <Card title="Stream Pump AMM Data" icon="chart-line" href="/docs/es/laserstream/guides/stream-pump-amm-data">
    Ejemplo práctico: monitorea transacciones de Pump AMM.
  </Card>

  <Card title="Decoding Transaction Data" icon="binary" href="/docs/es/laserstream/guides/decoding-transaction-data">
    Analiza los payloads binarios `transactionUpdate` y conviértelos en transacciones de Solana legibles.
  </Card>

  <Card title="Yellowstone protocol reference" icon="book" href="/docs/es/grpc/slot-and-block-monitoring">
    El mismo flujo de trabajo con el protocolo gRPC de Yellowstone sin procesar.
  </Card>
</CardGroup>
