# comdirect-rest-api
> [!WARNING]
> This project is in its **early stages** of development. Currently, it only supports listing depots and uses **Push-TAN** for authentication.
A Rust library for interacting with the Comdirect REST API. This crate handles the complex OAuth2 handshake, session management, and Push-TAN validation required by Comdirect.
While currently focused on a subset of functionality, the architecture is designed to be easily extensible. I plan to add support for more API endpoints (orders, account balances, etc.) and potentially additional TAN methods in the future.
## Features
- **OAuth2 Session Management**: Automatic token refresh in the background.
- **Push-TAN Support**: Built-in flow for handling Comdirect's 2FA.
- **Async First**: Built on top of `tokio` and `reqwest`.
- **Easy Extension**: Modular API structure that makes adding new endpoints straightforward.
## Getting Started
### Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
comdirect-rest-api = { git = "https://codeberg.org/flower1024/comdirect-rest-api.git" }
```
### Usage Example
```rust
use comdirect_rest_api::oauth2::{ComdirectConfig, Session};
use comdirect_rest_api::api::brokerage::v3::depots;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ComdirectConfig {
user: "1234567".to_string(),
password: "your_password".to_string(),
client_id: "your_client_id".to_string(),
client_secret: "your_client_secret".to_string(),
on_refresh_token: Some(Arc::new(|token| {
// Save token for later sessions
})),
on_awaits_user_confirm: Arc::new(|| Box::pin(async {
println!("Please confirm the Push-TAN on your device and press ENTER...");
let mut line = String::new();
let _ = tokio::io::stdin().read_line(&mut line).await;
})),
};
// Initialize session (last_token is Option<String>. It will fail if the token is to old)
let session = Session::new(&config, last_token).await?;
// Now you can use the session to call API methods
let positions = depots::positions(&session, &settings.comdirect_depot_id)
.await
.map_err(|e| anyhow::anyhow!("Failed to fetch positions: {}", e))?;
Ok(())
}
```
## Contributing
Contributions are welcome! If you'd like to help expand the API coverage or improve the documentation, feel free to open a PR.
## License
This project is licensed under the MIT License.