Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ bothan-coinmarketcap = { path = "bothan-coinmarketcap", version = "0.0.1" }
bothan-htx = { path = "bothan-htx", version = "0.0.1" }
bothan-kraken = { path = "bothan-kraken", version = "0.0.1" }
bothan-okx = { path = "bothan-okx", version = "0.0.1" }
bothan-band = { path = "bothan-band", version = "0.0.1" }

anyhow = "1.0.86"
async-trait = "0.1.77"
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,32 @@ This project comprises primarily of 6 main components:
docker-compose up
```

## Generating Protobuf Files

Bothan uses [Buf](https://buf.build/) for protobuf file generation and linting.

1. **Generate all proto files for Go client, Rust client, and server:**

Run the following command from the root of the project:

```bash
buf generate
```

This command will generate protobuf files for all supported languages (Go, Rust, server stubs, etc.) as specified in the `buf.gen.yaml` configuration.

2. **Generate the descriptor file for the server:**

To create a protobuf descriptor file needed by the server, run:

```bash
buf build -o bothan-api/server/src/proto/descriptor.pb
```

This will output the descriptor file to `bothan-api/server/src/proto/descriptor.pb`.

For more information on modifying or generating protobuf files, refer to [Buf documentation](https://docs.buf.build/).

## Support

If you encounter any issues or have questions related to Bothan, we encourage you to open a GitHub issue. This ensures a
Expand Down
12 changes: 12 additions & 0 deletions bothan-api/server-cli/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ url = "wss://ws.kraken.com/v2"
# WebSocket URL for streaming data from OKX.
url = "wss://ws.okx.com:8443/ws/v5/public"

[manager.crypto.source.band_kiwi]
# URL for Band Kiwi source
url = "https://kiwi.bandchain.org"
# Update interval for Band Kiwi source
update_interval = "1m"

[manager.crypto.source.band_macaw]
# URL for Band Macaw source
url = "https://macaw.bandchain.org"
# Update interval for Band Macaw source
update_interval = "1m"

# Telemetry configuration
[telemetry]
# Enable or disable telemetry.
Expand Down
4 changes: 1 addition & 3 deletions bothan-api/server-cli/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use std::path::PathBuf;

use anyhow::{Context, anyhow};
use bothan_api::config::AppConfig;
use bothan_api::config::manager::crypto_info::sources::CryptoSourceConfigs;
use clap::{Parser, Subcommand};

use crate::bothan_home_dir;
Expand Down Expand Up @@ -54,8 +53,7 @@ impl ConfigCli {
.with_context(|| "Failed to create parent directories")?;
}

let mut app_config = AppConfig::default();
app_config.manager.crypto.source = CryptoSourceConfigs::with_default_sources();
let app_config = AppConfig::default();

let config_str =
toml::to_string(&app_config).with_context(|| "Failed to serialize config")?;
Expand Down
2 changes: 1 addition & 1 deletion bothan-api/server-cli/src/commands/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn export_key(config: &AppConfig) -> anyhow::Result<()> {
read(&config.monitoring.path).with_context(|| "Failed to read monitoring key file")?;
let pk = String::from_utf8(pkb).with_context(|| "Failed to parse monitoring key file")?;
println!("Private Key");
println!("{}", pk);
println!("{pk}");
Ok(())
}

Expand Down
6 changes: 3 additions & 3 deletions bothan-api/server-cli/src/commands/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl RequestCli {
let client = match GrpcClient::connect(&uri).await {
Ok(client) => client,
Err(e) => {
eprintln!("Failed to connect to server: {:#?}", e);
eprintln!("Failed to connect to server: {e:#?}");
std::process::exit(1);
}
};
Expand All @@ -71,7 +71,7 @@ impl RequestCli {
.get_info()
.await
.with_context(|| "Failed to get info")?;
println!("{:#?}", info);
println!("{info:#?}");
}
RequestSubCommand::UpdateRegistry { ipfs_hash, version } => {
client
Expand All @@ -98,7 +98,7 @@ impl RequestCli {
.get_prices(&ids)
.await
.with_context(|| "Failed to get prices")?;
println!("{:#?}", prices);
println!("{prices:#?}");
}
}
Ok(())
Expand Down
2 changes: 2 additions & 0 deletions bothan-api/server-cli/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ async fn init_crypto_opts(
add_worker_opts(&mut worker_opts, &source.htx).await?;
add_worker_opts(&mut worker_opts, &source.kraken).await?;
add_worker_opts(&mut worker_opts, &source.okx).await?;
add_worker_opts(&mut worker_opts, &source.band_kiwi).await?;
add_worker_opts(&mut worker_opts, &source.band_macaw).await?;

Ok(worker_opts)
}
Expand Down
2 changes: 1 addition & 1 deletion bothan-api/server-cli/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<T> Exitable<T> for anyhow::Result<T> {
match self {
Ok(t) => t,
Err(e) => {
eprintln!("{:?}", e);
eprintln!("{e:?}");
std::process::exit(code);
}
}
Expand Down
5 changes: 3 additions & 2 deletions bothan-api/server-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async fn main() {
let cli = match Cli::try_parse() {
Ok(cli) => cli,
Err(e) => {
eprintln!("{}", e);
eprintln!("{e}");
std::process::exit(1);
}
};
Expand Down Expand Up @@ -117,7 +117,8 @@ async fn main() {
.add_directive(create_directive("bothan_cryptocompare", src_log_lvl))
.add_directive(create_directive("bothan_htx", src_log_lvl))
.add_directive(create_directive("bothan_kraken", src_log_lvl))
.add_directive(create_directive("bothan_okx", src_log_lvl));
.add_directive(create_directive("bothan_okx", src_log_lvl))
.add_directive(create_directive("bothan_band", src_log_lvl));

tracing_subscriber::fmt().with_env_filter(filter).init();

Expand Down
1 change: 1 addition & 0 deletions bothan-api/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bothan-coinmarketcap = { workspace = true }
bothan-htx = { workspace = true }
bothan-kraken = { workspace = true }
bothan-okx = { workspace = true }
bothan-band = { workspace = true }

async-trait = { workspace = true }
chrono = { workspace = true }
Expand Down
3 changes: 2 additions & 1 deletion bothan-api/server/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
//! ```rust,no_run
//! use bothan_api::api::BothanServer;
//! use bothan_api::config::AppConfig;
//! use bothan_api::config::manager::crypto_info::sources::CryptoSourceConfigs;
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let config = AppConfig::default();
//! let mut config = AppConfig::default();
//! // Initialize server with config
//! Ok(())
//! }
Expand Down
2 changes: 1 addition & 1 deletion bothan-api/server/src/config/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Display for LogLevel {
LogLevel::Warn => "warn".to_string(),
LogLevel::Error => "error".to_string(),
};
write!(f, "{}", str)
write!(f, "{str}")
}
}

Expand Down
43 changes: 38 additions & 5 deletions bothan-api/server/src/config/manager/crypto_info/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
//!
//! ```rust,no_run
//! use bothan_api::config::manager::crypto_info::sources::CryptoSourceConfigs;
//! let sources = CryptoSourceConfigs::with_default_sources();
//! let sources = CryptoSourceConfigs::default();
//! ```

use serde::{Deserialize, Serialize};

/// Configuration for the worker sources for crypto asset info.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CryptoSourceConfigs {
/// Binance worker options.
pub binance: Option<bothan_binance::WorkerOpts>,
Expand All @@ -32,11 +32,34 @@ pub struct CryptoSourceConfigs {
pub kraken: Option<bothan_kraken::WorkerOpts>,
/// OKX worker options.
pub okx: Option<bothan_okx::WorkerOpts>,
/// Band/kiwi worker options.
#[serde(deserialize_with = "de_kiwi")]
pub band_kiwi: Option<bothan_band::WorkerOpts>,
/// Band/macaw worker options.
#[serde(deserialize_with = "de_macaw")]
pub band_macaw: Option<bothan_band::WorkerOpts>,
}

impl CryptoSourceConfigs {
/// Creates a new `CryptoSourceConfigs` with all sources set to their default options.
pub fn with_default_sources() -> Self {
macro_rules! de_band_named {
($fn_name:ident, $name:expr) => {
fn $fn_name<'de, D>(d: D) -> Result<Option<bothan_band::WorkerOpts>, D::Error>
where
D: serde::Deserializer<'de>,
{
let v = Option::<bothan_band::WorkerOpts>::deserialize(d)?;
let v = v.map(|w| bothan_band::WorkerOpts::new($name, &w.url, Some(w.update_interval)));
Ok(v)
}
};
}

const BAND1_WORKER_NAME: &str = "band/kiwi";
de_band_named!(de_kiwi, BAND1_WORKER_NAME);
const BAND2_WORKER_NAME: &str = "band/macaw";
de_band_named!(de_macaw, BAND2_WORKER_NAME);

impl Default for CryptoSourceConfigs {
fn default() -> Self {
CryptoSourceConfigs {
binance: Some(bothan_binance::WorkerOpts::default()),
bitfinex: Some(bothan_bitfinex::WorkerOpts::default()),
Expand All @@ -47,6 +70,16 @@ impl CryptoSourceConfigs {
htx: Some(bothan_htx::WorkerOpts::default()),
kraken: Some(bothan_kraken::WorkerOpts::default()),
okx: Some(bothan_okx::WorkerOpts::default()),
band_kiwi: Some(bothan_band::WorkerOpts::new(
"band/kiwi",
"https://kiwi.bandchain.org",
None,
)),
band_macaw: Some(bothan_band::WorkerOpts::new(
"band/macaw",
"https://macaw.bandchain.org",
None,
)),
}
}
}
Binary file modified bothan-api/server/src/proto/descriptor.pb
Binary file not shown.
31 changes: 31 additions & 0 deletions bothan-band/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "bothan-band"
version = "0.0.1"
description = "Rust client for the Band source with Bothan integration"
edition.workspace = true
license.workspace = true
repository.workspace = true

[dependencies]
bothan-lib = { workspace = true }

async-trait = { workspace = true }
chrono = { workspace = true }
humantime-serde = { workspace = true }
itertools = { workspace = true }
reqwest = { workspace = true }
rust_decimal = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

[dev-dependencies]
mockito = { workspace = true }


[package.metadata.cargo-machete]
ignored = ["humantime-serde"]
26 changes: 26 additions & 0 deletions bothan-band/src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Band REST API client implementation.
//!
//! This module provides types and utilities for interacting with the Band REST API,
//! including configuration, request execution, error handling, and response deserialization.
//!
//! The module provides:
//!
//! - [`builder`] — A builder pattern for creating [`RestApi`] clients with parameters like base URL.
//! - [`rest`] — Core API client implementation, including HTTP request logic and integration with Bothan's `AssetInfoProvider` trait.
//! - [`types`] — Data types that represent Band REST API responses such as [`Price`](types::Price)
//! - [`error`] — Custom error types used during API client configuration and request processing.
//!
//! # Integration with Workers
//!
//! This module is intended to be used by worker implementations (such as [`Worker`](`crate::worker::Worker`))
//! that periodically query Band for asset data. The [`RestApi`] implements the
//! [`AssetInfoProvider`](bothan_lib::worker::rest::AssetInfoProvider) trait, which allows
//! Band responses to be translated into Bothan-compatible asset updates.

pub use builder::RestApiBuilder;
pub use rest::RestApi;

pub mod builder;
pub mod error;
pub mod rest;
pub mod types;
Loading