Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 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
24 changes: 24 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
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ This project comprises primarily of 6 main components:
- [HTX](bothan-htx)
- [Kraken](bothan-kraken)
- [OKX](bothan-okx)
- [Band/kiwi](bothan-band)
- [Band/macaw](bothan-band)

## Features

Expand Down Expand Up @@ -64,6 +66,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
1 change: 1 addition & 0 deletions bothan-api/server-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ bothan-coinmarketcap = { workspace = true }
bothan-htx = { workspace = true }
bothan-kraken = { workspace = true }
bothan-okx = { workspace = true }
bothan-band = { workspace = true }

dirs = { workspace = true }
futures = { workspace = true }
Expand Down
14 changes: 13 additions & 1 deletion bothan-api/server-cli/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ api_key = ""
# User agent string for HTTP requests to CoinGecko.
user_agent = "Bothan"
# Update interval for polling data from CoinGecko.
update_interval = "30s"
update_interval = "1m"

# Configuration for CoinMarketCap.
[manager.crypto.source.coinmarketcap]
Expand All @@ -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
36 changes: 36 additions & 0 deletions bothan-api/server-cli/src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ pub enum QuerySubCommand {
#[clap(flatten)]
args: QueryArgs,
},
/// Query Band/kiwi prices
#[clap(name = "band/kiwi")]
BandKiwi {
#[clap(flatten)]
args: QueryArgs,
},
/// Query Band/macaw prices
#[clap(name = "band/macaw")]
BandMacaw {
#[clap(flatten)]
args: QueryArgs,
},
}

impl QueryCli {
Expand Down Expand Up @@ -155,6 +167,14 @@ impl QueryCli {
let opts = source_config.okx.ok_or(config_err)?;
query_okx(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::BandKiwi { args } => {
let opts = source_config.band_kiwi.ok_or(config_err)?;
query_band(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::BandMacaw { args } => {
let opts = source_config.band_macaw.ok_or(config_err)?;
query_band(opts, &args.query_ids, args.timeout).await?;
}
}

Ok(())
Expand Down Expand Up @@ -294,6 +314,22 @@ async fn query_okx<T: Into<Duration>>(
Ok(())
}

async fn query_band<T: Into<Duration>>(
opts: bothan_band::WorkerOpts,
query_ids: &[String],
timeout_interval: T,
) -> anyhow::Result<()> {
let api = bothan_band::api::RestApiBuilder::new(opts.url).build()?;
let asset_infos = timeout(
timeout_interval.into(),
api.get_asset_info(&dedup(query_ids)),
)
.await??;

display_asset_infos(asset_infos);
Ok(())
}

async fn query_websocket_with_max_sub<C, P, E1, E2>(
connector: Arc<C>,
ids: Vec<String>,
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
53 changes: 48 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,44 @@ pub struct CryptoSourceConfigs {
pub kraken: Option<bothan_kraken::WorkerOpts>,
/// OKX worker options.
pub okx: Option<bothan_okx::WorkerOpts>,
/// Band/kiwi worker options.
///
/// NOTE: The `name` field in `WorkerOpts` is marked with `#[serde(skip)]`, so deserialized instances
/// will have an empty/default name. The custom deserializer `de_kiwi` reconstructs the options
/// with the correct name.
/// Custom deserializer is required to ensure the correct name is set.
#[serde(deserialize_with = "de_kiwi")]
pub band_kiwi: Option<bothan_band::WorkerOpts>,
/// Band/macaw worker options.
///
/// NOTE: The `name` field in `WorkerOpts` is marked with `#[serde(skip)]`, so deserialized instances
/// will have an empty/default name. The custom deserializer `de_macaw` reconstructs the options
/// with the correct name.
/// Custom deserializer is required to ensure the correct name is set.
#[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 +80,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.
Loading