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

# Inicio rápido de LaserStream gRPC

> Instala el SDK, elige un endpoint y transmite tus primeras transacciones de Solana mediante LaserStream gRPC: endpoints, referencia de solicitudes de suscripción y ejemplos.

## Descripción general

LaserStream es un servicio administrado de streaming gRPC de Solana. Es compatible a nivel de protocolo con el protocolo abierto Yellowstone gRPC, por lo que cualquier cliente de Yellowstone funciona sin configuración adicional. Además, incorpora funciones para producción, como reproducción histórica, conmutación por error entre varios nodos y un entorno completamente administrado.

LaserStream usa el protocolo gRPC de código abierto, lo que evita la dependencia de un proveedor y garantiza la máxima compatibilidad con las implementaciones de gRPC existentes.

Puedes conectarte con el cliente `@triton-one/yellowstone-grpc` estándar o usar el **[SDK de Helius LaserStream](/docs/es/laserstream/clients)** optimizado para el rendimiento. Este ofrece ventajas adicionales, como mayor rendimiento, reconexiones automáticas, administración de suscripciones, gestión de errores y más.

<Card title="LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients" icon="bolt" href="https://www.helius.dev/blog/laserstream-sdks">
  Descubre cómo usamos Rust Core con enlaces NAPI sin copias para maximizar el rendimiento del SDK de JavaScript
</Card>

<Warning>
  **Aviso de rendimiento**: Si experimentas retrasos o problemas de rendimiento con tu conexión de LaserStream, consulta la [sección de solución de problemas](#solución-de-problemas--preguntas-frecuentes) para conocer las causas y soluciones comunes.
</Warning>

<Divider />

## Endpoints y regiones

LaserStream está disponible en varias regiones de todo el mundo.

Elige el endpoint más cercano a tu aplicación para obtener un rendimiento óptimo:

### Endpoints de Mainnet

| Región   | Ubicación                                  | Endpoint                                          |
| -------- | ------------------------------------------ | ------------------------------------------------- |
| **ewr**  | Newark, Nueva Jersey (cerca de Nueva York) | `https://laserstream-mainnet-ewr.helius-rpc.com`  |
| **pitt** | Pittsburgh, EE. UU. (centro)               | `https://laserstream-mainnet-pitt.helius-rpc.com` |
| **slc**  | Salt Lake City, EE. UU. (costa oeste)      | `https://laserstream-mainnet-slc.helius-rpc.com`  |
| **lax**  | Los Ángeles, EE. UU. (costa oeste)         | `https://laserstream-mainnet-lax.helius-rpc.com`  |
| **lon**  | Londres, Europa                            | `https://laserstream-mainnet-lon.helius-rpc.com`  |
| **ams**  | Ámsterdam, Europa                          | `https://laserstream-mainnet-ams.helius-rpc.com`  |
| **fra**  | Fráncfort, Europa                          | `https://laserstream-mainnet-fra.helius-rpc.com`  |
| **tyo**  | Tokio, Asia                                | `https://laserstream-mainnet-tyo.helius-rpc.com`  |
| **sgp**  | Singapur, Asia                             | `https://laserstream-mainnet-sgp.helius-rpc.com`  |

### Endpoint de Devnet

| Red        | Ubicación                                  | Endpoint                                        |
| ---------- | ------------------------------------------ | ----------------------------------------------- |
| **Devnet** | Newark, Nueva Jersey (cerca de Nueva York) | `https://laserstream-devnet-ewr.helius-rpc.com` |

<Note>
  **Selección de red y región**:

  * Para **aplicaciones de producción**, elige el endpoint de Mainnet más cercano a tu servidor para obtener el mejor rendimiento (por ejemplo, si implementas en Europa, usa Ámsterdam (`ams`) o Fráncfort (`fra`))
  * Para **pruebas**, usa: `https://laserstream-devnet-ewr.helius-rpc.com`.
</Note>

### Compresión `zstd`

Todos los endpoints de LaserStream gRPC admiten la compresión `zstd`. La compresión es opcional: las respuestas permanecen sin comprimir a menos que tu cliente anuncie compatibilidad con `zstd`.

Habilita `zstd` en el SDK de TypeScript de Helius LaserStream:

```typescript theme={"system"}
import { CompressionAlgorithms } from 'helius-laserstream'
import type { LaserstreamConfig } from 'helius-laserstream'

const config: LaserstreamConfig = {
  apiKey: 'YOUR_API_KEY',
  endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  channelOptions: {
    'grpc.default_compression_algorithm': CompressionAlgorithms.zstd,
  },
}
```

`zstd` reduce el ancho de banda de red, pero agrega trabajo de compresión. Evalúa su rendimiento con la carga de trabajo de tu suscripción antes de habilitarlo en streams sensibles a la latencia.

### Truncamiento de registros

De forma predeterminada, LaserStream trunca los mensajes de registro de transacciones a **10 KB** para mejorar la velocidad y el rendimiento. Si necesitas los registros completos, hay endpoints dedicados sin truncamiento. Consulta [Truncamiento de registros](/docs/es/laserstream/log-truncation).

## Inicio rápido

<Tip>
  Comienza a usar LaserStream desde tu [panel de Helius](https://dashboard.helius.dev/laserstream). Mainnet requiere un plan Business o Professional; Devnet está disponible en el plan Developer y superiores. Consulta [Planes y precios](/docs/es/billing/plans) para obtener más información.
</Tip>

<Steps>
  <Step title="Create a New Project">
    ```bash theme={"system"}
    mkdir laserstream-grpc-demo
    cd laserstream-grpc-demo
    npm init -y
    ```
  </Step>

  <Step title="Install Dependencies">
    ```bash theme={"system"}
    npm install helius-laserstream
    npm install --save-dev typescript tsx @types/node
    ```

    Usamos `tsx` porque el `npx tsc --init` predeterminado de TypeScript 5.x establece `verbatimModuleSyntax`, `module: "nodenext"` y `types: []`, que impiden una ejecución rápida de `ts-node index.ts`. `tsx` ejecuta archivos `.ts` sin un tsconfig.
  </Step>

  <Step title="Obtain Your API Key">
    Genera una clave desde el [panel de Helius](https://dashboard.helius.dev/).

    Esta clave servirá como tu token de autenticación para LaserStream.

    <Note>
      **Requisitos del plan**: LaserStream Devnet está disponible en todos los [planes](/docs/es/billing/plans). LaserStream Mainnet requiere un plan Business o Professional.
    </Note>
  </Step>

  <Step title="Create a Subscription Script">
    Crea **`index.ts`** con lo siguiente:

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

    async function main() {
      const subscriptionRequest: SubscribeRequest = {
        transactions: {
          "token-filter": { // user-defined label for this filter
            accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
            accountExclude: [],
            accountRequired: [],
            vote: false,
            failed: false
          }
        },
        commitment: CommitmentLevel.CONFIRMED,
        accounts: {},
        slots: {},
        transactionsStatus: {},
        blocks: {},
        blocksMeta: {},
        entry: {},
        accountsDataSlice: [],
        // Optionally, you can replay missed data by specifying a `fromSlot` (u64 number):
        // fromSlot: currentSlot - 1000,
        // Note: replay is currently limited to the last ~216,000 slots (≈24 hours).
      };

    // Replace the values below with your actual LaserStream API key and endpoint
    const config: LaserstreamConfig = {
      apiKey: 'YOUR_API_KEY', // Replace with your key from https://dashboard.helius.dev/
      endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
    }

      await subscribe(config, subscriptionRequest, async (data) => {
        
        console.log(data);

      }, async (error) => {
        console.error(error);
      });
    }

    main().catch(console.error);
    ```
  </Step>

  <Step title="Replace Your API Key and Choose Your Region">
    En `index.ts`, actualiza el objeto `config` con:

    1. Tu clave de API real del [panel de Helius](https://dashboard.helius.dev/)
    2. El endpoint de LaserStream más cercano a la ubicación de tu servidor

    ```typescript theme={"system"}
    const config: LaserstreamConfig = {
      apiKey: 'YOUR_ACTUAL_API_KEY', // Replace with your key from Helius Dashboard
      endpoint: 'https://laserstream-mainnet-fra.helius-rpc.com', // Example: Frankfurt mainnet
      // For devnet: endpoint: 'https://laserstream-devnet-ewr.helius-rpc.com'
    }
    ```

    **Ejemplos de selección de red y región:**

    * **Para producción (Mainnet)**:
      * Europa: usa `fra` (Fráncfort), `ams` (Ámsterdam) o `lon` (Londres)
      * Este de EE. UU.: usa `ewr` (Nueva York)
      * Oeste de EE. UU.: usa `slc` (Salt Lake City) o `lax` (Los Ángeles)
      * Asia: usa `tyo` (Tokio) o `sgp` (Singapur)
    * **Para desarrollo (Devnet)**:
      * Usa `https://laserstream-devnet-ewr.helius-rpc.com`
  </Step>

  <Step title="Run and View Results">
    ```bash theme={"system"}
    npx tsx index.ts
    ```

    Cada vez que una transacción del token `confirmed` involucre a `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`, verás los datos en tu consola.
  </Step>
</Steps>

<Divider />

## Flujos de trabajo comunes

Guías paso a paso para los flujos de trabajo que vemos con mayor frecuencia. Cada guía usa el SDK [`helius-laserstream`](/docs/es/laserstream/clients), con reconexión automática y reproducción histórica integradas.

<CardGroup cols={2}>
  <Card title="Account Subscriptions" icon="user" href="/docs/es/laserstream/guides/account-subscription">
    Supervisa los cambios de saldo, datos y propiedad de cuentas específicas mediante filtros.
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/es/laserstream/guides/transaction-monitoring">
    Transmite transacciones que involucren cuentas objetivo y filtra por programa, voto o estado de error.
  </Card>

  <Card title="Slot & Block Monitoring" icon="cube" href="/docs/es/laserstream/guides/slot-and-block-monitoring">
    Realiza un seguimiento del consenso de la red, la producción de bloques y las transiciones del nivel de confirmación.
  </Card>

  <Card title="Decoding Transaction Data" icon="binary" href="/docs/es/laserstream/guides/decoding-transaction-data">
    Analiza las cargas útiles binarias `transactionUpdate` y conviértelas en transacciones de Solana legibles.
  </Card>

  <Card title="Stream Pump AMM Data" icon="chart-line" href="/docs/es/laserstream/guides/stream-pump-amm-data">
    Ejemplo real: supervisa operaciones de Pump AMM con filtros resistentes a las reconexiones.
  </Card>
</CardGroup>

<Tip>
  El cliente `@triton-one/yellowstone-grpc` funciona con los mismos endpoints si prefieres el protocolo Yellowstone sin abstracciones. Consulta la [referencia de Yellowstone gRPC](/docs/es/grpc) para obtener detalles a nivel de protocolo.
</Tip>

<Divider />

## Solicitud de suscripción

En la solicitud de suscripción, debes incluir los siguientes parámetros generales:

<Note>
  **Reproducción histórica:** Puedes incluir opcionalmente un campo `fromSlot` (un número `u64`) en el objeto `SubscribeRequest` principal para reproducir datos a partir de un slot específico. Actualmente, la reproducción se limita a los últimos 216 000 slots (≈24 horas). Ten en cuenta que [las reproducciones con más de \~20 minutos de antigüedad solo devuelven datos finalizados](/docs/es/laserstream/historical-replay#hasta-dónde-puedes-retroceder-en-la-reproducción).
</Note>

<ParamField body="commitment" type="enum">
  Especifica el nivel de confirmación, que puede ser **processed**, **confirmed** o **finalized**.
</ParamField>

<ParamField body="accountsDataSlice" type="array">
  Un arreglo de objetos `{ offset: uint64, length: uint64 }` que te permite recibir únicamente las secciones de datos necesarias de las cuentas.
</ParamField>

<ParamField body="ping" type="boolean">
  Algunos proveedores de nube, como Cloudflare, pueden cerrar los streams inactivos después de un periodo sin actividad. Para evitarlo y mantener activa la conexión sin tener que reenviar los filtros, establece este valor en **true**. El servidor responderá con un mensaje Pong cada 15 segundos.
</ParamField>

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

A continuación, debes especificar los filtros de los datos a los que quieres suscribirte, como cuentas, bloques, slots o transacciones.

<Accordion title="Slots">
  Define filtros para las actualizaciones de slots. La clave que uses (por ejemplo, `mySlotLabel`) es una **etiqueta definida por ti** para esta configuración de filtro específica. Esto te permite definir varias configuraciones con nombre si es necesario, aunque normalmente basta con una.

  <ParamField body="filterByCommitment" type="boolean">
    De forma predeterminada, se envían slots para todos los niveles de confirmación. Con este filtro, puedes elegir recibir solo el nivel de confirmación seleccionado.
  </ParamField>

  <ParamField body="interslotUpdates" type="boolean">
    Permite que la suscripción reciba actualizaciones sobre cambios dentro de un slot, no solo al comienzo de nuevos slots. Esto resulta útil para obtener datos de slots más detallados y con baja latencia.
  </ParamField>

  ```typescript theme={"system"}
  slots: {
    // mySlotLabel is a user-defined name for this slot update filter configuration
    mySlotLabel: {
      // filterByCommitment: true => Only broadcast slot updates at the specified subscribeRequest commitment
      filterByCommitment: true
      // interslotUpdates: true allows receiving updates for changes occurring within a slot, not just new slots.
      interslotUpdates: true
    }
  },
  ```
</Accordion>

<Accordion title="Accounts">
  Define filtros para las actualizaciones de datos de cuentas. La clave que uses (por ejemplo, `tokenAccounts`) es una **etiqueta definida por ti** para esta configuración de filtro específica.

  <ParamField body="account" type="array">
    Coincide con cualquier clave pública del arreglo proporcionado.
  </ParamField>

  <ParamField body="owner" type="array">
    La clave pública del propietario de la cuenta. Coincide con cualquier clave pública del arreglo proporcionado.
  </ParamField>

  <ParamField body="filters" type="array">
    Es similar a los filtros de [getProgramAccounts](https://solana.com/docs/rpc/http/getprogramaccounts). Es un arreglo de filtros `datasize` o `memcmp`, o de ambos. Para `memcmp`, el valor de comparación se coloca en `bytes`, `base58` o `base64` directamente en el objeto `memcmp`.
  </ParamField>

  <ParamField body="notifyOn" type="enum" deprecated>
    **Obsoleto: no tiene efecto desde Agave 4.2.** Establecer `notifyOn` no produce ningún efecto. El campo se eliminará más adelante.
  </ParamField>

  Si todos los campos están vacíos, se transmiten todas las cuentas. De lo contrario:

  * Los campos operan como un **AND** lógico.
  * Los valores dentro de los arreglos operan como un **OR** lógico (excepto dentro de `filters`, donde operan como un **AND** lógico).

  ```typescript theme={"system"}
  accounts: {
    // tokenAccounts is a user-defined label for this account filter configuration
    tokenAccounts: {
      // Matches any of these public keys (logical OR)
      account: ["9SHQTA66Ekh7ZgMnKWsjxXk6DwXku8przs45E8bcEe38"],
      // Matches owners that are any of these public keys
      owner: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
      // Filters - all must match (AND logic)
      filters: [
        { datasize: 165 },
        {
          memcmp: {
            offset: 0,
            base58: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          }
        }
      ]
    }
  },
  ```

  ¿Realizas un seguimiento de más de \~10 000 cuentas? En lugar de una lista explícita de claves públicas (32 bytes por cuenta), usa un [filtro cuckoo](/docs/es/laserstream/cuckoo-filters) comprimido (\~3–4 bytes por cuenta) para suscribirte a cientos de miles de cuentas en un solo stream. Está disponible en los SDK de Rust y JavaScript.
</Accordion>

<Accordion title="Transaction">
  Define filtros para las actualizaciones de transacciones. La clave que uses (por ejemplo, `myTxSubscription`) es una **etiqueta definida por ti** para esta configuración de filtro específica.

  <ParamField body="vote" type="boolean">
    Habilita o deshabilita la transmisión de transacciones de voto.
  </ParamField>

  <ParamField body="failed" type="boolean">
    Habilita o deshabilita la transmisión de transacciones fallidas.
  </ParamField>

  <ParamField body="signature" type="string">
    Transmite únicamente las transacciones que coincidan con la firma especificada.
  </ParamField>

  <ParamField body="accountInclude" type="array">
    Filtra las transacciones que involucren cualquier cuenta de la lista proporcionada.
  </ParamField>

  <ParamField body="accountExclude" type="array">
    Excluye las transacciones que involucren cualquier cuenta de la lista proporcionada (lo contrario de `accountInclude`).
  </ParamField>

  <ParamField body="accountRequired" type="array">
    Filtra las transacciones que involucren todas las cuentas de la lista proporcionada (deben usarse todas las cuentas).
  </ParamField>

  <ParamField body="tokenAccounts" type="string">
    Expansión opcional de `tokenAccounts` (cuenta de token asociada). Cuando se establece, una cartera `accountInclude` también coincide con las transacciones donde **posee** un saldo de tokens SPL; por ejemplo, transferencias de tokens entrantes que interactúan con la cuenta de tokens de la cartera en lugar de su clave pública. Acepta `"balanceChanged"` (coincidencias por diferencia de saldo), `"all"` (cualquier referencia, mayor volumen) o `"none"` (sin expansión, el valor predeterminado). El SDK convierte la cadena al enum `TokenAccountExpansionControlFlag` del nivel de protocolo (parte de `yellowstone-grpc-proto` 12.5.0+). Consulta [Filtrado de cuentas de tokens (ATA)](/docs/es/laserstream/token-account-filtering) para saber qué hace y cómo funciona.
  </ParamField>

  <ParamField body="matchMints" type="boolean">
    Indicador `matchMints` opcional (valor predeterminado: `false`). Cuando es `true`, las listas `accountInclude`, `accountExclude` e `accountRequired` también se comparan con los mints de los saldos de tokens anteriores y posteriores a la transacción, no solo con sus claves de cuenta. Coloca un mint en `accountInclude` para recibir todas las transacciones que interactúen con ese token, incluidas las transferencias SPL simples que nunca hagan referencia al mint en sus claves de cuenta. Es opcional y no afecta a los filtros existentes. Requiere `helius-laserstream` 0.8.5+ (JS), 0.6.4+ (Rust) o `go/v0.3.0`+ (Go). Consulta [Filtrado por mint de token](/docs/es/laserstream/mint-filtering) para conocer la semántica y ver ejemplos.
  </ParamField>

  Si todos los campos quedan vacíos, se transmiten todas las transacciones. De lo contrario:

  * Los campos operan como un **AND** lógico.
  * Los valores dentro de los arreglos se tratan como un **OR** lógico (excepto en `accountRequired`, donde todos deben coincidir).

  ```typescript theme={"system"}
  transactions: {
    // myTxSubscription is a user-defined label for this transaction filter configuration
    myTxSubscription: {
      vote: false,
      failed: false,
      signature: "",
      // Transaction must include at least one of these public keys (OR)
      accountInclude: ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"],
      // Exclude if it matches any of these
      accountExclude: [],
      // Require all accounts in this array (AND)
      accountRequired: []
    }
  },
  ```
</Accordion>

<Accordion title="Block">
  Define filtros para las actualizaciones de bloques. La clave que uses (por ejemplo, `myBlockLabel`) es una **etiqueta definida por ti** para esta configuración de filtro específica.

  <ParamField body="accountInclude" type="array">
    Filtra las transacciones y cuentas que involucren cualquier cuenta de la lista proporcionada.
  </ParamField>

  <ParamField body="includeTransactions" type="boolean">
    Incluye todas las transacciones en la transmisión.
  </ParamField>

  <ParamField body="includeAccounts" type="boolean">
    Incluye todas las actualizaciones de cuentas en la transmisión.
  </ParamField>

  <ParamField body="includeEntries" type="boolean">
    Incluye todas las entradas en la transmisión.
  </ParamField>

  ```typescript theme={"system"}
  blocks: {
    // myBlockLabel is a user-defined label for this block filter configuration
    myBlockLabel: {
      // Only broadcast blocks referencing these accounts
      accountInclude: ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"],
      includeTransactions: true,
      includeAccounts: false,
      includeEntries: false
    }
  },
  ```
</Accordion>

<Accordion title="Blocks Meta">
  Funciona de forma similar a los bloques, pero excluye transacciones, cuentas y entradas. La clave que uses (por ejemplo, `blockmetadata`) es una **etiqueta definida por ti** para esta suscripción. Actualmente, no hay filtros disponibles para los metadatos de bloques; todos los mensajes se transmiten de forma predeterminada.

  ```typescript theme={"system"}
  blocksMeta: {
    blockmetadata: {}
  },
  ```
</Accordion>

<Accordion title="Entries">
  Suscríbete a las entradas del libro mayor. La clave que uses (por ejemplo, `entrySubscribe`) es una **etiqueta definida por ti** para esta suscripción. Actualmente, no hay filtros disponibles para las entradas; se transmiten todas.

  ```typescript theme={"system"}
  entry: {
    entrySubscribe: {}
  },
  ```
</Accordion>

<Divider />

## Ejemplos de código (SDK de LaserStream)

<Tabs>
  <Tab title="Slot Updates">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            transactions: {},
            commitment: CommitmentLevel.CONFIRMED,
            accounts: {},
            slots: {
                slot: { filterByCommitment: true },
            },
            transactionsStatus: {},
            blocks: {},
            blocksMeta: {},
            entry: {},
            accountsDataSlice: [],
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Account Updates">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            accounts: {
                "usdc-account": { // user-defined label for this filter
                    account: ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"], // USDC mint account
                    owner: [],
                    filters: []
                }
            },
            accountsDataSlice: [],
            commitment: CommitmentLevel.CONFIRMED,
            slots: {},
            transactions: {},
            transactionsStatus: {},
            blocks: {},
            blocksMeta: {},
            entry: {}
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Transaction Updates">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            transactions: {
                "token-filter": { // user-defined label for this filter
                    accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
                    accountExclude: [],
                    accountRequired: [],
                    vote: false,
                    failed: false
                }
            },
            commitment: CommitmentLevel.CONFIRMED,
            accounts: {},
            slots: {},
            transactionsStatus: {},
            blocks: {},
            blocksMeta: {},
            entry: {},
            accountsDataSlice: [],
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Blocks">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            entry: {},
            accounts: {},
            accountsDataSlice: [],
            slots: {},
            blocks: {
                blocks: {
                    accountInclude: []
                }
            },
            blocksMeta: {},
            transactions: {},
            transactionsStatus: {},
            commitment: CommitmentLevel.CONFIRMED,
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Block Metadata">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            entry: {},
            accounts: {},
            accountsDataSlice: [],
            slots: {},
            blocks: {},
            blocksMeta: {
                blockmetadata: {}
            },
            transactions: {},
            transactionsStatus: {},
            commitment: CommitmentLevel.CONFIRMED,
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Entries">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            entry: {
                entrySubscribe: {}  // Subscribe to all entries
            },
            accounts: {},
            accountsDataSlice: [],
            slots: {},
            blocks: {},
            blocksMeta: {},
            transactions: {},
            transactionsStatus: {},
            commitment: CommitmentLevel.CONFIRMED,
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>
</Tabs>

<Divider />

## Opciones de SDK

Ofrecemos SDK oficiales para varios lenguajes de programación:

* **TypeScript**: [SDK de TypeScript de LaserStream](https://github.com/helius-labs/laserstream-sdk)
* **Rust**: [SDK de Rust de LaserStream](https://github.com/helius-labs/laserstream-sdk/tree/main/rust)
* **Go**: [SDK de Go de LaserStream](https://github.com/helius-labs/laserstream-sdk/tree/main/go)

Para otros lenguajes o implementaciones personalizadas, puedes usar directamente los [archivos proto de Yellowstone gRPC](https://github.com/rpcpool/yellowstone-grpc/tree/v6.0.0%2Bsolana.2.2.12/yellowstone-grpc-proto/proto) para generar clientes gRPC en el lenguaje que prefieras.

<Divider />

## Solución de problemas / Preguntas frecuentes

<Accordion title="Q: I'm experiencing lag or slow performance with my LaserStream connection. What could be causing this?">
  **R:** Los problemas de rendimiento de las conexiones de LaserStream suelen deberse a:

  * **Lentitud del cliente de JavaScript**: El cliente de JavaScript puede quedarse atrás cuando procesa demasiados mensajes o consume demasiado ancho de banda. Considera aplicar filtros más específicos a tus suscripciones para reducir el volumen de mensajes, cambiar al [SDK de JavaScript de LaserStream](/docs/es/laserstream/clients) o usar otro lenguaje.

  * **Ancho de banda local limitado**: Las suscripciones de gran volumen pueden saturar a los clientes con un ancho de banda de red limitado. Supervisa el uso de tu red y considera mejorar tu conexión o reducir el alcance de la suscripción.

  * **Distancia geográfica**: Las rutas de red largas aumentan la latencia y la pérdida de paquetes. Usa el [endpoint más cercano a tu servidor](#endpoints-de-mainnet). Para conexiones de alta latencia, aumenta el tamaño de los búferes de lectura de red (puede mejorar el ancho de banda 5 veces o más):

    ```bash theme={"system"}
    sudo sysctl -w net.core.rmem_max=67108864 net.ipv4.tcp_rmem="4096 87380 67108864"
    ```

    Para conservar la configuración después de reiniciar, agrégala a `/etc/sysctl.conf`:

    ```bash theme={"system"}
    net.core.rmem_max=67108864
    net.ipv4.tcp_rmem=4096 87380 67108864
    ```

    Aumenta a 64 MB el tamaño de las ventanas de **stream y conexión** de HTTP/2 para evitar cuellos de botella en el control de flujo. Ambas son necesarias: aumentar solo la ventana del stream deja la ventana a nivel de conexión como la restricción determinante:

    ```rust theme={"system"}
    // Rust (tonic)
    Channel::from_static("https://laserstream-mainnet-ewr.helius-rpc.com")
        .initial_stream_window_size(1024 * 1024 * 64)      // 64MB stream window
        .initial_connection_window_size(1024 * 1024 * 64)  // 64MB connection window
        .connect()
        .await?;
    ```

  * **Cuellos de botella en el procesamiento del cliente**: Asegúrate de que tu lógica de procesamiento de mensajes esté optimizada y no bloquee el hilo principal durante periodos prolongados.

  **Depuración del retraso del cliente**: Para ayudarte a depurar el cliente, creamos una herramienta que prueba el ancho de banda máximo desde tu nodo hasta un servidor de LaserStream gRPC. Para usarla, ejecuta:

  ```
  cargo install helius-laserstream-bandwidth
  helius-laserstream-bandwidth --laserstream-url $LASERSTREAM_URL --api-key $API_KEY
  ```

  El resultado devuelve la capacidad máxima de red entre tu servidor y el servidor de LaserStream. Necesitas como mínimo 10 MB/s para suscribirte a todos los datos de transacciones y 80 MB/s para suscribirte a todos los datos de cuentas. Recomendamos tener al menos el doble de la capacidad necesaria para obtener un rendimiento óptimo.
</Accordion>

<Accordion title="Q: I'm getting connection errors. What should I check?">
  **R:** Verifica que tu clave de API y tu endpoint sean correctos, y que tu red permita conexiones gRPC salientes al endpoint especificado. Consulta la [página de estado de Helius](https://helius.statuspage.io/) para comprobar si hay incidentes en curso.
</Accordion>

<Accordion title="Q: Why aren't my filters working as expected?">
  **R:** Vuelve a comprobar los operadores lógicos (AND/OR) descritos en las secciones de filtros. Asegúrate de que las claves públicas sean correctas. Revisa el nivel de confirmación especificado en tu solicitud.
</Accordion>

<Accordion title="Q: Can I subscribe to multiple types of data (e.g., accounts and transactions) in one request?">
  **R:** Sí, puedes definir configuraciones de filtros bajo varias claves (por ejemplo, `accounts` e `transactions`) dentro del mismo objeto `SubscribeRequest`.
</Accordion>

<Accordion title="Q: Does LaserStream support consumer groups?">
  **R:** No implementamos grupos de consumidores. En su lugar, LaserStream ofrece los mismos resultados que buscan los equipos: reanudación, reproducción y confiabilidad entre varios nodos sin una capa de coordinación ni la latencia y sobrecarga que conlleva. Creemos que los grupos de consumidores no son necesarios para la mayoría de las cargas de trabajo y que agregan latencia y sobrecarga operativa. Por ejemplo, una sola conexión de LaserStream gRPC puede emitir hasta 10 veces el volumen de datos de transacciones y cuentas de Solana, y la mayoría de los clientes se suscriben a una pequeña sección filtrada. Usar grupos de consumidores en este caso consume el margen de rendimiento e introduce otro punto de falla.
</Accordion>

<Accordion title="Q: Why are my transaction log messages cut off?">
  **R:** LaserStream trunca de forma predeterminada los mensajes de registro de transacciones a 10 KB para mejorar la velocidad y el rendimiento. Si necesitas los registros completos, conéctate a un endpoint dedicado sin truncamiento. Consulta [Truncamiento de registros](/docs/es/laserstream/log-truncation) para ver la lista.
</Accordion>

<Accordion title="Q: Why am I only receiving Pong responses with no account or slot data?">
  **R:** Incluir un campo `ping` en tu objeto `SubscribeRequest` inicial hace que LaserStream ignore silenciosamente todos los filtros de suscripción. Solo se devuelve un Pong, sin datos de cuentas, transacciones ni slots. Para corregirlo, elimina `ping` de la solicitud de suscripción inicial y, una vez establecida la suscripción, envía los pings por separado mediante el receptor del stream. Esto mantiene activa la conexión sin interferir con tus filtros.
</Accordion>
