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

# Commerce sur les transactions prétraitées

> Surveillez les transactions Solana d'un programme avant qu'elles n'atteignent le niveau d'engagement traité avec preprocessedSubscribe.

`preprocessedSubscribe` diffuse les transactions signées avant qu'elles n'atteignent le niveau d'engagement `processed`, décodées à partir des fragments à leur arrivée au validateur, sans infrastructure de défragmentation requise de votre côté.

Ce guide construit un moniteur qui surveille un programme de trading avant exécution, déduplique le flux, reste sous la limite de contre-pression du serveur et rapproche les données traitées avant d'agir.

<Tip>
  [Transactions prétraitées](/docs/fr/preprocessed-transactions/overview) sont disponibles sur tous les plans payants et coûtent 0.1 crédits par message, avec jusqu'à 10 connexions simultanées par clé API.
</Tip>

## Ciblez l'abonnement sur votre objectif

Il n'y a pas de flux non filtré : `accountInclude` et `accountRequired` doivent nommer au moins un compte entre eux. Pour un moniteur de trading, incluez le programme contre lequel vous tradez et excluez le bruit que vous paieriez autrement :

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

Les filtres se combinent avec AND, chaque liste accepte jusqu'à 5 000 adresses, et Helius résout les tables de recherche d'adresses côté serveur, de sorte qu'un compte chargé via un ALT correspond toujours. Pour surveiller les interactions d'un portefeuille spécifique avec le programme, placez les deux dans le champ `accountRequired` à la place.

## Décoder les trames et dédupliquer par signature

Les notifications arrivent sous forme de trames binaires : un préfixe de 73 octets, puis la transaction sérialisée en bincode. La signature est dans le préfixe, vous pouvez donc dédupliquer sans décoder le corps. Le flux agrège plusieurs sources avant exécution, et la même transaction peut arriver plus d'une fois :

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

## Gardez la boucle de réception plus rapide que le flux

Helius ne tamponne pas indéfiniment pour les consommateurs lents : si plus de 4 000 messages s'accumulent côté serveur, la connexion est fermée. C'est pourquoi le gestionnaire ci-dessus ne lit que le préfixe de 73 octets et met en file d'attente.

La désérialisation et la logique de stratégie s'exécutent dans une boucle séparée :

```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 file d'attente croît sans limite, resserrez les filtres. Les transactions que vous écartez côté client coûtent toujours 0.1 crédits chacune et comptent toujours dans la limite de contre-pression.

## Reconcile against processed data

Une transaction prétraitée montre ce que l'expéditeur a essayé de faire, pas ce qui s'est passé. Elle ne comporte pas de statut d'exécution, de changements de solde ou de journaux, et elle peut échouer, être abandonnée ou atterrir sur une autre branche. La livraison est au mieux sans relecture historique, donc :

* Rapprochez-vous de [`transactionSubscribe`](/docs/fr/rpc/websocket/transaction-subscribe) à `processed` ou `confirmed` avant que votre stratégie ne réserve quoi que ce soit comme un fait.
* En cas de déconnexion, réabonnez-vous immédiatement et acceptez l'écart, car il n'y a pas de relecture pour le combler.
* Si vous avez besoin de l'état du compte en temps réel plutôt que des intentions de transaction, cela n'existe qu'après exécution : utilisez [LaserStream gRPC](/docs/fr/laserstream) à `processed`.

## Guides connexes

<CardGroup cols={2}>
  <Card title="Référence de preprocessedSubscribe" icon="code" href="/docs/fr/preprocessed-transactions/preprocessed-subscribe">
    Disposition complète de la charge utile, règles de filtrage, contre-pression, et tarification
  </Card>

  <Card title="Commerce sur les pré-confirmations" icon="stopwatch" href="/docs/fr/pre-confirmations/guides/trade-on-preconfirmations">
    Le signal de transaction le plus précoce offert par Helius, directement du planificateur
  </Card>
</CardGroup>
