跳转到主要内容
有关使用 Helius Rust SDK 的代理的最佳实践和推荐模式。有关安装和入门,请参见概述

代理的建议

使用 get_transactions_for_address 替代两步查找

get_transactions_for_address 将签名查找和交易获取结合为一次调用,并进行服务器端过滤。
// 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 会自动添加它们。
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 路由。
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
// 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?;
}

使用 webhooks 替代轮询

不要在循环中轮询 get_transactions_for_address。使用 webhooks 进行服务器到服务器的通知。
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 方法)

// 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)

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_accountsget_token_accounts_by_owner
// 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. 优先费用以每计算单元的微 lamports 计 — 不是 lamports。来自 get_priority_fee_estimate 的值已经在正确的单位中。
  4. DAS 分页从 1 开始page: 1 是第一页,不是 page: 0
  5. async_connection() 需要 new_asyncHeliusBuilder — 在通过 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 特性标志 —— crate 默认使用 native-tls。当 OpenSSL 不可用时,使用 features = ["rustls"](和 default-features = false)进行纯 Rust TLS。

错误处理和重试

SDK 通过 HeliusError 枚举提供类型化错误变体,因此您可以直接匹配它们:
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. */ }
}

重试策略

RateLimitExceededInternalError 上重试,采用指数退避:
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 状态操作
Unauthorized401检查 API 密钥
RateLimitExceeded429后退并重试
InternalError5xx使用指数退避重试
BadRequest400修正请求参数
NotFound404检查资源是否存在
Timeout增加超时或重试