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

# Panduan Pengoptimalan Transaksi Solana

> Optimalkan transaksi Solana untuk meminimalkan latensi konfirmasi dan memaksimalkan tingkat pengiriman. Pelajari biaya prioritas, unit komputasi, dan praktik terbaik.

Ada dua metode utama untuk mengirim transaksi di Solana:

1. Menggunakan [koneksi ber-stake](https://www.helius.dev/staked-connections) (bawaan)
2. Menggunakan layanan pendaratan khusus seperti [Sender](https://www.helius.dev/sender) (direkomendasikan)

Artikel ini membahas praktik terbaik pengoptimalan transaksi saat menggunakan koneksi ber-stake, yang merupakan metode bawaan untuk semua paket berbayar Helius.

Koneksi ber-stake paling sesuai untuk kasus penggunaan ketika latensi tidak bersifat kritis bagi bisnis Anda (misalnya pembayaran, dompet, aplikasi sosial, dan sebagainya).

Jika Anda seorang trader tingkat lanjut (misalnya propAMM, sniper, copy trader, bot likuidasi, arbitrase) yang mencari layanan pendaratan transaksi khusus dengan latensi sangat rendah, baca [tutorial Sender kami](/docs/id/sending-transactions/sender).

## Ringkasan

Koneksi ber-stake Helius menjamin pengiriman 100% transaksi dengan waktu konfirmasi minimal. Untuk mengoptimalkan tingkat keberhasilan pendaratan transaksi Anda dengan koneksi ber-stake, kami merekomendasikan praktik terbaik berikut:

* Gunakan komitmen "confirmed" untuk mengambil [blockhash terbaru](/docs/id/rpc/guides/getlatestblockhash)
* Tambahkan [biaya prioritas](/docs/id/sending-transactions/optimizing-transactions#menetapkan-biaya-prioritas-yang-tepat) dan hitung secara dinamis
* Optimalkan penggunaan unit komputasi (CU)
* Tetapkan `maxRetries` ke 0 dan terapkan logika percobaan ulang yang andal
* Kirim dengan `skipPreflight` yang ditetapkan ke `true` (opsional)

<Tip>
  Ingin mempelajari lebih lanjut? Kami membahas semua dasar-dasarnya dalam [postingan blog ini](https://www.helius.dev/blog/how-to-land-transactions-on-solana).
</Tip>

## Pengoptimalan yang Direkomendasikan untuk Trader

Untuk kasus penggunaan perdagangan yang sensitif terhadap latensi, kami merekomendasikan [penggunaan Sender](/docs/id/sending-transactions/sender).

Namun, jika Anda menggunakan koneksi ber-stake dan ingin mengoptimalkan konfigurasi agar memperoleh latensi serendah mungkin, kami merekomendasikan pengoptimalan berikut (selain menerapkan praktik terbaik yang disebutkan di atas):

* Server klien Anda (mesin yang digunakan untuk mengirim transaksi) harus berada di Amerika Serikat bagian timur atau Eropa Barat.
* Pilih FRA atau PIT jika Anda ingin menempatkannya di lokasi yang sama dengan server pengiriman transaksi Helius.
* Hindari pengiriman dari wilayah yang jauh dari jaringan validator (misalnya LATAM dan Afrika Selatan).
* Hangatkan cache regional Helius untuk meminimalkan latensi ekor.
* Hanya diperlukan satu thread pemanasan per wilayah—thread tambahan tidak akan memberikan manfaat apa pun.
* Kirim panggilan RPC [`getHealth`](/docs/id/rpc/guides/gethealth) setiap detik menggunakan endpoint dan kunci API yang sama dengan yang Anda gunakan untuk mengirim transaksi.

Manfaat ini hanya akan terasa bagi trader berpengalaman. Untuk pengembang aplikasi umum, kami merekomendasikan agar Anda mengikuti panduan di bagian Mengirim Transaksi Cerdas di bawah ini.

<Tip>
  Dapatkan data transaksi onchain secepat mungkin dengan [Raw Shreds (UDP)](/docs/id/shred-delivery/raw-shreds). [Berlangganan melalui Dasbor Helius Anda](https://dashboard.helius.dev/shred-delivery-seats).
</Tip>

## Mengirim Transaksi Cerdas

SDK Helius [TypeScript](/docs/id/sending-transactions/optimizing-transactions#sdk-typescript) dan [Rust](/docs/id/sending-transactions/optimizing-transactions#sdk-rust) dapat mengirim transaksi cerdas. Metode baru ini membuat dan mengirim transaksi yang telah dioptimalkan sekaligus menangani status konfirmasinya.

Pengguna dapat mengonfigurasi opsi pengiriman transaksi, seperti apakah transaksi harus melewati pemeriksaan preflight.

Pada tingkat paling dasar, pengguna harus memberikan keypair dan instruksi yang ingin dijalankan, lalu kami akan menangani sisanya.

Kami akan:

* Mengambil blockhash terbaru
* Membuat transaksi awal
* Menyimulasikan transaksi awal untuk mendapatkan jumlah unit komputasi (CU) yang digunakan
* Menetapkan batas CU ke jumlah CU yang digunakan pada langkah sebelumnya, dengan sedikit margin
* Mendapatkan biaya prioritas yang direkomendasikan Helius melalui [Priority Fee API](/docs/id/priority-fee-api) kami
* Menetapkan biaya prioritas (microlamport per CU) sesuai biaya yang direkomendasikan Helius
* Menambahkan sedikit biaya penyangga jika biaya yang direkomendasikan berubah dalam beberapa detik berikutnya
* Membuat dan mengirim transaksi yang telah dioptimalkan
* Mengembalikan tanda tangan transaksi jika berhasil

<Note>
  Mewajibkan nilai yang direkomendasikan (atau lebih tinggi) untuk koneksi ber-stake kami memastikan bahwa Helius mengirim transaksi berkualitas tinggi dan validator tidak akan membatasi laju permintaan kami.
</Note>

Metode ini merupakan cara termudah untuk membuat, mengirim, dan mendaratkan transaksi di Solana.

Dengan menggunakan biaya yang direkomendasikan Helius, transaksi yang dikirim oleh pengguna Helius melalui salah satu [paket berbayar standar](/docs/id/billing/plans) kami akan dirutekan melalui koneksi ber-stake kami, sehingga menjamin hampir 100% pengiriman transaksi dan latensi minimal.

### SDK TypeScript

Metode `sendSmartTransaction` tersedia dalam [SDK TypeScript Helius](/docs/id/sdks/typescript) kami untuk [versi >= 1.3.2](https://www.npmjs.com/package/helius-sdk). Untuk memperbarui ke versi SDK yang lebih baru, jalankan `npm update helius-sdk`.

Contoh ini mentransfer SOL ke akun pilihan Anda. Contoh ini menggunakan `sendSmartTransaction` untuk mengirim transaksi yang telah dioptimalkan tanpa melewati pemeriksaan preflight:

```typescript theme={"system"}
import { Helius } from "helius-sdk";
import {
  Keypair,
  SystemProgram,
  LAMPORTS_PER_SOL,
  TransactionInstruction,
} from "@solana/web3.js";

const helius = new Helius("YOUR_API_KEY");
const fromKeypair = /* Your keypair goes here */;
const fromPubkey = fromKeypair.publicKey;
const toPubkey = /* The person we're sending 0.5 SOL to */;

const instructions: TransactionInstruction[] = [
  SystemProgram.transfer({
    fromPubkey: fromPubkey,
    toPubkey: toPubkey,
    lamports: 0.5 * LAMPORTS_PER_SOL, 
  }),
];

const transactionSignature = await helius.rpc.sendSmartTransaction(instructions, [fromKeypair]);
console.log(`Successful transfer: ${transactionSignature}`);
```

### SDK Rust

Metode `send_smart_transaction` tersedia dalam [SDK Rust](/docs/id/sdks/rust) kami untuk [versi >= 0.1.5](https://docs.rs/helius/latest/helius/). Untuk memperbarui ke versi SDK yang lebih baru, jalankan `cargo update helius`.

Contoh berikut mentransfer 0,01 SOL ke akun pilihan Anda.

Contoh ini menggunakan `send_smart_transaction` untuk mengirim transaksi yang telah dioptimalkan, melewati pemeriksaan preflight, dan mencoba ulang dua kali jika diperlukan:

```rust theme={"system"}
use helius::types::*;
use helius::Helius;
use solana_sdk::{
    pubkey::Pubkey,
    signature::Keypair,
    system_instruction
};

#[tokio::main]
async fn main() {
    let api_key: &str = "YOUR_API_KEY";
    let cluster: Cluster = Cluster::MainnetBeta;
    let helius: Helius = Helius::new(api_key, cluster).unwrap();
    
    let from_keypair: Keypair = /* Your keypair goes here */;
    let from_pubkey: Pubkey = from_keypair.pubkey();
    let to_pubkey: Pubkey = /* The person we're sending 0.01 SOL to */;

    // Create a simple instruction (transfer 0.01 SOL from from_pubkey to to_pubkey)
    let transfer_amount = 100_000; // 0.01 SOL in lamports
    let instruction = system_instruction::transfer(&from_pubkey, &to_pubkey, transfer_amount);

    // Create the SmartTransactionConfig
    let config = SmartTransactionConfig {
        instructions,
        signers: vec![&from_keypair],
        send_options: RpcSendTransactionConfig {
            skip_preflight: true,
            preflight_commitment: None,
            encoding: None,
            max_retries: Some(2),
            min_context_slot: None,
        },
        lookup_tables: None,
    };

    // Send the optimized transaction
    match helius.send_smart_transaction(config).await {
        Ok(signature) => {
            println!("Transaction sent successfully: {}", signature);
        }
        Err(e) => {
            eprintln!("Failed to send transaction: {:?}", e);
        }
    }
}
```

## Mengirim Transaksi Tanpa SDK

Kami merekomendasikan pengiriman transaksi cerdas dengan salah satu SDK kami, tetapi fungsionalitas yang sama dapat dicapai tanpa menggunakannya.

SDK TypeScript dan SDK Rust bersifat sumber terbuka, sehingga kode dasar untuk fungsionalitas pengiriman transaksi cerdas dapat dilihat kapan saja.

### Menyiapkan dan Membuat Transaksi Awal

Pertama, siapkan dan buat transaksi awal. Langkah ini mencakup pembuatan transaksi baru dengan serangkaian instruksi, penambahan blockhash terbaru, dan penetapan pembayar biaya.

Untuk transaksi berversi, buat `TransactionMessage` dan kompilasikan dengan tabel pencarian jika tersedia.

Kemudian, buat transaksi berversi baru dan tanda tangani—hal ini diperlukan untuk langkah berikutnya saat kami menyimulasikan transaksi karena transaksi tersebut harus ditandatangani.

Misalnya, jika kita ingin menyiapkan transaksi berversi:

```typescript theme={"system"}
// Prepare your instructions and set them to an instructions variable
// The payerKey is the public key that will be paying for this transaction
// Prepare your lookup tables and set them to a lookupTables variable
let recentBlockhash = (await this.connection.getLatestBlockhash()).blockhash;
const v0Message = new TransactionMessage({
    instructions: instructions,
    payerKey: pubKey,
    recentBlockhash: recentBlockhash,
}).compileToV0Message(lookupTables);
versionedTransaction = new VersionedTransaction(v0Message);
versionedTransaction.sign([fromKeypair]);
```

### Mengoptimalkan Penggunaan Unit Komputasi (CU) Transaksi

Untuk [mengoptimalkan penggunaan unit komputasi (CU) transaksi](https://www.helius.dev/blog/optimizing-solana-programs), kita dapat menggunakan metode RPC `simulateTransaction` untuk menyimulasikan transaksi.

[Penyimulasian transaksi](/docs/id/api-reference/rpc/http/simulatetransaction) akan mengembalikan jumlah CU yang digunakan, sehingga kita dapat menggunakan nilai ini untuk menetapkan batas komputasi yang sesuai.

Sebaiknya gunakan terlebih dahulu transaksi pengujian dengan instruksi yang diinginkan, ditambah instruksi yang menetapkan batas komputasi ke 1,4 juta CU.

Hal ini dilakukan untuk memastikan simulasi transaksi berhasil.

Contoh:

```typescript theme={"system"}
const testInstructions = [
    ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 }),
    ...instructions,
];

const testTransaction = new VersionedTransaction(
    new TransactionMessage({
        instructions: testInstructions,
        payerKey: payer,
        recentBlockhash: (await this.connection.getLatestBlockhash()).blockhash,
    }).compileToV0Message(lookupTables)
);

const rpcResponse = await this.connection.simulateTransaction(testTransaction, {
    replaceRecentBlockhash: true,
    sigVerify: false,
});

const unitsConsumed = rpcResponse.value.unitsConsumed;
```

Sebaiknya tambahkan sedikit margin untuk memastikan transaksi dijalankan tanpa masalah. Kita dapat melakukannya dengan menetapkan hal berikut:

```typescript theme={"system"}
let customersCU = Math.ceil(unitsConsumed * 1.1);
```

Kemudian, buat instruksi yang menetapkan batas unit komputasi ke nilai ini dan tambahkan ke array instruksi Anda:

```typescript theme={"system"}
const computeUnitIx = ComputeBudgetProgram.setComputeUnitLimit({
    units: customersCU
});
instructions.push(computeUnitIx);
```

### Menserialisasi dan Mengodekan Transaksi

Langkah ini relatif mudah.

Pertama, untuk menserialisasi transaksi, tipe Transaction dan VersionedTransaction memiliki metode `.serialize()`. Kemudian, gunakan [paket bs58](https://www.npmjs.com/package/bs58) untuk mengodekan transaksi.

Kode Anda akan terlihat kurang lebih seperti `bs58.encode(txt.serialize());`

### Menetapkan Biaya Prioritas yang Tepat

Pertama, gunakan [Priority Fee API](/docs/id/priority-fee-api) untuk mendapatkan estimasi biaya prioritas. Kita perlu memasukkan transaksi dan mendapatkan biaya yang direkomendasikan Helius melalui parameter recommended:

```typescript theme={"system"}
const response = await fetch(HeliusURL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [
            {
                transaction: bs58.encode(versionedTransaction), // Pass the serialized transaction in
                options: { recommended: true },
            },
        ],   
    }),
});

const data = await response.json();
const priorityFeeRecommendation = data.result.priorityFeeEstimate;
```

Kemudian, buat instruksi yang menetapkan harga unit komputasi ke nilai ini dan tambahkan instruksi tersebut ke instruksi sebelumnya:

```typescript theme={"system"}
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFeeRecommendation,
});

instructions.push(computeBudgetIx);
```

### Membuat dan Mengirim Transaksi yang Telah Dioptimalkan

Langkah ini hampir mengulangi langkah pertama. Namun, array instruksi awal telah diubah dengan menambahkan dua instruksi untuk menetapkan batas dan harga unit komputasi secara optimal.

Sekarang, kirim transaksi tersebut.

Tidak masalah apakah Anda mengirim dengan atau tanpa pemeriksaan preflight maupun mengubah opsi pengiriman lainnya—transaksi akan dirutekan melalui koneksi ber-stake kami untuk semua paket berbayar.

### Memeriksa Status Transaksi dan Menyiarkan Ulang

<Warning>
  Meskipun koneksi ber-stake akan meneruskan transaksi langsung kepada pemimpin, transaksi masih mungkin dibuang pada [Tahap Perbankan](https://www.helius.dev/blog/solana-virtual-machine#the-banking-stage). Sebaiknya pengguna menerapkan logika penyiaran ulang sendiri daripada mengandalkan RPC untuk mencoba ulang transaksi.
</Warning>

[Metode RPC `sendTransaction`](/docs/id/api-reference/rpc/http/sendtransaction) memiliki parameter `maxRetries` yang dapat ditetapkan untuk menggantikan logika percobaan ulang bawaan RPC, sehingga pengembang memiliki kontrol lebih besar atas proses percobaan ulang.

Pola yang umum digunakan adalah mengambil blockhash saat ini melalui [`getLatestBlockhash`](/docs/id/rpc/guides/getlatestblockhash), menyimpan `lastValidBlockHeight`, dan mencoba ulang transaksi hingga blockhash kedaluwarsa.

Anda harus menandatangani ulang transaksi hanya ketika blockhash sudah tidak valid. Jika tidak, kedua transaksi mungkin diterima oleh jaringan.

Setelah transaksi dikirim, penting untuk memeriksa status konfirmasinya guna mengetahui apakah jaringan telah memproses dan mengonfirmasinya sebelum mencoba ulang. Gunakan [metode RPC `getSignatureStatuses`](/docs/id/rpc/guides/getsignaturestatuses) untuk memeriksa status konfirmasi daftar transaksi.

SDK @solana/web3.js juga memiliki metode `getSignatureStatuses` pada kelas `Connection` untuk mengambil status terkini dari beberapa tanda tangan.

### Cara sendSmartTransaction Menangani Pemeriksaan Status dan Penyiaran Ulang

Metode `sendSmartTransaction` memiliki periode batas waktu 60 detik. Karena blockhash berlaku selama 150 slot, dan dengan asumsi setiap slot berlangsung tepat 400 md, kita dapat memperkirakan bahwa blockhash transaksi tidak lagi valid setelah satu menit.

Metode ini mengirim transaksi dan memeriksa tanda tangannya menggunakan periode batas waktu tersebut:

```typescript theme={"system"}
try {
   // Create a smart transaction
   const transaction = await this.createSmartTransaction(instructions, signers, lookupTables, sendOptions);
  
   const timeout = 60000;
   const startTime = Date.now();
   let txtSig;
  
   while (Date.now() - startTime < timeout) {
     try {
       txtSig = await this.connection.sendRawTransaction(transaction.serialize(), {
         skipPreflight: sendOptions.skipPreflight,
         ...sendOptions,
       });
  
       return await this.pollTransactionConfirmation(txtSig);
     } catch (error) {
       continue;
     }
   }
} catch (error) {
   throw new Error(`Error sending smart transaction: ${error}`);
}
```

`txtSig` ditetapkan ke tanda tangan transaksi yang baru saja dikirim.

Metode tersebut kemudian menggunakan metode `pollTransactionConfirmation()` untuk memeriksa status konfirmasi transaksi. Metode ini memeriksa status transaksi setiap lima detik, maksimal tiga kali.

Jika transaksi tidak dikonfirmasi selama periode ini, galat akan dikembalikan:

```typescript theme={"system"}
async pollTransactionConfirmation(txtSig: TransactionSignature): Promise<TransactionSignature> {
    // 15 second timeout
    const timeout = 15000;
    // 5 second retry interval
    const interval = 5000;
    let elapsed = 0;

    return new Promise<TransactionSignature>((resolve, reject) => {
      const intervalId = setInterval(async () => {
        elapsed += interval;

        if (elapsed >= timeout) {
          clearInterval(intervalId);
          reject(new Error(`Transaction ${txtSig}'s confirmation timed out`));
        }

        const status = await this.connection.getSignatureStatuses([txtSig]);

        if (status?.value[0]?.confirmationStatus === "confirmed") {
          clearInterval(intervalId);
          resolve(txtSig);
        }
      }, interval);
   });
}
```
