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

# Diffusion de données Solana Pump AMM avec LaserStream

> Script LaserStream prêt à l'emploi qui diffuse en temps réel l'activité des comptes et transactions Pump.fun, avec statistiques continues et décodage de signatures.

Diffusez chaque mise à jour de compte Pump.fun et transaction en temps réel en utilisant le [SDK LaserStream](/docs/fr/laserstream/clients). Cette page décrit un script complet TypeScript que vous pouvez exécuter de bout en bout : il imprime chaque transaction au fur et à mesure, rapporte des statistiques continues (débit, payeurs de frais uniques, frais totaux en SOL) une fois par minute, et reste connecté lors des reconnexions automatiquement.

C'est un point de départ utile pour tout ce qui nécessite une visibilité continue de Pump.fun — bots de trading, tableaux de bord analytiques, pipelines d'alerte, ou simplement explorer la forme des données pour construire quelque chose de plus spécialisé.

<Info>
  **Prérequis :** Une [clé API Helius](https://dashboard.helius.dev/) (plan Business ou Professional pour Mainnet LaserStream) et Node.js 18+. Une connaissance des [Abonnements de Comptes](/docs/fr/laserstream/guides/account-subscription) et de la [Surveillance des Transactions](/docs/fr/laserstream/guides/transaction-monitoring) est utile mais non requise.
</Info>

***

## Configuration

Créez un nouveau projet, installez le SDK + `bs58` (utilisé pour décoder les signatures de transaction), et définissez votre clé API :

```bash theme={"system"}
mkdir pump-monitor && cd pump-monitor
npm init -y
npm install helius-laserstream bs58
npm install --save-dev typescript ts-node @types/node
npx tsc --init
export HELIUS_API_KEY=your-key-here
```

Choisissez le point de terminaison le plus proche de l'endroit où ce script s'exécutera — voir les [régions LaserStream](/docs/fr/laserstream/grpc#endpoints-mainnet).

***

## Le script

Enregistrez ceci comme `index.ts`, puis exécutez `npx ts-node index.ts` :

```typescript [expandable] theme={"system"}
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';
import bs58 from 'bs58';

const PUMP_PROGRAM_ID = '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P';

// Rolling stats across the session.
const stats = {
  startedAt: Date.now(),
  transactions: 0,
  successes: 0,
  failures: 0,
  uniquePayers: new Set<string>(),
  totalFeesLamports: 0,
  accountUpdates: 0,
};

async function handleUpdate(data: any) {
  if (data.transaction) {
    const tx = data.transaction.transaction;
    if (!tx) return;

    stats.transactions++;
    const failed = !!tx.meta?.err;
    failed ? stats.failures++ : stats.successes++;

    // tx.meta.fee is a u64 string — coerce before adding.
    stats.totalFeesLamports += Number(tx.meta?.fee ?? 0);

    // Fee payer is the first account in the message.
    const firstKey = tx.transaction?.message?.accountKeys?.[0];
    if (firstKey) {
      const payer = typeof firstKey === 'string' ? firstKey : bs58.encode(firstKey);
      stats.uniquePayers.add(payer);
    }

    // tx.signature is a Buffer in the SDK.
    const sig = bs58.encode(tx.signature);
    const slot = data.transaction.slot;
    const flag = failed ? '❌' : '✅';
    console.log(`${flag}  ${sig.slice(0, 12)}…  slot ${slot}  fee ${tx.meta?.fee} lamports`);
  }

  if (data.account) {
    stats.accountUpdates++;
    const acct = data.account.account;
    const pubkey = typeof acct.pubkey === 'string' ? acct.pubkey : bs58.encode(acct.pubkey);
    console.log(`📋  account ${pubkey}  ${acct.data?.length ?? 0} bytes`);
  }
}

function printReport() {
  const minutes = (Date.now() - stats.startedAt) / 60_000;
  console.log('\n📊  Pump.fun activity report');
  console.log(`   Runtime:           ${minutes.toFixed(1)} min`);
  console.log(`   Transactions:      ${stats.transactions} (${stats.successes} ok, ${stats.failures} failed)`);
  console.log(`   Throughput:        ${(stats.transactions / Math.max(minutes, 0.0001)).toFixed(1)} tx/min`);
  console.log(`   Unique fee payers: ${stats.uniquePayers.size}`);
  console.log(`   Total fees:        ${(stats.totalFeesLamports / 1e9).toFixed(4)} SOL`);
  console.log(`   Account updates:   ${stats.accountUpdates}\n`);
}

async function main() {
  const config: LaserstreamConfig = {
    apiKey: process.env.HELIUS_API_KEY ?? 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // pick the region closest to you
  };

  const subscriptionRequest: SubscribeRequest = {
    accounts: {
      'pump-accounts': {
        account: [],
        owner: [PUMP_PROGRAM_ID],
        filters: [],
      },
    },
    transactions: {
      'pump-transactions': {
        accountInclude: [PUMP_PROGRAM_ID],
        accountExclude: [],
        accountRequired: [],
        vote: false,
        failed: false,
      },
    },
    commitment: CommitmentLevel.CONFIRMED,
    slots: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    accountsDataSlice: [],
  };

  console.log('🚀  Streaming Pump.fun activity. Press Ctrl+C to stop.\n');

  const reportTimer = setInterval(printReport, 60_000);
  process.on('SIGINT', () => {
    clearInterval(reportTimer);
    printReport();
    process.exit(0);
  });

  await subscribe(config, subscriptionRequest, handleUpdate, async (error) => {
    console.error('Stream error:', error);
  });
}

main().catch(console.error);
```

***

## Ce que fait le script

### Un abonnement, deux blocs de filtres

Un seul appel `subscribe(...)` transporte deux groupes de filtres nommés :

* Le filtre **`accounts`** reçoit chaque compte possédé par le programme Pump.fun (courbes de liaison, état de la frappe, etc.) chaque fois que leurs données changent.
* Le filtre **`transactions`** reçoit chaque transaction qui interagit avec le programme Pump.fun. Les drapeaux `vote: false, failed: false` suppriment les votes et les transactions échouées avant qu'ils n'atteignent votre gestionnaire.

Les deux arrivent via un flux gRPC unique, donc le SDK n'a qu'une seule connexion à gérer. Si elle tombe, le SDK se reconnecte automatiquement et vous continuez à recevoir des mises à jour des deux filtres.

### Lecture des champs bruts

Quelques valeurs dans la charge utile nécessitent une petite conversion avant d'être faciles à utiliser :

* **`tx.signature`** est un [`Buffer`](https://nodejs.org/api/buffer.html). Passez-le par `bs58.encode(...)` pour obtenir la signature base58 que vous verriez dans un explorateur ou dans une réponse `getTransaction`.
* **`tx.meta.fee`** est un u64 stocké sous forme de chaîne pour que les valeurs au-dessus de `Number.MAX_SAFE_INTEGER` ne perdent pas de précision en JavaScript. Enveloppez-le dans `Number(...)` avant de faire des calculs. La même convention chaîne-pour-u64 s'applique à plusieurs champs de niveau bloc aussi — voir [Surveillance de Slot et Bloc](/docs/fr/laserstream/guides/slot-and-block-monitoring) pour la forme complète des données.

### Statistiques continues

Un `setInterval` imprime un instantané toutes les 60 secondes : total des transactions, succès versus échecs, débit, payeurs de frais uniques et frais totaux en SOL. Appuyez sur `Ctrl+C` pour un dernier instantané avant que le script ne se termine.

***

## Extension du script

Quelques directions pour aller plus loin :

* **Décodez les discriminateurs d'instruction** pour étiqueter les échanges comme `buy` / `sell` / `create` — voir [Décodage des Données de Transactions](/docs/fr/laserstream/guides/decoding-transaction-data) pour le modèle d'analyse.
* **Conservez** les statistiques continues dans une base de données (Postgres, Redis, ClickHouse) au lieu de `Set` / compteurs en mémoire.
* **Alertez** sur les seuils — grands payeurs de frais, pics soudains de volume, nouveaux comptes à courbe de liaison.
* **Rejouez** l'activité manquée au démarrage en définissant `fromSlot` sur `SubscribeRequest` (jusqu'à 24 heures en arrière — voir [Relecture Historique](/docs/fr/laserstream/historical-replay)).
* **Combinez** avec [Surveillance de Slot et Bloc](/docs/fr/laserstream/guides/slot-and-block-monitoring) pour un contexte de niveau bloc.

***

## Prochaines étapes

<CardGroup cols={2}>
  <Card title="Surveillance des Transactions" icon="receipt" href="/docs/fr/laserstream/guides/transaction-monitoring">
    Les modèles généraux de filtrage des transactions que ce script utilise.
  </Card>

  <Card title="Décodage des Données de Transactions" icon="binary" href="/docs/fr/laserstream/guides/decoding-transaction-data">
    Analysez la charge utile binaire des transactions en transactions Solana lisibles.
  </Card>

  <Card title="Abonnements de Comptes" icon="user" href="/docs/fr/laserstream/guides/account-subscription">
    Surveillez les changements d'état de comptes spécifiques avec des filtres.
  </Card>

  <Card title="Relecture Historique" icon="clock-rotate-left" href="/docs/fr/laserstream/historical-replay">
    Rejouez jusqu'à 24h d'activité passée de Pump.fun à partir d'un slot de départ.
  </Card>
</CardGroup>
