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

# Cách sử dụng Jupiter Swap API và Helius Sender để giao dịch

> Tìm hiểu cách thực hiện thành công các giao dịch bằng Swap API của Jupiter và Helius Sender, một dịch vụ gửi giao dịch Solana có độ trễ cực thấp.

## Sử dụng Helius Sender với Jupiter Swap API

Helius Sender là dịch vụ gửi giao dịch Solana có độ trễ thấp, gửi giao dịch của bạn qua mọi tuyến đường (Helius, Jito, Harmonic, Rakurai, v.v.), giúp tối đa hóa tốc độ đưa vào khối và tỷ lệ thực hiện thành công.

Swap API của Jupiter cho phép bạn tìm tuyến đường có mức giá tối ưu nhất cho các giao dịch hoán đổi và tạo sẵn một giao dịch để sử dụng.

Việc kết hợp hai công cụ này giúp nhà giao dịch nắm bắt cơ hội trước đối thủ và tăng khả năng giao dịch hoán đổi thành công.

<Tip>
  Sender được cung cấp công khai — không yêu cầu gói dịch vụ.
</Tip>

## Cách hoạt động

<ol>
  <li>Nhận báo giá từ Jupiter cho một cặp giao dịch</li>
  <li>Dùng báo giá đó để tạo giao dịch hoán đổi bằng [Swap API của Jupiter](https://dev.jup.ag/docs/api/swap-api/swap)</li>
  <li>Điều chỉnh giao dịch để tương thích với Sender</li>
  <li>Phát tán giao dịch qua Helius Sender để tối đa hóa tỷ lệ thành công</li>
</ol>

## Yêu cầu

<Card>
  <ul>
    <li><strong>Node.js ≥ 20</strong> (đã kiểm thử với v20.9.0)</li>
    <li><strong>TypeScript ≥ 5</strong></li>
    <li>Một [tài khoản Helius](https://dashboard.helius.dev/signup) (miễn phí hoặc trả phí) để truy cập RPC</li>
    <li>Một <strong>ví Solana</strong> có đủ SOL để trả phí giao dịch và tiền tip</li>
  </ul>

  <Tip>
    Cài đặt các phần phụ thuộc trên toàn hệ thống: <code>npm i -g typescript</code>
  </Tip>
</Card>

## Triển khai

<Steps>
  <Step title="Set up the environment">
    ```bash theme={"system"}
    npx tsc --init
    npm install @solana/web3.js bs58
    npm install --save-dev @types/node
    ```

    Đặt `"types": ["node"]` trong `tsconfig.json` của bạn

    Đặt `"type": "module"` trong `package.json`
  </Step>

  <Step title="Create the Jupiter Swap Client">
    Tạo một tệp có tên `jupiter-swap-sender.ts` với đoạn mã sau:

    ```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">
    Thay API key và khóa riêng tư được mã hóa cứng bằng thông tin xác thực của bạn. Đặt đúng các tham số cho giao dịch hoán đổi: địa chỉ token, số lượng và độ trượt giá. Chọn [điểm cuối Sender](https://dashboard.helius.dev/sender) gần máy chủ của bạn nhất.
  </Step>

  <Step title="Run the Application">
    Chạy tập lệnh để thực hiện giao dịch hoán đổi Jupiter qua Helius Sender:

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

## Kết quả mẫu

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

[Giao dịch mẫu](https://orbmarkets.io/tx/2weWhhYyGA9xPqFaXVfR9FdBDAjM3AEbebYzEER2bLQn6JJ7tJ8wwtncbvD9qi2xFJuDxHdDGQWQWQ7m1cUCg74S?cluster=mainnet-beta\&tab=instructions)
