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

# Opera con transacciones preprocesadas

> Observa las transacciones de Solana de un programa antes de que alcancen el nivel de compromiso processed con preprocessedSubscribe.

`preprocessedSubscribe` transmite transacciones firmadas antes de que alcancen el nivel de compromiso `processed`. Las decodifica a partir de los shreds a medida que llegan al validador, sin que necesites infraestructura para reconstruirlos.

Esta guía crea un monitor que observa un programa de trading antes de la ejecución, elimina duplicados del flujo, se mantiene por debajo del límite de contrapresión del servidor y coteja los datos procesados antes de actuar.

<Tip>
  Las [transacciones preprocesadas](/docs/es/preprocessed-transactions/overview) están disponibles en todos los planes de pago y cuestan 0.1 créditos por mensaje, con hasta 10 conexiones simultáneas por API key.
</Tip>

## Limita la suscripción a tu objetivo

No existe un flujo sin filtros: `accountInclude` e `accountRequired` deben especificar al menos una cuenta entre ambos. Para un monitor de trading, incluye el programa con el que operas y excluye el ruido por el que, de otro modo, pagarías:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preprocessedSubscribe",
  "params": {
    "accountInclude": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
    "accountExclude": ["Vote111111111111111111111111111111111111111"],
    "accountRequired": []
  }
}
```

Los filtros se combinan con AND, cada lista admite hasta 5,000 direcciones y Helius resuelve las tablas de búsqueda de direcciones en el servidor, por lo que una cuenta cargada mediante una ALT también coincide. Para observar las interacciones de una billetera específica con el programa, coloca ambos en el campo `accountRequired`.

## Decodifica las tramas y elimina duplicados por firma

Las notificaciones llegan como tramas binarias: un prefijo de 73 bytes seguido de la transacción serializada con bincode. La firma está en el prefijo, por lo que puedes eliminar duplicados sin decodificar el cuerpo. El flujo agrega varias fuentes previas a la ejecución, y la misma transacción puede llegar más de una vez:

```javascript monitor.js theme={"system"}
const WebSocket = require('ws');
const bs58module = require('bs58');
const bs58 = bs58module.default ?? bs58module;

const ws = new WebSocket('wss://beta.helius-rpc.com/?api-key=YOUR_API_KEY');
const seen = new Set(); // rotate or expire entries in production
const queue = [];       // decode off the receive path; see next step

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'preprocessedSubscribe',
    params: {
      accountInclude: ['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
      accountExclude: ['Vote111111111111111111111111111111111111111'],
      accountRequired: []
    }
  }));
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data, isBinary) => {
  if (!isBinary) {
    const msg = JSON.parse(data.toString());
    if (msg.id === 1) console.log('Subscribed, ID:', msg.result);
    return;
  }

  // version (u8) | slot (u64 LE) | signature ([u8; 64]) | bincode(VersionedTransaction)
  const buf = Buffer.from(data);
  if (buf.readUInt8(0) !== 1) return; // unknown schema version; update your decoder
  const signature = bs58.encode(buf.subarray(9, 73));
  if (seen.has(signature)) return;
  seen.add(signature);

  queue.push({
    slot: buf.readBigUInt64LE(1),
    signature,
    txBytes: buf.subarray(73)
  });
});

ws.on('error', console.error);
ws.on('close', () => process.exit(1)); // supervisor restarts and resubscribes
```

## Mantén el bucle de recepción más rápido que el flujo

Helius no almacena datos indefinidamente en búfer para consumidores lentos: si se acumulan más de 4,000 mensajes en el servidor, la conexión se cierra. Por eso, el controlador anterior solo lee el prefijo de 73 bytes y lo agrega a la cola.

La deserialización y la lógica de la estrategia se ejecutan en un bucle separado:

```javascript theme={"system"}
setImmediate(async function drain() {
  const { VersionedTransaction } = require('@solana/web3.js');
  while (true) {
    const item = queue.shift();
    if (!item) { await new Promise(r => setTimeout(r, 1)); continue; }
    const tx = VersionedTransaction.deserialize(item.txBytes);
    strategy.onPreExecution(item.slot, item.signature, tx);
  }
});
```

Si la cola crece sin límite, restringe los filtros. Las transacciones que descartes en el cliente siguen costando 0.1 créditos cada una y también cuentan para el límite de contrapresión.

## Coteja con los datos procesados

Una transacción preprocesada muestra lo que el remitente intentó hacer, no lo que ocurrió. No incluye el estado de ejecución, los cambios de saldo ni los registros, y puede fallar, descartarse o incluirse en una bifurcación diferente. La entrega se realiza con el mejor esfuerzo y no incluye reproducción histórica, por lo que debes hacer lo siguiente:

* Coteja con [`transactionSubscribe`](/docs/es/rpc/websocket/transaction-subscribe) en el nivel de compromiso `processed` o `confirmed` antes de que tu estrategia registre algo como un hecho.
* Si se desconecta, vuelve a suscribirte de inmediato y acepta el vacío, ya que no hay reproducción para rellenarlo.
* Si necesitas el estado de una cuenta en tiempo real en lugar de intenciones de transacción, solo está disponible después de la ejecución: usa [LaserStream gRPC](/docs/es/laserstream) en `processed`.

## Guías relacionadas

<CardGroup cols={2}>
  <Card title="preprocessedSubscribe reference" icon="code" href="/docs/es/preprocessed-transactions/preprocessed-subscribe">
    Diseño completo del payload, reglas de filtrado, contrapresión y precios
  </Card>

  <Card title="Trade on Preconfirmations" icon="stopwatch" href="/docs/es/pre-confirmations/guides/trade-on-preconfirmations">
    La señal de transacción más temprana que ofrece Helius, directamente desde el planificador
  </Card>
</CardGroup>
