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

# Cómo usar preconfSubscribe

> Transmite transacciones de Solana con la menor latencia posible mediante el método WebSocket preconfSubscribe: suscríbete, filtra y decodifica la carga útil.

<Tip>
  **Usa [Sender Max](/docs/es/sending-transactions/sender-max) (propina mín.: 0.001 SOL) para
  actuar según las Preconfirmations.** Una preconfirmación solo resulta útil si tu
  transacción se incluye
  primero. Sender Max es la forma más rápida de lograrlo. Desarrolla sobre Sender Max desde el
  principio para aprovechar al máximo las Preconfirmations.
</Tip>

## ¿Qué es `preconfSubscribe`?

`preconfSubscribe` es un método WebSocket de Helius que transmite [Preconfirmations](/docs/es/pre-confirmations/overview): transacciones entregadas antes de que se recopilen en entradas y se fragmenten. Es la señal de transacciones con menor latencia que ofrece Helius. Una suscripción entrega tanto las preconfirmaciones de Helius, emitidas en el instante en que el líder ejecuta la transacción e incluyendo su estado de ejecución, como las [preconfirmaciones de BAM](/docs/es/pre-confirmations/overview#preconfirmaciones-de-bam) de validadores que ejecutan el cliente Block Assembly Marketplace de Jito, emitidas cuando el validador se compromete a ejecutar la transacción. El acceso requiere un [plan Professional o superior](/docs/es/billing/plans). Consulta [Precios](#precios).

<Note>
  El flujo no es continuo. La cobertura aumenta según la proporción de participación
  que reenvía datos a Helius o ejecuta BAM, por lo que habrá slots sin mensajes. Gestiona
  estas interrupciones adecuadamente. Consulta [Cobertura](/docs/es/pre-confirmations/overview#cobertura).
</Note>

`preconfSubscribe` se sirve desde `wss://beta.helius-rpc.com`, el endpoint de [Gatekeeper](/docs/es/gatekeeper/overview) de Helius, en lugar de `mainnet.helius-rpc.com`. Autentícate con tu clave de API como parámetro de consulta.

```
wss://beta.helius-rpc.com/?api-key=<API_KEY>
```

<Note>
  El nombre de host `beta` hace referencia al despliegue de [Gatekeeper](/docs/es/gatekeeper/overview),
  no al nivel de madurez de Preconfirmations. Preconfirmations se lanza primero en el
  endpoint de Gatekeeper, que se convertirá en el endpoint estándar a medida que Helius
  migre el tráfico a Gatekeeper.
</Note>

## Suscribirse

Envía una solicitud JSON-RPC con el método `preconfSubscribe`. El servidor responde con un ID de suscripción y luego transmite una notificación por cada transacción. Pasa un [filtro](#filtrado) opcional como primer elemento de `params` para recibir solo las transacciones que coincidan. Omite `params` para recibir el flujo completo de Helius y BAM.

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe"
}
```

### Respuesta de suscripción

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "result": 24040,
  "id": 1
}
```

Guarda `result`: es el ID de suscripción que usarás para [cancelar la suscripción](#cancelar-la-suscripción). Después de esta confirmación, las notificaciones se transmiten como tramas binarias (consulta más abajo).

## Filtrado

De forma predeterminada, `preconfSubscribe` transmite todas las transacciones de ambas fuentes. Para limitar el flujo, pasa un objeto de filtro como primer elemento de `params`. El filtrado se realiza en el servidor, por lo que solo pagas y recibes las transacciones que te interesan.

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe",
  "params": [
    {
      "includeBam": true,
      "failed": false,
      "regionInclude": ["ewr", "fra"],
      "accountInclude": ["9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"],
      "accountExclude": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
      "accountRequired": ["11111111111111111111111111111111"]
    }
  ]
}
```

Todos los campos son opcionales. Si falta un campo, significa que ese predicado «no tiene restricciones», por lo que un filtro vacío (o la ausencia de `params`) coincide con todas las transacciones de ambas fuentes.

| Campo             | Tipo       | Semántica                                                                                                                                                                                                                                         |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `includeBam`      | `boolean`  | El valor predeterminado es `true`. `false` descarta las preconfirmaciones de BAM para que solo recibas preconfirmaciones de Helius.                                                                                                               |
| `failed`          | `boolean`  | `true` devuelve solo transacciones fallidas (revertidas); `false` devuelve solo transacciones correctas. Cualquiera de los dos valores excluye las transacciones de Helius con estado desconocido. Omite el campo para recibir todos los estados. |
| `regionInclude`   | `string[]` | Si no está vacío, la transacción debe originarse en **una de** estas [regiones](#filtrado-por-ubicación).                                                                                                                                         |
| `accountInclude`  | `string[]` | Si no está vacío, la transacción debe hacer referencia a **al menos una** de estas cuentas.                                                                                                                                                       |
| `accountExclude`  | `string[]` | La transacción se descarta si hace referencia a **cualquiera** de estas cuentas. Tiene prioridad sobre `accountInclude`.                                                                                                                          |
| `accountRequired` | `string[]` | La transacción debe hacer referencia a **todas** estas cuentas.                                                                                                                                                                                   |

Reglas de filtrado:

* Todos los predicados se combinan mediante AND y se evalúan en el orden `includeBam` → `failed` → `regionInclude` → `accountExclude` → `accountRequired` → `accountInclude`.
* Las preconfirmaciones con estado desconocido ignoran el filtro de estado `failed` y se entregan si coinciden con los filtros de fuente, región y cuenta.
* Las cuentas son claves públicas codificadas en base58. Un valor no válido devuelve el error JSON-RPC `-32602` (parámetros no válidos).
* Cada lista de cuentas tiene un límite de **500** entradas.

Para recibir solo preconfirmaciones de Helius:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe",
  "params": [{ "includeBam": false }]
}
```

### Resolución de tablas de búsqueda de direcciones (ALT)

Los filtros de cuentas no solo coinciden con las claves de cuentas estáticas de la transacción. Helius resuelve las [tablas de búsqueda de direcciones](/docs/es/glossary#tabla-de-consulta-de-direcciones-alt) v0 en el servidor, por lo que `accountInclude`, `accountExclude` e `accountRequired` también coinciden con las cuentas que una transacción carga mediante una ALT.

Esto significa que puedes filtrar por cualquier cuenta que toque una transacción, incluso cuando solo aparezca detrás de una tabla de búsqueda. No necesitas mantener asignaciones de ALT ni resolver las tablas por tu cuenta. Solo pasa la clave pública de la cuenta y Helius se encargará de resolverla antes de aplicar el filtro.

### Filtrado por ubicación

Usa `regionInclude` para recibir solo transacciones que se originen en regiones específicas. Pasa uno o más códigos de región. Una transacción supera el filtro cuando su región de origen coincide con cualquiera de ellos.

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe",
  "params": [{ "regionInclude": ["ewr", "fra"] }]
}
```

La región de origen depende de la fuente. Para las preconfirmaciones de Helius, es la región de Helius que recibió la transacción. Para las preconfirmaciones de BAM, es el endpoint regional de BAM que emitió la preconfirmación, no el lugar donde Helius la recibió. Los endpoints de BAM en Singapur y Dallas corresponden a `sgp` e `dal`.

Códigos de región válidos:

| Código | Ubicación          |
| ------ | ------------------ |
| `slc`  | Salt Lake City     |
| `fra`  | Fráncfort          |
| `lon`  | Londres            |
| `pit`  | Pittsburgh         |
| `sgp`  | Singapur           |
| `ewr`  | Newark             |
| `tyo`  | Tokio              |
| `ams`  | Ámsterdam          |
| `dal`  | Dallas             |
| `dub`  | Dublín             |
| `mia`  | Miami              |
| `lax`  | Los Ángeles        |
| `iad`  | Ashburn            |
| `sea`  | Seattle            |
| `hkg`  | Hong Kong          |
| `sqq`  | Šiauliai, Lituania |

<Note>
  Cuando se establece `regionInclude`, se descartan las transacciones que no incluyen información sobre la región. Un código de región no reconocido devuelve el error JSON-RPC `-32602` (parámetros no válidos).
</Note>

## Carga útil de la notificación

Las notificaciones se entregan como tramas WebSocket **binarias** (no JSON). Las preconfirmaciones de Helius y BAM comparten la misma estructura. Cada trama tiene una estructura de bytes compacta que contiene una sola transacción:

| Bytes | Campo         | Tipo                  | Descripción                                                                                                                                                                                                                                             |
| ----- | ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0     | `version`     | `u8`                  | Versión del esquema de la carga útil. Actualmente es `1`.                                                                                                                                                                                               |
| 1–8   | `slot`        | `u64` (little-endian) | El slot al que pertenece la transacción.                                                                                                                                                                                                                |
| 9–16  | `tx_index`    | `u64` (little-endian) | Índice de la transacción dentro del slot. Siempre es `0` para las preconfirmaciones de BAM. BAM ordena las transacciones por ID de secuencia y posición del paquete, en lugar de usar un índice de slot, y este flujo no incluye ninguno de esos datos. |
| 17    | `status`      | `u8`                  | Estado de la transacción: `0` = fallida, `1` = correcta, `2` = desconocido.                                                                                                                                                                             |
| 18+   | `transaction` | `bytes`               | La transacción en formato de transmisión de Solana. Consulta [Decodificar la transacción](#decodificar-la-transacción).                                                                                                                                 |

La carga útil no tiene un campo de fuente. No deduzcas un origen de BAM a partir de `tx_index = 0`, ya que las preconfirmaciones de Helius pueden incluir los mismos valores.

### Distinguir las dos fuentes

Como no hay un campo de fuente, no puedes etiquetar un mensaje cualquiera como procedente de Helius o BAM. El byte `status` proporciona un clasificador unidireccional:

* **`status` es `0` o `1`**: el mensaje es una preconfirmación de Helius y la transacción se ejecutó. BAM nunca informa estos valores.
* **`status` es `2`**: la fuente es ambigua. Puede ser una preconfirmación de BAM o una preconfirmación de Helius cuyo estado de ejecución no estaba disponible.

Ningún otro campo permite distinguirlas. Este flujo no incluye el ID de secuencia ni la posición del paquete de BAM, por lo que no hay metadatos de ordenamiento de BAM que puedas usar como clave. Además, `regionInclude` es un filtro de suscripción y no un campo de la carga útil, por lo que no puede leerse en cada mensaje.

Si necesitas que todos los mensajes de un flujo incluyan el mismo tipo de evidencia, configura `includeBam: false`. Así solo quedan las preconfirmaciones de Helius, todas emitidas cuando el líder ejecuta la transacción. No existe un filtro exclusivo para BAM.

<Warning>
  **Lee y comprueba siempre primero el byte `version`.** Actualmente es `1`. Si
  Helius necesita actualizar el formato de la carga útil, la versión aumentará. Crea una rama
  según este valor para que tu decodificador siga funcionando cuando cambie el esquema.
</Warning>

<Note>
  Una preconfirmación es una señal temprana, no una garantía. La transacción aún no
  se ha incorporado onchain y todavía podría descartarse. Además, el estado de ejecución de una preconfirmación de Helius
  refleja el resultado local del líder, que no es definitivo hasta que
  se confirma el bloque. Confirma la inclusión mediante comprobaciones de compromiso estándar
  antes de considerarla definitiva.
</Note>

### Decodificar la transacción

Los bytes de la transacción se reenvían exactamente como los serializó el validador, con la codificación de transmisión estándar correspondiente a la versión de la transacción. Las transacciones heredadas y v0 usan la estructura con las firmas al principio que genera `bincode`. La transacción v1 ([SIMD-0385](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md)) usa una estructura con el mensaje al principio y las firmas al final, por lo que `bincode` falla con cargas útiles v1. Usa un decodificador compatible con todas las versiones:

* **Rust:** [`agave-transaction-view`](https://docs.rs/agave-transaction-view) analiza las transacciones heredadas, v0 y v1 directamente, sin una copia intermedia. Esta es la opción recomendada. [`wincode`](https://docs.rs/wincode), el serializador compatible con bincode que usan los SDK actuales de Solana, también decodifica v1 en `VersionedTransaction`.
* **JavaScript / TypeScript:** asegúrate de que la versión de tu biblioteca sea compatible con la transacción v1. Las implementaciones anteriores de `VersionedTransaction.deserialize` solo admiten transacciones heredadas y v0. Usa `@solana/kit` 8.0+ o `@solana/web3.js` v3. Consulta [Compatibilidad con transacciones v1](/docs/es/rpc/transaction-v1).

```rust theme={"system"}
use agave_transaction_view::transaction_view::TransactionView;

// `frame` is the full binary WebSocket message
let tx_bytes = &frame[18..];
let tx = TransactionView::try_new_unsanitized(tx_bytes)?;

println!("version: {:?}", tx.version()); // Legacy, V0, or V1
println!("signature: {}", tx.signatures()[0]);
for ix in tx.instructions_iter() {
    println!("program index {}: {} bytes", ix.program_id_index, ix.data.len());
}
```

## Notificaciones duplicadas

Las preconfirmaciones de Helius y BAM se desduplican por fuente, no entre fuentes. Una pequeña proporción de las transacciones llega a Helius por ambas vías, por lo que puedes recibir dos veces la misma firma, y las dos copias pueden indicar slots diferentes.

Desduplica por firma en el cliente y haz que las acciones activadas por transacciones sean idempotentes, para que una segunda notificación no ejecute dos veces la misma acción. Confirma la ejecución y la inclusión mediante comprobaciones de compromiso estándar.

## Ejemplo

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

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

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'preconfSubscribe' // Helius and BAM preconfirmations by default
    // Optional: txs from EWR/FRA touching a given account; Helius txs must be successful.
    // BAM ignores the status filter; region and account filters still apply.
    // params: [{ failed: false, regionInclude: ['ewr', 'fra'], accountInclude: ['9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM'] }]
    // Optional: Helius preconfirmations only
    // params: [{ includeBam: false }]
  }));

  // Keep the connection alive
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data, isBinary) => {
  // The subscribe acknowledgement arrives as a JSON text frame
  if (!isBinary) {
    const msg = JSON.parse(data.toString());
    if (msg.id === 1) console.log('Subscribed, ID:', msg.result);
    return;
  }

  // Notifications arrive as binary frames:
  // version (u8) | slot (u64 LE) | tx_index (u64 LE) | status (u8) | transaction bytes
  const buf = Buffer.from(data);
  const version = buf.readUInt8(0); // currently 1 — branch on this if it changes
  if (version !== 1) return; // unknown schema version; update your decoder
  const slot = buf.readBigUInt64LE(1);
  const txIndex = buf.readBigUInt64LE(9); // always 0 for BAM preconfirmations
  const status = buf.readUInt8(17); // 0 = failed, 1 = success, 2 = unknown
  const txBytes = buf.subarray(18); // transaction in Solana wire format (legacy, v0, or v1)

  console.log('Preconfirmation:', { version, slot, txIndex, status, bytes: txBytes.length });
  // Decode txBytes with a decoder that supports transaction v1 (see "Decoding the transaction")
});

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

## Cancelar la suscripción

Para dejar de recibir notificaciones, llama a `preconfUnsubscribe` con el ID de suscripción devuelto por `preconfSubscribe`.

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "preconfUnsubscribe",
  "params": [24040]
}
```

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "result": true,
  "id": 2
}
```

## Precios

Preconfirmations requiere un **plan Professional o superior** y cuesta **10 créditos por mensaje** —un mensaje por transacción transmitida—, que se facturan con cargo a tu plan. Consulta [Créditos](/docs/es/billing/credits) para obtener más información.

La facturación se realiza por mensaje, no por firma única. Una transacción entregada tanto por Helius como por BAM cuenta dos veces. Configura `includeBam: false` si solo quieres preconfirmaciones de Helius.

<Note>
  Preconfirmations es un producto nuevo y los precios están sujetos a cambios.
</Note>

## Contenido relacionado

<CardGroup cols={2}>
  <Card title="Preconfirmations Overview" icon="bolt" href="/docs/es/pre-confirmations/overview">
    Qué son las Preconfirmations y dónde se ubican en el flujo de procesamiento del validador.
  </Card>

  <Card title="transactionSubscribe" icon="tower-broadcast" href="/docs/es/rpc/websocket/transaction-subscribe">
    Transmite transacciones con nivel de compromiso confirmado mediante filtros avanzados.
  </Card>

  <Card title="preconfSubscribe API reference" icon="code" href="/docs/es/api-reference/pre-confirmations/preconfsubscribe">
    Parámetros de solicitud, campos de filtro y estructura de la notificación binaria.
  </Card>
</CardGroup>
