> ## 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ác phương pháp hay nhất cho Rust SDK

> Các mẫu Solana được đề xuất cho tác nhân AI sử dụng Helius Rust SDK — lịch sử giao dịch, gửi, xử lý theo lô, webhook, phân trang và xử lý lỗi.

Các phương pháp hay nhất và mẫu được đề xuất cho tác nhân sử dụng [Helius Rust SDK](https://github.com/helius-labs/helius-rust-sdk). Để cài đặt và bắt đầu, hãy xem phần [tổng quan](/docs/vi/agents/rust-sdk).

## Đề xuất cho tác nhân

### Sử dụng `get_transactions_for_address` thay vì tra cứu hai bước

`get_transactions_for_address` kết hợp việc tra cứu chữ ký và truy xuất giao dịch trong một lệnh gọi duy nhất, đồng thời lọc ở phía máy chủ.

```rust theme={"system"}
// GOOD: Single call, server-side filtering
let txs = helius.rpc().get_transactions_for_address(
    "address".to_string(),
    GetTransactionsForAddressOptions {
        transaction_details: Some(TransactionDetails::Full),
        limit: Some(100),
        filters: Some(GetTransactionsFilters {
            token_accounts: Some(TokenAccountsFilter::BalanceChanged),
            ..Default::default()
        }),
        ..Default::default()
    },
).await?;

// BAD: Two calls, client-side filtering
let sigs = helius.connection().get_signatures_for_address(&address)?;
```

### Sử dụng `send_smart_transaction` cho các thao tác gửi tiêu chuẩn

Phương thức này tự động mô phỏng, ước tính đơn vị tính toán, truy xuất phí ưu tiên và xác nhận. Không tự tạo các chỉ thị `ComputeBudget` — SDK sẽ tự động thêm chúng.

```rust theme={"system"}
let sig = helius.send_smart_transaction(SmartTransactionConfig {
    create_config: CreateSmartTransactionConfig {
        instructions: vec![your_instruction],
        signers: vec![wallet_signer],
        priority_fee_cap: Some(100_000),
        cu_buffer_multiplier: Some(1.1),
        ..Default::default()
    },
    ..Default::default()
}).await?;
```

### Sử dụng Helius Sender để đạt độ trễ cực thấp

Đối với các giao dịch nhạy cảm về thời gian (kinh doanh chênh lệch giá, săn lệnh, thanh lý), hãy sử dụng `send_smart_transaction_with_sender`. Phương thức này định tuyến qua cơ sở hạ tầng đa khu vực của Helius và Jito.

```rust theme={"system"}
let sig = helius.send_smart_transaction_with_sender(
    SmartTransactionConfig {
        create_config: CreateSmartTransactionConfig {
            instructions: vec![your_instruction],
            signers: vec![wallet_signer],
            ..Default::default()
        },
        ..Default::default()
    },
    SenderSendOptions {
        region: "US_EAST".to_string(),    // Default, US_SLC, US_EAST, EU_WEST, EU_CENTRAL, EU_NORTH, AP_SINGAPORE, AP_TOKYO
        swqos_only: false,                // true = SWQOS only (lower tip), false = Dual (SWQOS + Jito)
        poll_timeout_ms: 60_000,
        poll_interval_ms: 2_000,
    },
).await?;
```

### Sử dụng `get_asset_batch` cho nhiều tài sản

Khi truy xuất nhiều tài sản, hãy xử lý chúng theo lô. Không gọi `get_asset` trong vòng lặp.

```rust theme={"system"}
// GOOD: Single request
let assets = helius.rpc().get_asset_batch(GetAssetBatch {
    ids: vec!["mint1".to_string(), "mint2".to_string(), "mint3".to_string()],
    ..Default::default()
}).await?;

// BAD: N requests
for id in mints {
    let asset = helius.rpc().get_asset(GetAsset { id, ..Default::default() }).await?;
}
```

### Sử dụng webhook thay vì thăm dò

Không thăm dò `get_transactions_for_address` trong vòng lặp. Hãy sử dụng webhook cho các thông báo giữa máy chủ với máy chủ.

```rust theme={"system"}
let webhook = helius.create_webhook(CreateWebhookRequest {
    webhook_url: "https://your-server.com/webhook".to_string(),
    webhook_type: WebhookType::Enhanced,
    transaction_types: vec![TransactionType::Transfer, TransactionType::NftSale, TransactionType::Swap],
    account_addresses: vec!["address_to_monitor".to_string()],
    auth_header: Some("Bearer your-secret".to_string()),
    ..Default::default()
}).await?;
```

## Phân trang

### Dựa trên token/con trỏ (các phương thức RPC V2)

```rust theme={"system"}
// get_transactions_for_address uses pagination_token
let mut pagination_token: Option<String> = None;
let mut all_txs = Vec::new();
loop {
    let result = helius.rpc().get_transactions_for_address(
        "address".to_string(),
        GetTransactionsForAddressOptions {
            limit: Some(100),
            pagination_token: pagination_token.clone(),
            ..Default::default()
        },
    ).await?;
    all_txs.extend(result.data);
    pagination_token = result.pagination_token;
    if pagination_token.is_none() { break; }
}

// Or use auto-paginating variants:
let all_accounts = helius.rpc().get_all_program_accounts(
    program_id.to_string(),
    GetProgramAccountsV2Config::default(),
).await?;
```

### Dựa trên trang (DAS API)

```rust theme={"system"}
let mut page = 1;
let mut all_assets = Vec::new();
loop {
    let result = helius.rpc().get_assets_by_owner(GetAssetsByOwner {
        owner_address: "...".to_string(),
        page,
        limit: Some(1000),
        ..Default::default()
    }).await?;
    let count = result.items.len();
    all_assets.extend(result.items);
    if count < 1000 { break; }
    page += 1;
}
```

## Bộ lọc `token_accounts`

Khi truy vấn `get_transactions_for_address`, bộ lọc `token_accounts` kiểm soát việc có bao gồm hoạt động của tài khoản token hay không:

| Giá trị          | Hành vi                                             | Sử dụng khi                                                                                        |
| ---------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `None`           | Chỉ các giao dịch liên quan trực tiếp đến địa chỉ   | Bạn chỉ quan tâm đến việc chuyển SOL và các lệnh gọi chương trình                                  |
| `BalanceChanged` | Cũng bao gồm các giao dịch token làm thay đổi số dư | **Được đề xuất cho hầu hết tác nhân** — hiển thị các lượt gửi/nhận token mà không có dữ liệu nhiễu |
| `All`            | Bao gồm tất cả giao dịch của tài khoản token        | Bạn cần toàn bộ hoạt động token (có thể trả về nhiều kết quả)                                      |

## `changed_since_slot` — Truy xuất tài khoản tăng dần

`changed_since_slot` chỉ trả về các tài khoản được sửa đổi sau một slot nhất định. Hữu ích cho quy trình đồng bộ hóa hoặc lập chỉ mục. Được hỗ trợ bởi `get_program_accounts_v2`, `get_token_accounts_by_owner_v2`, `get_account_info`, `get_multiple_accounts`, `get_program_accounts` và `get_token_accounts_by_owner`.

```rust theme={"system"}
// First fetch: get all accounts
let baseline = helius.rpc().get_program_accounts_v2(
    program_id.to_string(),
    GetProgramAccountsV2Config { limit: Some(10_000), ..Default::default() },
).await?;
let last_slot = current_slot;

// Later: only get accounts that changed since your last fetch
let updates = helius.rpc().get_program_accounts_v2(
    program_id.to_string(),
    GetProgramAccountsV2Config {
        limit: Some(10_000),
        changed_since_slot: Some(last_slot),
        ..Default::default()
    },
).await?;
```

## Các lỗi thường gặp

1. **`transaction_details: Some(TransactionDetails::Full)` không phải là giá trị mặc định** — Theo mặc định, `get_transactions_for_address` chỉ trả về chữ ký. Đặt `TransactionDetails::Full` để nhận đầy đủ dữ liệu giao dịch.

2. **Không thêm các chỉ thị ComputeBudget khi sử dụng `send_smart_transaction`** — SDK tự động thêm chúng. Việc tự thêm sẽ gây ra lỗi `HeliusError::InvalidInput`.

3. **Phí ưu tiên được tính bằng microlamport trên mỗi đơn vị tính toán** — Không phải lamport. Các giá trị từ `get_priority_fee_estimate` đã sử dụng đúng đơn vị.

4. **Phân trang DAS được đánh số từ 1** — `page: 1` là trang đầu tiên, không phải `page: 0`.

5. **`async_connection()` yêu cầu `new_async` hoặc `HeliusBuilder`** — Việc gọi `helius.async_connection()` trên một máy khách được tạo bằng `Helius::new()` sẽ trả về `Err(HeliusError::ClientNotInitialized)`.

6. **`get_asset` trả về `Option<Asset>`** — Một phản hồi thành công vẫn có thể là `None` nếu tài sản không tồn tại. Hãy xử lý `Option` một cách tường minh.

7. **Tiền boa cho Sender là bắt buộc** — `send_smart_transaction_with_sender` tự động xác định và thêm tiền boa. Tối thiểu 0.0002 SOL (chế độ Dual) hoặc 0.000005 SOL (chỉ SWQOS).

8. **Cờ tính năng TLS** — Crate mặc định sử dụng `native-tls`. Sử dụng `features = ["rustls"]` (và `default-features = false`) để dùng TLS thuần Rust khi OpenSSL không khả dụng.

9. **Đặt phiên bản giao dịch tối đa được hỗ trợ thành 1 khi truy xuất giao dịch.** Nếu không, `get_transaction`, `get_block` và `get_transactions_for_address` với `TransactionDetails::Full` sẽ gặp lỗi `-32015` trên giao dịch v1. Trên giao dịch v1, phí ưu tiên là `transactionConfig.priorityFee` của thông điệp, tức tổng số tính bằng lamport; không có chỉ thị ComputeBudget nào để quét. Xem [Hỗ trợ giao dịch v1](/docs/vi/rpc/transaction-v1).

## Xử lý lỗi và thử lại

SDK cung cấp các biến thể lỗi có kiểu thông qua enum `HeliusError`, nhờ đó bạn có thể đối sánh trực tiếp với chúng:

```rust theme={"system"}
use helius::error::{HeliusError, Result};

match helius.rpc().get_asset(request).await {
    Ok(asset) => { /* success */ }
    Err(HeliusError::Unauthorized { .. }) => { /* 401: invalid or missing API key */ }
    Err(HeliusError::RateLimitExceeded { .. }) => { /* 429: too many requests or out of credits */ }
    Err(HeliusError::InternalError { .. }) => { /* 5xx: server error, retry with backoff */ }
    Err(HeliusError::NotFound { .. }) => { /* 404: resource not found */ }
    Err(HeliusError::BadRequest { .. }) => { /* 400: malformed request */ }
    Err(HeliusError::Timeout { .. }) => { /* transaction confirmation timed out */ }
    Err(e) => { /* other errors: Network, SerdeJson, etc. */ }
}
```

### Chiến lược thử lại

Thử lại khi gặp `RateLimitExceeded` và `InternalError` với thời gian chờ tăng theo cấp số nhân:

```rust theme={"system"}
async fn with_retry<T, F, Fut>(f: F, max_retries: u32) -> Result<T>
where
    F: Fn() -> Fut,
    Fut: std::future::Future<Output = Result<T>>,
{
    for attempt in 0..=max_retries {
        match f().await {
            Ok(val) => return Ok(val),
            Err(HeliusError::RateLimitExceeded { .. })
            | Err(HeliusError::InternalError { .. }) if attempt < max_retries => {
                tokio::time::sleep(std::time::Duration::from_millis(1000 * 2u64.pow(attempt))).await;
            }
            Err(e) => return Err(e),
        }
    }
    unreachable!()
}
```

| Biến thể lỗi        | Trạng thái HTTP | Hành động                                       |
| ------------------- | --------------- | ----------------------------------------------- |
| `Unauthorized`      | 401             | Kiểm tra khóa API                               |
| `RateLimitExceeded` | 429             | Tăng thời gian chờ rồi thử lại                  |
| `InternalError`     | 5xx             | Thử lại với thời gian chờ tăng theo cấp số nhân |
| `BadRequest`        | 400             | Sửa các tham số yêu cầu                         |
| `NotFound`          | 404             | Kiểm tra xem tài nguyên có tồn tại hay không    |
| `Timeout`           | —               | Tăng thời gian chờ hoặc thử lại                 |
