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

# Rust

> Connect to Anthid's Streaming API using Rust and Tonic.

Anthid provides Protocol Buffer definitions that can be used to generate Rust clients with Tonic.

This guide demonstrates connecting to the Streaming API and receiving real-time broker order and position updates.

## Prerequisites

Add the required dependencies.

```toml theme={null}
[dependencies]
tokio = { version = "1", features = ["full"] }
tonic = { version = "0.14", features = ["tls-webpki-roots"] }
prost = "0.14"
```

## Generate Rust Types

Generate Rust code from the Anthid protobuf definitions.

```bash theme={null}
git clone https://github.com/anthid-labs/proto.git
```

Example `build.rs`:

```rust theme={null}
fn main() {
    tonic_prost_build::compile_protos(
        "proto/trading.proto",
    )
    .unwrap();
}
```

Example `Cargo.toml` build dependency:

```toml theme={null}
[build-dependencies]
tonic-prost-build = "0.14"
```

## Authentication

Anthid authenticates streaming requests using the `x-api-key` metadata header.

```rust theme={null}
use tonic::metadata::MetadataValue;

request.metadata_mut().insert(
    "x-api-key",
    MetadataValue::try_from("YOUR_API_KEY")?,
);
```

## Subscribe to Events

The `SubscribeEvents` endpoint provides a server-streaming interface suitable for most applications.

```rust theme={null}
use tonic::{
    metadata::MetadataValue,
    transport::Channel,
    Request,
};

pub mod trading {
    tonic::include_proto!("trading");
}

use trading::{
    trading_service_client::TradingServiceClient,
    EventType,
    Subscribe,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>>
{
    let mut client =
        TradingServiceClient::connect(
            "https://stream.anthid.com",
        )
        .await?;

    let mut request = Request::new(
        Subscribe {
            trading_account_id:
                "YOUR_TRADING_ACCOUNT_ID"
                    .to_string(),
            subscriptions: vec![
                EventType::BrokerOrder as i32,
                EventType::BrokerPosition
                    as i32,
            ],
        },
    );

    request.metadata_mut().insert(
        "x-api-key",
        MetadataValue::try_from(
            "YOUR_API_KEY",
        )?,
    );

    let mut stream = client
        .subscribe_events(request)
        .await?
        .into_inner();

    while let Some(event) =
        stream.message().await?
    {
        println!("{event:?}");
    }

    Ok(())
}
```

## Handling Events

Each `TradingEvent` contains a single event variant.

```rust theme={null}
while let Some(event) =
    stream.message().await?
{
    match event.event {
        Some(
            trading::trading_event::Event::Heartbeat(_),
        ) => {
            println!("heartbeat");
        }

        Some(
            trading::trading_event::Event::Status(
                status,
            ),
        ) => {
            println!(
                "status: {}",
                status.message
            );
        }

        Some(
            trading::trading_event::Event::Error(
                error,
            ),
        ) => {
            println!(
                "error: {}",
                error.message
            );
        }

        Some(
            trading::trading_event::Event::BrokerOrder(
                order,
            ),
        ) => {
            println!(
                "order: {:?}",
                order
            );
        }

        Some(
            trading::trading_event::Event::BrokerPosition(
                position,
            ),
        ) => {
            println!(
                "position: {:?}",
                position
            );
        }

        None => {}
    }
}
```

## Bidirectional Streaming

Backend and native applications may use `StreamEvents` when subscriptions need to be modified over an existing connection.

```rust theme={null}
use tokio_stream::iter;
use tonic::Request;

use trading::{
    EventType,
    StreamEventsRequest,
    Subscribe,
};

let request_stream = iter(vec![
    StreamEventsRequest {
        msg: Some(
            trading::stream_events_request::Msg::Subscribe(
                Subscribe {
                    trading_account_id:
                        "YOUR_TRADING_ACCOUNT_ID"
                            .to_string(),
                    subscriptions: vec![
                        EventType::BrokerOrder
                            as i32,
                        EventType::BrokerPosition
                            as i32,
                    ],
                },
            ),
        ),
    },
]);

let mut request =
    Request::new(request_stream);

request.metadata_mut().insert(
    "x-api-key",
    MetadataValue::try_from(
        "YOUR_API_KEY",
    )?,
);

let response = client
    .stream_events(request)
    .await?;

let mut stream =
    response.into_inner();
```

## Handling Disconnects

Applications should automatically reconnect when a stream closes unexpectedly.

After reconnecting:

1. Create a new stream.
2. Authenticate using the API key.
3. Re-subscribe to required trading accounts.
4. Resume event processing.

## Related Resources

* Streaming Overview
* Python Guide
* Trading Accounts
* Orders
* Positions
* Ledger
* Intents
