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

# Rust SDK ベストプラクティス

> Helius Rust SDKを使用したAIエージェント向けの推奨パターン。取引履歴、取引の送信、バッチ処理、Webhook、ページネーション、インクリメンタルフェッチ、一般的なミスとエラーハンドリングを網羅しています。

[Helius Rust SDK](https://github.com/helius-labs/helius-rust-sdk)を使用するエージェント向けのベストプラクティスと推奨パターンです。インストールと開始方法については[概要](/ja/agents/rust-sdk)を参照してください。

## エージェント向けの推奨事項

### 二段階ルックアップの代わりに`get_transactions_for_address`を使用する

`get_transactions_for_address`は、署名のルックアップと取引の取得を一度の呼び出しで行い、サーバー側でフィルタリングします。

```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)?;
```

### 標準送信には`send_smart_transaction`を使用する

自動シミュレーション、コンピュートユニットの推定、優先料金の取得、確認を自動的に行います。`ComputeBudget`命令を手動で作成しないでください — SDKが自動的に追加します。

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

### 超低遅延にはHelius Senderを使用する

時間が重要な取引（アービトラージ、スナイピング、清算）には、`send_smart_transaction_with_sender`を使用します。Heliusの多地域インフラストラクチャと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?;
```

### 複数資産には`get_asset_batch`を使用する

複数の資産を取得する場合は、バッチ処理を行います。`get_asset`をループで呼び出さないでください。

```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?;
}
```

### ポーリングの代わりにWebhookを使用する

`get_transactions_for_address`をループでポーリングしないでください。サーバー間の通知にはWebhookを使用してください。

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

## ページネーション

### トークン/カーソルベース（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?;
```

### ページベース（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;
}
```

## `token_accounts`フィルタ

`get_transactions_for_address`をクエリするとき、トークンアカウントの活動が含まれるかどうかを`token_accounts`フィルタで制御します:

| 値                | 振る舞い              | 使用時                                      |
| ---------------- | ----------------- | ---------------------------------------- |
| `None`           | アドレスに直接関係する取引のみ   | SOL転送やプログラム呼び出しのみを気にする場合                 |
| `BalanceChanged` | 残高を変更したトークン取引も含む  | **ほとんどのエージェントに推奨** — トークンの送信/受信をノイズなしで表示 |
| `All`            | 全てのトークンアカウント取引を含む | 完全なトークン活動が必要な場合（多くの結果が戻る可能性があります)        |

## `changed_since_slot` — インクリメンタルアカウントフェッチング

`changed_since_slot`は指定されたスロット以降に変更されたアカウントのみを返します。同期やインデックス作業フローに便利です。`get_program_accounts_v2`, `get_token_accounts_by_owner_v2`, `get_account_info`, `get_multiple_accounts`, `get_program_accounts`, `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?;
```

## 一般的なミス

1. **デフォルトでは`transaction_details: Some(TransactionDetails::Full)`ではありません** — デフォルトでは、`get_transactions_for_address`は署名のみを返します。完全な取引データを取得するには`TransactionDetails::Full`を設定します。

2. **`send_smart_transaction`でComputeBudget命令を追加しない** — SDKが自動的に追加します。独自に追加すると`HeliusError::InvalidInput`エラーが発生します。

3. **優先料金はコンピュートユニットごとのマイクロランポーツです** — ランポーツではありません。`get_priority_fee_estimate`からの値はすでに正しい単位になっています。

4. **DASページネーションは1インデックスです** — `page: 1`は最初のページであり、`page: 0`ではありません。

5. **`async_connection()`は`new_async`または`HeliusBuilder`を必要とします** — `Helius::new()`で作成されたクライアントで`helius.async_connection()`を呼び出すと`Err(HeliusError::ClientNotInitialized)`が返ります。

6. **`get_asset`は`Option<Asset>`を返すことがあります** — 資産が存在しない場合、成功した応答でも`None`になることがあります。`Option`を明示的に処理してください。

7. **送信者のチップは必須です** — `send_smart_transaction_with_sender`は自動的にチップを決定し追加します。最小0.0002 SOL（デュアルモード）または0.000005 SOL（SWQOS専用）。

8. **TLS機能フラグ** — クレートはデフォルトで`native-tls`です。OpenSSLが利用できない場合、純粋なRust TLSには`features = ["rustls"]`（および`default-features = false`）を使用してください。

## エラーハンドリングと再試行

SDKは`HeliusError`列挙型を通じて型付きエラー変異を提供するので、直接マッチできます。

```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. */ }
}
```

### 再試行戦略

`RateLimitExceeded`と`InternalError`で指数バックオフ再試行を行います:

```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!()
}
```

| エラー変異型              | HTTPステータス | アクション          |
| ------------------- | --------- | -------------- |
| `Unauthorized`      | 401       | APIキーを確認       |
| `RateLimitExceeded` | 429       | バックオフして再試行     |
| `InternalError`     | 5xx       | 指数バックオフで再試行    |
| `BadRequest`        | 400       | リクエストパラメータを修正  |
| `NotFound`          | 404       | リソースが存在するか確認   |
| `Timeout`           | —         | タイムアウトを増やすか再試行 |
