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

# Échanges de terrains avec Sender

> Construisez une boucle d'envoi à faible latence avec Helius Sender : points de terminaison régionaux, connexion préchauffée, frais de priorité dynamiques, astuces et confirmation d'atterrissage avec des tentatives de nouvelle envoi.

Sender soumet simultanément votre transaction à travers chaque voie à grande vitesse (Helius, Jito, Harmonic, Rakurai) et ne consomme aucun crédit API. Vous payez par envoi avec un pourboire en SOL. Ce guide construit une boucle d'envoi en production avec des connexions chaudes, des frais à prix réel et une confirmation avec une politique de nouvelle tentative.

## Choisissez votre niveau

[Sender Max](/docs/fr/sending-transactions/sender-max) (pourboire minimum de 0,001 SOL) s'adresse à toutes les voies et entre dans le tampon de pourboires prioritaires, où un plus grand pourboire atterrit en premier.

[SWQOS-only](/docs/fr/sending-transactions/sender-swqos-only) (0,000005 SOL) prend une seule voie rapide pour un flux optimisé en termes de coûts. Ajoutez `?swqos_only=true` à l'URL du point de terminaison.

Les pourboires entre les deux minimums sont des meilleurs efforts à travers moins de voies, donc choisissez l'un ou l'autre niveau.

## Choisissez votre point de terminaison

Les backends doivent utiliser le point de terminaison HTTP régional le plus proche de leurs serveurs (`http://ewr-sender.helius-rpc.com/fast`, `fra`, `slc`, `ams`, `lon`, `sg`, `tyo`).

Les navigateurs doivent utiliser le point de terminaison HTTPS global `https://sender.helius-rpc.com/fast`, qui s'auto-route et évite les problèmes CORS.

## Préchauffez la connexion

Une poignée de main TCP/TLS à froid ajoute une latence au premier envoi après une période d'inactivité.

Si votre système peut dépasser environ 5 secondes entre les envois, gardez la connexion chaude avec le point de terminaison ping :

```typescript theme={"system"}
const SENDER = 'http://ewr-sender.helius-rpc.com';

setInterval(async () => {
  try {
    await fetch(`${SENDER}/ping`);
  } catch (e) {
    console.warn('warm-up failed:', e);
  }
}, 5_000);
```

## Construisez la transaction

Chaque transaction Sender doit inclure à la fois un transfert de pourboire à un compte de pourboire désigné et un prix d'unité de calcul. Sender rejette les transactions manquant soit l'un soit l'autre.

Le codage en dur des frais de priorité vous fait surpayer sur les marchés calmes et perdre des courses sur les marchés chargés, alors fixez-les à partir de l'[API des frais de priorité](/docs/fr/priority-fee-api) :

```typescript send.ts theme={"system"}
import {
  Connection, TransactionMessage, VersionedTransaction,
  SystemProgram, PublicKey, Keypair, ComputeBudgetProgram, LAMPORTS_PER_SOL
} from '@solana/web3.js';

const RPC = 'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY';
const TIP_ACCOUNTS = [
  '4ACfpUFoaSD9bfPdeu6DBt89gB6ENTeHBXCAi87NhDEE',
  'D2L6yPZ2FmmmTKPgzaMKdhu6EWZcTpLy1Vhx8uvZe7NZ',
  '9bnz4RShgq1hAnLnZbP8kbgBg1kEmcJBYQq3gQbmnSta'
];

async function buildTransaction(keypair: Keypair, tradeInstructions: any[]) {
  const connection = new Connection(RPC);
  const { blockhash } = await connection.getLatestBlockhash('confirmed');

  // Price the fee against the accounts the trade touches
  const feeRes = await fetch(RPC, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0', id: '1', method: 'getPriorityFeeEstimate',
      params: [{
        accountKeys: tradeInstructions.flatMap(ix => ix.keys.map((k: any) => k.pubkey.toBase58())),
        options: { recommended: true }
      }]
    })
  });
  const { result } = await feeRes.json();

  const tx = new VersionedTransaction(
    new TransactionMessage({
      instructions: [
        ComputeBudgetProgram.setComputeUnitLimit({ units: 100_000 }),
        ComputeBudgetProgram.setComputeUnitPrice({ microLamports: result.priorityFeeEstimate }),
        ...tradeInstructions,
        SystemProgram.transfer({
          fromPubkey: keypair.publicKey,
          toPubkey: new PublicKey(TIP_ACCOUNTS[Math.floor(Math.random() * TIP_ACCOUNTS.length)]),
          lamports: 0.001 * LAMPORTS_PER_SOL // Sender Max minimum; tip more to land first
        })
      ],
      payerKey: keypair.publicKey,
      recentBlockhash: blockhash
    }).compileToV0Message()
  );
  tx.sign([keypair]);
  return tx;
}
```

Le pourboire détermine quelles voies votre transaction peut emprunter, et les frais de priorité augmentent sa position dans la file d'attente du validateur. Ensemble, ils maximisent la probabilité d'inclusion.

## Envoyer, puis confirmer

Soumettez avec `skipPreflight: true` pour échanger la validation côté client contre la latence, puis confirmez via votre connexion RPC.

Sender renvoie immédiatement la signature, ce qui n'est pas une preuve d'atterrissage :

```typescript theme={"system"}
async function sendAndConfirm(tx: VersionedTransaction): Promise<string> {
  const signature = await send(tx);

  const connection = new Connection(RPC);
  for (let i = 0; i < 30; i++) {
    const { value } = await connection.getSignatureStatuses([signature]);
    const status = value[0];
    if (status?.err) throw new Error(`Transaction failed: ${JSON.stringify(status.err)}`);
    if (status?.confirmationStatus === 'confirmed' || status?.confirmationStatus === 'finalized') {
      return signature;
    }
    await new Promise(r => setTimeout(r, 1_000));
  }
  throw new Error('Not confirmed within 30s: rebuild with a fresh blockhash and resend');
}

async function send(tx: VersionedTransaction): Promise<string> {
  const res = await fetch(`${SENDER}/fast`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: Date.now().toString(),
      method: 'sendTransaction',
      params: [
        Buffer.from(tx.serialize()).toString('base64'),
        { encoding: 'base64', skipPreflight: true, maxRetries: 0 }
      ]
    })
  });
  const json = await res.json();
  if (json.error) throw new Error(json.error.message);
  return json.result;
}
```

Avec `maxRetries: 0` vous possédez la politique de nouvelle tentative : lorsque la confirmation expire, reconstruisez avec un nouveau blockhash et des frais réévalués au lieu de renvoyer la transaction obsolète.

Le débit par défaut est de 50 TPS. Les plans professionnels peuvent [demander des limites plus élevées](https://www.helius.dev/contact).

## Optionnel : contournez les attaquants en sandwich

Ajoutez `?mev-protect=true` à l'URL du point de terminaison pour éviter les validateurs statistiquement liés aux attaques sandwich. Le corps de la requête reste inchangé, et cela fonctionne sur les deux niveaux :

```text theme={"system"}
http://ewr-sender.helius-rpc.com/fast?mev-protect=true
```

Voir [MEV Protect](/docs/fr/sending-transactions/mev-protect) pour les compromis. Pour une exécution multi-transaction atomique (jusqu'à 4 transactions, tout-ou-rien), utilisez [`sendBundle`](/docs/fr/sending-transactions/sender-max#paquets) sur le même point de terminaison.

## Guides connexes

<CardGroup cols={2}>
  <Card title="Aperçu de Sender" icon="paper-plane" href="/docs/fr/sending-transactions/sender">
    Niveaux, points de terminaison, comptes de pourboires et limites de taux en entier
  </Card>

  <Card title="Échanger sur les pré-confirmations" icon="stopwatch" href="/docs/fr/pre-confirmations/guides/trade-on-preconfirmations">
    Associer le chemin d'envoi le plus rapide avec le signal de transaction le plus tôt
  </Card>
</CardGroup>
