> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitflare.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust SDK

> Robinhood Chain 的 Rust SDK：orbitflare-robinhood-sdk crate。

全程使用 [alloy](https://github.com/alloy-rs/alloy) 类型——`Address`、`U256`、`B256`、`Filter`、`TransactionRequest`，以及类型化的区块、交易、收据与日志——并配备 OrbitFlare 自有的传输层：端点故障转移、带退避的重试与自愈的 WebSocket 订阅。SDK 面向 [Robinhood Chain](/cn/robinhood-chain)（EVM 兼容 L2），默认连接 OrbitFlare 的生产端点。

## 安装

```bash theme={null}
cargo add orbitflare-robinhood-sdk
```

默认仅启用 RPC 客户端。按需启用其他特性：

```bash theme={null}
cargo add orbitflare-robinhood-sdk --features ws
cargo add orbitflare-robinhood-sdk --features all
```

## Alloy 类型

所有地址、哈希与数量均为 alloy 类型。常用类型在 crate 根部重新导出（`Address`、`U256`、`B256`、`Bytes`、`Filter`、`TransactionRequest`、`BlockNumberOrTag` 等），完整 crate 也可通过 `orbitflare_robinhood_sdk::primitives`（alloy-primitives）与 `orbitflare_robinhood_sdk::rpc_types`（alloy-rpc-types-eth）访问。

```rust theme={null}
use orbitflare_robinhood_sdk::primitives::{address, b256, utils::format_ether};
```

## RPC 客户端

以下示例启用全部选项：

```rust theme={null}
use orbitflare_robinhood_sdk::{BlockNumberOrTag, Result, RetryPolicy, RpcClientBuilder};
use std::time::Duration;

let client = RpcClientBuilder::new()
    .url("https://robinhood.rpc.orbitflare.com")
    .fallback_urls(&["https://robinhood-backup.rpc.orbitflare.com"])
    .api_key("ORBIT-XXXXXX-NNNNNN-NNNNNN")
    .block_tag(BlockNumberOrTag::Finalized)
    .retry(RetryPolicy {
        initial_delay: Duration::from_millis(100),
        max_delay: Duration::from_secs(30),
        multiplier: 2.0,
        max_attempts: 5,
    })
    .timeout(Duration::from_secs(30))
    .build()?;
```

所有选项都有合理默认值——构建器默认使用 OrbitFlare 生产端点，因此最简配置为：

```rust theme={null}
let client = RpcClientBuilder::new().build()?;
```

### 构建器方法

**`.url(url)`** — 主端点。解析顺序：构建器上的 `.url()`，然后是环境变量 `ORBITFLARE_ROBINHOOD_RPC_URL`，最后是默认值 `https://robinhood.rpc.orbitflare.com`（`rpc::DEFAULT_RPC_URL`）。

**`.urls(&[...])`** — 一次设置主端点与所有备用端点。第一个元素为主端点，其余为备用。

**`.fallback_url(url)` / `.fallback_urls(&[...])`** — 添加故障转移端点。主端点失败时，SDK 按顺序尝试备用端点。失败的端点会被隔离并进入指数冷却（10s、20s、40s，最大 60s），冷却结束后自动重试；健康端点始终优先。

**`.api_key(key)`** — 你的 OrbitFlare 许可证密钥。若未设置，SDK 从环境读取 `ORBITFLARE_LICENSE_KEY`。密钥在请求时附加到端点 URL。

**`.block_tag(tag)`** — 状态查询（`get_balance`、`call`、`get_code` 等）使用的默认区块标签。接受任何可转换为 `BlockNumberOrTag` 的值。默认为 `Latest`。

**`.retry(policy)`** — 控制瞬时错误（5xx、429、连接重置、JSON-RPC 错误码 -32005）的重试策略，采用指数退避，之后故障转移到下一个端点。带 `Retry-After` 头的 429 响应会被遵守。

**`.timeout(duration)`** — 单次 HTTP 请求超时。

### 可用 RPC 方法

| 方法                                                           | 返回值                                 |
| ------------------------------------------------------------ | ----------------------------------- |
| `get_block_number()`                                         | `u64`                               |
| `get_chain_id()`                                             | `u64`                               |
| `get_balance(Address)`                                       | `U256` wei                          |
| `get_transaction_count(Address)`                             | `u64` nonce                         |
| `get_gas_price()`                                            | `u128` wei                          |
| `max_priority_fee_per_gas()`                                 | `u128` wei                          |
| `get_block_by_number(impl Into<BlockNumberOrTag>, full_txs)` | `Option<Block>`                     |
| `get_transaction_by_hash(B256)`                              | `Option<Transaction>`               |
| `get_transaction_receipt(B256)`                              | `Option<TransactionReceipt>`        |
| `get_logs(&Filter)`                                          | `Vec<Log>`                          |
| `get_code(Address)`                                          | `Bytes`                             |
| `call(&TransactionRequest)`                                  | `Bytes`                             |
| `estimate_gas(&TransactionRequest)`                          | `u64`                               |
| `send_raw_transaction(&[u8])`                                | `B256` 交易哈希                         |
| `fee_history(blocks, newest, percentiles)`                   | `FeeHistory`                        |
| `request(method, params)`                                    | 按名称调用任意 RPC 方法（`serde_json::Value`） |
| `request_raw(body)`                                          | 原始 JSON-RPC 请求体字符串                  |

### 读取链上状态

```rust theme={null}
use orbitflare_robinhood_sdk::primitives::{address, utils::format_ether};

let block = client.get_block_number().await?;
let gas_price = client.get_gas_price().await?;

let wallet = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045");
let balance = client.get_balance(wallet).await?;
let nonce = client.get_transaction_count(wallet).await?;

println!("ETH: {}", format_ether(balance));
```

### 日志过滤器

`get_logs` 直接接受 alloy 的 `Filter`：

```rust theme={null}
use orbitflare_robinhood_sdk::primitives::{address, b256};
use orbitflare_robinhood_sdk::{BlockNumberOrTag, Filter};

let transfer_topic =
    b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");

let filter = Filter::new()
    .from_block(1_000_000u64)
    .to_block(BlockNumberOrTag::Latest)
    .address(address!("d0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC"))
    .event_signature(transfer_topic);

let logs = client.get_logs(&filter).await?;
```

### 合约调用与交易

`call` 与 `estimate_gas` 接受 alloy 的 `TransactionRequest`。要发送交易，先用 alloy（`alloy-signer`、`alloy-network`）构建并签名，再通过 SDK 广播：

```rust theme={null}
let hash = client.send_raw_transaction(&signed_tx_rlp).await?;
let receipt = client.get_transaction_receipt(hash).await?;
```

### 任意方法

`request` 按名称调用任意 RPC 方法——SDK 构建 JSON-RPC 信封，处理重试与故障转移，并返回 `result` 字段。这也覆盖了 Robinhood Chain 作为 Arbitrum Nitro 链提供的 `arb_*` 扩展方法。`request_raw` 发送原始 JSON-RPC 请求体字符串。

```rust theme={null}
use serde_json::json;

let syncing = client.request("eth_syncing", json!([])).await?;

let version = client
    .request_raw(r#"{"jsonrpc":"2.0","id":1,"method":"web3_clientVersion","params":[]}"#)
    .await?;
```

## WebSocket 客户端

启用 `ws` 特性。Robinhood Chain 大约每 100 毫秒出一个块，因此 `newHeads` 的触发频率远高于以太坊主网和大多数 L2。

```rust theme={null}
use orbitflare_robinhood_sdk::{Result, RetryPolicy, WsClientBuilder};
use std::time::Duration;

let client = WsClientBuilder::new()
    .url("wss://robinhood.rpc.orbitflare.com")
    .api_key("ORBIT-XXXXXX-NNNNNN-NNNNNN")
    .retry(RetryPolicy {
        initial_delay: Duration::from_millis(100),
        max_delay: Duration::from_secs(30),
        multiplier: 2.0,
        max_attempts: 0,
    })
    .ping_interval_secs(10)
    .max_missed_pongs(3)
    .build()
    .await?;
```

最简配置：

```rust theme={null}
let client = WsClientBuilder::new().build().await?;
```

注意 `.build()` 为异步——在返回前会建立 WebSocket 连接。构建器与 RPC 构建器共享 `.urls()`、`.fallback_url(s)()`、`.api_key()` 与 `.retry()`；WebSocket 特有的选项为：

**`.url(url)`** — 主 WebSocket 端点。解析顺序：`.url()`，然后是 `ORBITFLARE_ROBINHOOD_WS_URL`，最后是默认值 `wss://robinhood.rpc.orbitflare.com`（`ws::DEFAULT_WS_URL`）。

**`.ping_interval_secs(n)`** — SDK 发送 WebSocket `Ping` 帧以检测失效连接的频率。默认：10。

**`.max_missed_pongs(n)`** — 多少次 Ping 无应答后判定连接失效并重连。默认：3。

### 订阅

订阅是类型化的——每个订阅产出对应的 alloy 类型，而非原始 JSON：

| 方法                                     | 产出               |
| -------------------------------------- | ---------------- |
| `new_heads_subscribe()`                | 每个新区块一条 `Header` |
| `logs_subscribe(&Filter)`              | 匹配过滤器的 `Log`     |
| `new_pending_transactions_subscribe()` | `B256` 交易哈希      |

```rust theme={null}
use orbitflare_robinhood_sdk::primitives::b256;
use orbitflare_robinhood_sdk::Filter;

let mut heads = client.new_heads_subscribe().await?;

let transfer_topic =
    b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
let mut transfers = client
    .logs_subscribe(&Filter::new().event_signature(transfer_topic))
    .await?;
```

所有订阅返回 `WsSubscription<T>`。调用 `.next()` 获取下一条类型化事件（`None` 表示订阅已关闭），或调用 `.next_raw()` 获取未类型化的 `serde_json::Value` 负载。

```rust theme={null}
while let Some(head) = heads.next().await {
    println!("block {} (gas used {})", head.number, head.gas_used);
}
```

所有订阅共用单一 WebSocket 连接，且可随时添加新订阅。`sub.unsubscribe().await` 显式移除订阅；直接丢弃订阅而不调用也可以——SDK 会检测孤立订阅并自动发送取消订阅消息。

### 重连

若连接断开，后台任务会以指数退避重连，并自动重新订阅所有活跃订阅。你的 `.next()` 调用会持续工作——连接恢复后事件会继续到达。失效连接通过主动 ping/pong 检测，可用 `.ping_interval_secs()` 与 `.max_missed_pongs()` 配置。

## 环境变量

| 变量                             | 使用者           | 用途                   |
| ------------------------------ | ------------- | -------------------- |
| `ORBITFLARE_LICENSE_KEY`       | RPC、WebSocket | 附加到端点 URL 的 API 密钥   |
| `ORBITFLARE_ROBINHOOD_RPC_URL` | RPC           | 未调用 `.url()` 时覆盖默认端点 |
| `ORBITFLARE_ROBINHOOD_WS_URL`  | WebSocket     | 未调用 `.url()` 时覆盖默认端点 |

## 完整示例

监控脚本：先读取钱包状态，再实时跟踪新区块与 ERC-20 转账：

```rust theme={null}
use orbitflare_robinhood_sdk::primitives::{address, b256, utils::format_ether};
use orbitflare_robinhood_sdk::{Filter, Result, RpcClientBuilder, WsClientBuilder};

#[tokio::main]
async fn main() -> Result<()> {
    let rpc = RpcClientBuilder::new().build()?;

    let wallet = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045");
    let balance = rpc.get_balance(wallet).await?;
    let block = rpc.get_block_number().await?;
    println!("block {block}, wallet holds {} ETH", format_ether(balance));

    let ws = WsClientBuilder::new().build().await?;

    let mut heads = ws.new_heads_subscribe().await?;

    let transfer_topic = b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
    let mut transfers = ws
        .logs_subscribe(&Filter::new().event_signature(transfer_topic))
        .await?;

    println!("watching new heads and ERC-20 transfers...");

    loop {
        tokio::select! {
            Some(head) = heads.next() => {
                println!("block {} (gas used {})", head.number, head.gas_used);
            }
            Some(log) = transfers.next() => {
                let tx = log.transaction_hash.unwrap_or_default();
                println!("transfer on {} in {tx}", log.address());
            }
        }
    }
}
```

## 源码

SDK 为开源：[github.com/orbitflare/orbitflare-robinhood-sdk-rs](https://github.com/orbitflare/orbitflare-robinhood-sdk-rs)
