> ## 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 utiliser Jupiter Swap API et Helius Sender pour le trading

> Apprenez à réaliser des échanges avec l'API Swap de Jupiter et Helius Sender, un service d'envoi de transactions Solana à ultra-faible latence.

## Utilisation de Helius Sender avec l'API Swap de Jupiter

Helius Sender est un service d'envoi de transactions Solana à faible latence qui envoie vos transactions à travers tous les chemins (Helius, Jito, Harmonic, Rakurai, etc.), maximisant la vitesse d'inclusion et le taux de réussite.

L'API Swap de Jupiter vous permet de trouver l'itinéraire le plus économique pour vos échanges et crée une transaction prête à l'emploi pour vous.

Combiner ces deux outils permet aux traders de saisir les opportunités de trading avant la concurrence et d'augmenter les chances de succès de l'échange.

<Tip>
  Sender est disponible publiquement — aucun abonnement n'est requis.
</Tip>

## Comment ça fonctionne

<ol>
  <li>Obtenez un devis Jupiter pour une paire de trading</li>
  <li>Utilisez-le pour créer une transaction d'échange avec [l'API Swap de Jupiter](https://dev.jup.ag/docs/api/swap-api/swap)</li>
  <li>Modifiez-le pour la compatibilité avec Sender</li>
  <li>Diffusez-le via Helius Sender pour maximiser le taux de réussite</li>
</ol>

## Exigences

<Card>
  <ul>
    <li><strong>Node.js ≥ 20</strong> (testé avec v20.9.0)</li>
    <li><strong>TypeScript ≥ 5</strong></li>
    <li>Un [compte Helius](https://dashboard.helius.dev/signup) (gratuit ou payant) pour l'accès RPC</li>
    <li>Un <strong>portefeuille Solana</strong> avec suffisamment de SOL pour les frais de transaction et pourboires</li>
  </ul>

  <Tip>
    Installez les dépendances globalement : <code>npm i -g typescript</code>
  </Tip>
</Card>

## Mise en œuvre

<Steps>
  <Step title="Configurer l'environnement">
    ```bash theme={"system"}
    npx tsc --init
    npm install @solana/web3.js bs58
    npm install --save-dev @types/node
    ```

    Définissez `"types": ["node"]` dans votre `tsconfig.json`

    Définissez `"type": "module"` dans `package.json`
  </Step>

  <Step title="Créer le client Jupiter Swap">
    Créez un fichier nommé `jupiter-swap-sender.ts` avec le code suivant :

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

    const PRIV_B58 = 'Your private key in base58';
    const HELIUS_API_KEY = 'Your Helius API key';

    const SENDER_ENDPOINT = 'http://ewr-sender.helius-rpc.com/fast';

    const SWAP_AMOUNT = 1000000; // 0.001 SOL
    const SWAP_FROM_TOKEN = "So11111111111111111111111111111111111111112";
    const SWAP_TO_TOKEN = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
    const SWAP_SLIPPAGE_BPS = 50;

    const TIP_ACCOUNTS = [
      "4ACfpUFoaSD9bfPdeu6DBt89gB6ENTeHBXCAi87NhDEE",
      "D2L6yPZ2FmmmTKPgzaMKdhu6EWZcTpLy1Vhx8uvZe7NZ",
      "9bnz4RShgq1hAnLnZbP8kbgBg1kEmcJBYQq3gQbmnSta",
      "5VY91ws6B2hMmBFRsXkoAAdsPHBJwRfBht4DXox3xkwn",
      "2nyhqdwKcJZR2vcqCyrYsaPVdAnFoJjiksCXJ7hfEYgD",
      "2q5pghRs6arqVjRvT5gfgWfWcHWmw1ZuCzphgd5KfWGJ",
      "wyvPkWjVZz1M8fHQnMMCDTQDbkManefNNhweYk5WkcF",
      "3KCKozbAaF75qEU33jtzozcJ29yJuaLJTy2jFdzUY8bT",
      "4vieeGHPYPG2MmyPRcYjdiDmmhN3ww7hsFNap8pVN3Ey",
      "4TQLFNWK8AovT1gFvda5jfw2oJeRMKEmw7aH6MGBJ3or"
    ];

    // Use the Jupiter API to get a quote
    // https://dev.jup.ag/docs/api/swap-api/quote
    async function getQuote(inputMint: string, outputMint: string, amount: number, slippageBps: number) {
      console.log("Request Jupiter quote");
      const url = `https://lite-api.jup.ag/swap/v1/quote?inputMint=${inputMint}&outputMint=${outputMint}&amount=${amount}&slippageBps=${slippageBps}`
      const response = (await fetch(url)).json();
      return response
    }

    // Use the Jupiter API to get a swap transaction, based on the quote response
    // https://dev.jup.ag/docs/api/swap-api/swap
    async function getSwap(quote: any) {
      console.log("Request Jupiter swap");

      const user_wallet = Keypair.fromSecretKey(bs58.decode(PRIV_B58));
      const url = "https://lite-api.jup.ag/swap/v1/swap"
      const args = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          quoteResponse: quote,
          userPublicKey: user_wallet.publicKey,
          dynamicComputeUnitLimit: true,
          prioritizationFeeLamports: {
            priorityLevelWithMaxLamports: {
              maxLamports: 1000000,
              priorityLevel: "veryHigh"
            }
          }
        })
      }
      const response = (await fetch(url, args)).json();
      return response;
    }

    async function createSenderTransactionFromSwapResponse(swapResponse: any) {
      console.log("Create transaction for Sender");

      // Deserialize the Jupiter transaction
      const transactionBase64 = swapResponse.swapTransaction
      const jupiterTransaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64'));

      // Get the Address Lookup Tables
      const connection = new Connection(
        'https://mainnet.helius-rpc.com/?api-key=' + HELIUS_API_KEY
      );

      let altAccountResponses = await Promise.all(
        jupiterTransaction.message.addressTableLookups.map(l => connection.getAddressLookupTable(l.accountKey))
      );

      let altAccounts: AddressLookupTableAccount[] = altAccountResponses.map(item => {
        if (item.value == null) throw new Error("ALT is null");
        return item.value;
      });

      // Use the Address Lookup Tables to decompile the transaction
      let decompiledMessage = TransactionMessage.decompile(jupiterTransaction.message, {
        addressLookupTableAccounts: altAccounts,
      });

      // Note that Jupiter has already added the Compute Budget instructions
      // Nothing needs to be done here

      // Add a tip instruction
      const user_wallet = Keypair.fromSecretKey(bs58.decode(PRIV_B58));
      const transferIx = SystemProgram.transfer({
        fromPubkey: user_wallet.publicKey,
        toPubkey: new PublicKey(TIP_ACCOUNTS[Math.floor(Math.random() * TIP_ACCOUNTS.length)]!),
        lamports: 0.001 * LAMPORTS_PER_SOL,
      })

      decompiledMessage.instructions.push(transferIx);

      // Compile the full transaction
      const transaction = new VersionedTransaction(decompiledMessage.compileToV0Message(altAccounts));

      // Sign the transaction
      transaction.sign([user_wallet]);

      return transaction;
    }

    async function broadcastTransactionWithSender(transaction: VersionedTransaction) {
      console.log("Send to Sender");

      const connection = new Connection(
        'https://mainnet.helius-rpc.com/?api-key=' + HELIUS_API_KEY
      );

      const response = await fetch(SENDER_ENDPOINT, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          jsonrpc: '2.0',
          id: Date.now().toString(),
          method: 'sendTransaction',
          params: [
            Buffer.from(transaction.serialize()).toString('base64'),
            {
              encoding: 'base64',
              skipPreflight: true, // Optional: skip for lower latency
              maxRetries: 0
            }
          ]
        })
      });

      const json = await response.json();

      if (json.error) {
        throw new Error(json.error.message);
      }

      console.log("Sender Response:");
      console.log(json);

      console.log("Wait for confirmation");
      const {blockhash, lastValidBlockHeight} = await connection.getLatestBlockhash();
      const result = await connection.confirmTransaction({
        blockhash,
        lastValidBlockHeight,
        signature: bs58.encode(transaction.signatures[0]!)
      }, 'confirmed');
      console.log("Confirmed");
    }

    async function main() {
      const amount = SWAP_AMOUNT.toString();
      const quote = await getQuote(SWAP_FROM_TOKEN, SWAP_TO_TOKEN, SWAP_AMOUNT, SWAP_SLIPPAGE_BPS);
      const swap = await getSwap(quote);
      const senderTransaction = await createSenderTransactionFromSwapResponse(swap);
      console.log("Signature:", bs58.encode(senderTransaction.signatures[0]!));
      await broadcastTransactionWithSender(senderTransaction);
    }

    main().catch(console.error);
    ```
  </Step>

  <Step title="Configuration">
    Remplacez la clé API et la clé privée codées en dur par vos identifiants. Définissez les bons paramètres pour votre échange : adresses des tokens, montant, glissement. Choisissez le [point de terminaison Sender](https://dashboard.helius.dev/sender) le plus proche de votre serveur.
  </Step>

  <Step title="Exécuter l'application">
    Exécutez le script pour effectuer un échange Jupiter via Helius Sender :

    ```bash theme={"system"}
    npx tsx jupiter-swap-sender.ts
    ```
  </Step>
</Steps>

## Exemple de sortie

```
Request Jupiter quote
Request Jupiter swap
Create transaction for Sender
Signature: 2weWhhYyGA9xPqFaXVfR9FdBDAjM3AEbebYzEER2bLQn6JJ7tJ8wwtncbvD9qi2xFJuDxHdDGQWQWQ7m1cUCg74S
Send to Sender
Sender Response:
{
  jsonrpc: '2.0',
  id: '1758913856910',
  result: '2weWhhYyGA9xPqFaXVfR9FdBDAjM3AEbebYzEER2bLQn6JJ7tJ8wwtncbvD9qi2xFJuDxHdDGQWQWQ7m1cUCg74S'
}
Wait for confirmation
Confirmed
```

[Transaction d'exemple](https://orbmarkets.io/tx/2weWhhYyGA9xPqFaXVfR9FdBDAjM3AEbebYzEER2bLQn6JJ7tJ8wwtncbvD9qi2xFJuDxHdDGQWQWQ7m1cUCg74S?cluster=mainnet-beta\&tab=instructions)
