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

# Comment envoyer des transactions Solana

> Guide étape par étape pour construire des flux de travail d'envoi de transactions Solana robustes et de qualité production. Apprenez l'optimisation du calcul, les frais prioritaires et les stratégies de confirmation.

<Tip>
  Il s'agit du chemin d'envoi de transactions **basique** — facturé par envoi et préférable lorsque la fiabilité est plus importante que la vitesse brute (paiements, portefeuilles, applications). Si vous effectuez des transactions et avez besoin de la plus faible latence, utilisez plutôt [Helius
  Sender](/docs/fr/sending-transactions/sender).
</Tip>

Construire votre propre logique d'envoi de transactions est le meilleur moyen d'assurer des performances maximales, un contrôle et une fiabilité pour votre application. Bien que le [Helius SDK](/docs/fr/sdks) fournisse un emballage pratique pour commencer, comprendre et mettre en œuvre ce flux de travail manuel est fortement recommandé pour les systèmes de production.

Ce guide vous guidera à travers les étapes nécessaires pour construire votre propre solution.

### Le flux de travail manuel

L'envoi manuel d'une transaction implique les étapes suivantes :

<Steps>
  <Step title="Construire la transaction initiale">
    Assemblez vos instructions et signez la transaction afin qu'elle puisse être simulée.
  </Step>

  <Step title="Optimiser les unités de calcul">
    Simulez la transaction pour déterminer précisément les unités de calcul nécessaires et ajoutez une petite marge.
  </Step>

  <Step title="Ajouter des frais prioritaires">
    Obtenez une estimation des frais de l'API Helius Priority Fee et ajoutez-la à votre transaction.
  </Step>

  <Step title="Envoyer et rediffuser">
    Envoyez la transaction finale et implémentez une stratégie de sondage robuste pour gérer la confirmation.
  </Step>
</Steps>

<Info>
  Les SDK Helius sont open-source. Vous pouvez consulter le code sous-jacent pour la méthode `sendSmartTransaction` dans notre [SDK TypeScript](https://github.com/helius-labs/helius-sdk) et [SDK Rust](https://github.com/helius-labs/helius-rust-sdk) pour voir une mise en œuvre de qualité production de ce flux de travail.
</Info>

### 1. Construire la transaction initiale

Tout d'abord, rassemblez toutes les instructions que vous souhaitez inclure dans votre transaction. Ensuite, créez un objet `Transaction` ou `VersionedTransaction`. Vous devrez également récupérer un blockhash récent.

Cet exemple prépare une transaction versionnée. À ce stade, vous devez également la signer pour qu'elle puisse être simulée à l'étape suivante.

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

const connection = new Connection("YOUR_RPC_URL");
const fromKeypair = Keypair.generate(); // Assume this is funded
const toPubkey = Keypair.generate().publicKey;

// 1. Build your instructions
const instructions = [
  SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey: toPubkey,
    lamports: 0.001 * LAMPORTS_PER_SOL,
  }),
];

// 2. Get a recent blockhash
const { blockhash } = await connection.getLatestBlockhash();

// 3. Compile the transaction message
const messageV0 = new TransactionMessage({
  payerKey: fromKeypair.publicKey,
  recentBlockhash: blockhash,
  instructions,
}).compileToV0Message();

// 4. Create and sign the transaction
const transaction = new VersionedTransaction(messageV0);
transaction.sign([fromKeypair]);
```

### 2. Optimiser l'utilisation des unités de calcul (CU)

Pour éviter de gaspiller des frais ou que votre transaction échoue, vous devez définir la limite des unités de calcul (CU) aussi précisément que possible. Vous pouvez le faire en simulant la transaction à l'aide de la méthode RPC [`simulateTransaction`](/docs/fr/api-reference/rpc/http/simulatetransaction).

Il est recommandé de simuler d'abord avec une limite de CU élevée pour garantir que la simulation réussit, puis d'utiliser `unitsConsumed` de la réponse pour définir votre limite réelle.

```typescript theme={"system"}
import { ComputeBudgetProgram } from "@solana/web3.js";

// Create a test transaction with a high compute limit to ensure simulation succeeds
const testInstructions = [
    ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 }),
    ...instructions, // Your original instructions
];
const testMessage = new TransactionMessage({
    payerKey: fromKeypair.publicKey,
    recentBlockhash: blockhash,
    instructions: testInstructions,
}).compileToV0Message();
const testTransaction = new VersionedTransaction(testMessage);
testTransaction.sign([fromKeypair]);

// Simulate the transaction to get the exact CUs consumed
const { value: simulationResult } = await connection.simulateTransaction(testTransaction);

if (!simulationResult.unitsConsumed) {
  throw new Error("Simulation failed to return unitsConsumed");
}

// Add a 10% buffer to the CU estimate
const computeUnitLimit = Math.ceil(simulationResult.unitsConsumed * 1.1);

// Create the instruction to set the CU limit
const setCuLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit({
    units: computeUnitLimit,
});
```

Vous avez maintenant une instruction qui définit précisément la limite de calcul. Vous l'ajouterez à votre transaction finale.

### 3. Définir le bon frais prioritaire

Ensuite, déterminez le frais prioritaire optimal à ajouter à votre transaction. Utiliser l'API de frais prioritaires Helius [Priority Fee API](/docs/fr/priority-fee-api) est le meilleur moyen d'obtenir une estimation en temps réel basée sur les conditions actuelles du réseau.

Vous devrez appeler la méthode RPC `getPriorityFeeEstimate`. Pour maximiser les chances d'inclusion via les connexions misées de Helius, utilisez l'option `recommended: true`.

```typescript theme={"system"}
// The transaction needs to be serialized and base58 encoded
const serializedTransaction = bs58.encode(transaction.serialize());

const response = await fetch("YOUR_RPC_URL", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [
            {
                // Pass the serialized transaction
                transaction: serializedTransaction, 
                // Use 'recommended' for Helius's staked connections
                options: { recommended: true },
            },
        ],   
    }),
});
const data = await response.json();

if (!data.result || !data.result.priorityFeeEstimate) {
    throw new Error("Failed to get priority fee estimate");
}

const priorityFeeEstimate = data.result.priorityFeeEstimate;

// Create the instruction to set the priority fee
const setPriorityFeeInstruction = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFeeEstimate,
});
```

### 4. Construire, envoyer et confirmer

Maintenant, assemblez la transaction finale avec les nouvelles instructions de budget de calcul, envoyez-la et implémentez un mécanisme de sondage robuste pour confirmer qu'elle a bien été enregistrée.

<Warning>
  Ne vous fiez pas à la logique de réessai par défaut du fournisseur RPC (`maxRetries` dans [`sendTransaction`](/docs/fr/api-reference/rpc/http/sendtransaction)). Bien que les connexions mises de Helius transmettent votre transaction directement au leader, elle peut toujours être abandonnée. Vous devez implémenter votre propre logique de rediffusion pour une confirmation fiable.
</Warning>

Un modèle courant est de renvoyer la même transaction périodiquement jusqu'à l'expiration du blockhash. **Ne resignez la transaction que si vous obtenez également un nouveau blockhash.** Resigner avec le même blockhash peut entraîner la confirmation de transactions dupliquées.

```typescript theme={"system"}
// 1. Add the new instructions to your original set
const finalInstructions = [
  setCuLimitInstruction,
  setPriorityFeeInstruction,
  ...instructions,
];

// 2. Re-build and re-sign the transaction with the final instructions
const { blockhash: latestBlockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();

const finalMessage = new TransactionMessage({
  payerKey: fromKeypair.publicKey,
  recentBlockhash: latestBlockhash,
  instructions: finalInstructions,
}).compileToV0Message();

const finalTransaction = new VersionedTransaction(finalMessage);
finalTransaction.sign([fromKeypair]);

// 3. Send the transaction
const signature = await connection.sendTransaction(finalTransaction, {
  skipPreflight: true, // Optional: useful for bypassing client-side checks
});

// 4. Implement a polling loop to confirm the transaction
let confirmed = false;
while (!confirmed) {
    const statuses = await connection.getSignatureStatuses([signature]);
    const status = statuses && statuses.value && statuses.value[0];

    if (status && (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized')) {
        console.log('Transaction confirmed!');
        confirmed = true;
    }

    // Check if the blockhash has expired
    const currentBlockHeight = await connection.getBlockHeight();
    if (currentBlockHeight > lastValidBlockHeight) {
        console.log('Blockhash expired, transaction failed.');
        break;
    }
    
    // Wait for a short period before polling again
    await new Promise(resolve => setTimeout(resolve, 2000)); 
}
```

Cet exemple fournit une boucle de sondage basique. Une application de qualité production nécessiterait une logique plus sophistiquée, y compris la gestion des différents statuts de confirmation et des délais d'attente potentiels.

## Protégez-vous contre les attaques sandwich

Pour détourner votre transaction des validateurs statistiquement liés aux attaques sandwich, ajoutez le paramètre de requête `mev-protect=true` à votre URL RPC — aucun changement à votre logique de transaction :

```
https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY&mev-protect=true
```

<Card title="MEV Protect" icon="shield-halved" href="/docs/fr/sending-transactions/mev-protect">
  Voyez comment fonctionne MEV Protect, quelles méthodes il prend en charge et ses compromis.
</Card>

## Gagnez des remises sur vos transactions

Vous pouvez opter pour gagner une part du MEV généré par vos transactions, payée automatiquement en SOL — aucun changement à votre logique de transaction.

<Card title="Remises de transaction" icon="coins" href="/docs/fr/sending-transactions/backrun-rebates">
  Ajoutez un paramètre à vos appels `sendTransaction` pour commencer à gagner des remises en SOL.
</Card>

## Méthodes associées

<CardGroup cols={2}>
  <Card title="sendTransaction" href="/docs/fr/api-reference/rpc/http/sendtransaction">
    Envoyer une transaction signée au réseau
  </Card>

  <Card title="simulateTransaction" href="/docs/fr/api-reference/rpc/http/simulatetransaction">
    Simuler une transaction pour estimer les unités de calcul
  </Card>

  <Card title="getSignatureStatuses" href="/docs/fr/api-reference/rpc/http/getsignaturestatuses">
    Vérifier le statut de confirmation des transactions
  </Card>

  <Card title="getLatestBlockhash" href="/docs/fr/api-reference/rpc/http/getlatestblockhash">
    Obtenez un blockhash récent pour signer la transaction
  </Card>

  <Card title="getBlockHeight" href="/docs/fr/api-reference/rpc/http/getblockheight">
    Obtenez la hauteur de bloc actuelle pour les vérifications d'expiration
  </Card>
</CardGroup>
