> For the complete documentation index, see [llms.txt](https://docs.termina.technology/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.termina.technology/documentation/developer-docs-zh/ji-shu-she-zhi-zhi-nan/rust-ke-hu-duan.md).

# Rust 客户端

`simulator-client` 和 `simulator-api` crate 为 Termina 模拟器提供原生 Rust 接口，适用于希望将回测直接集成到 Rust 代码中、而不使用 `sim` CLI 的团队。

* **`simulator-client`** 是高层异步客户端。它封装了 WebSocket 协议，为常见工作流程提供易用的构建器：创建会话、推进 slot、注入交易以及读取账户状态。
* **`simulator-api`** 定义了原始协议类型（请求/响应结构体、错误变体、会话参数）。如需直接访问底层传输格式，或希望实现自己的客户端，请使用它。

完整的端到端示例，请参阅入门代码[仓库](https://github.com/nitro-svm/examples)。

### 安装

```toml
[dependencies]
simulator-client = "0.15"
simulator-api = "0.15" # If you only need the protocol types (e.g. to build a custom client):
```

### 示例

#### 可用 slot

创建会话之前，请确认要回测的 slot 范围可用：

```rust
let ranges = client.available_ranges().await?;
for r in &ranges {
    println!(
        "slots {} – {}",
        r.bundle_start_slot,
        r.max_bundle_end_slot.unwrap_or(0)
    );
}
```

#### 程序覆盖

加载已编译的 ELF 二进制文件，并将其替换到会话中。

```rust
let elf = std::fs::read("your_program.so")?;

// Derives the correct ProgramData account shape via the session's RPC endpoint
let modifications = session
    .modify_program("YourProgramId111111111111111111111111111111", &elf)
    .await?;

// Apply the modifications on the next Continue
session
    .continue_until_ready(
        Continue::builder()
            .advance_count(1)
            .modify_accounts(modifications)
            .build(),
        None,
        |_| {},
    )
    .await?;
```

#### 读取与写入

使用会话的 RPC 客户端发送交易和读取账户。

```rust
use std::str::FromStr;
use solana_sdk::pubkey::Pubkey;

// Build your transaction using any Solana SDK tooling
let tx: solana_sdk::transaction::VersionedTransaction = /* ... */;

session
    .continue_until_ready(
        Continue::builder()
            .advance_count(1)
            .build()
            .push_transaction(&tx)?,
        Some(Duration::from_secs(30)),
        |_| {},
    )
    .await?;

let pubkey = Pubkey::from_str("SomePubkey11111111111111111111111111111111")?;
let account = session.rpc().get_account(&pubkey).await?;
println!("lamports: {}", account.lamports);
```

#### 订阅

```rust
use solana_commitment_config::CommitmentConfig;

let _handle = session
    .subscribe_program_logs(
        "YourProgramId111111111111111111111111111111",
        CommitmentConfig::confirmed(),
        |notification| async move {
            println!("logs: {:?}", notification.value.logs);
        },
    )
    .await?;
    
let _handle = session
    .subscribe_account_diffs(
        "SomePubkey11111111111111111111111111111111",
        |diff| async move {
            println!("account changed: {:?}", diff);
        },
    )
    .await?;

// Drop the handle to unsubscribe
```

#### 重新路由订单流

在创建会话时启用 `reroute_order_flow`，即可将所有 taker 订单流通过 Jupiter Metis 重新路由，并直接计算成交率的变化。

```rust
let mut session = client
    .create_session(
        CreateSession::builder()
            .start_slot(300_000_000)
            .slot_count(100)
            .reroute_order_flow(true)
            .build(),
    )
    .await?;
```
