Skip to content
Merged
35 changes: 17 additions & 18 deletions Cargo.lock

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

30 changes: 13 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,20 @@ resolver = "2"

[workspace.dependencies]
bothan-api = { path = "bothan-api/server" }
bothan-core = { path = "bothan-core", version = "0.1.0" }
bothan-client = { path = "bothan-api/client/rust-client", version = "0.1.0" }
bothan-lib = { path = "bothan-lib", version = "0.1.0" }
bothan-core = { path = "bothan-core", version = "0.1.1" }
bothan-client = { path = "bothan-api/client/rust-client", version = "0.1.1" }
bothan-lib = { path = "bothan-lib", version = "0.1.1" }

bothan-binance = { path = "bothan-binance", version = "0.1.0" }
bothan-bitfinex = { path = "bothan-bitfinex", version = "0.1.0" }
bothan-bybit = { path = "bothan-bybit", version = "0.1.0" }
bothan-coinbase = { path = "bothan-coinbase", version = "0.1.0" }
bothan-coingecko = { path = "bothan-coingecko", version = "0.1.0" }
bothan-coinmarketcap = { path = "bothan-coinmarketcap", version = "0.1.0" }
bothan-htx = { path = "bothan-htx", version = "0.1.0" }
bothan-kraken = { path = "bothan-kraken", version = "0.1.0" }
bothan-okx = { path = "bothan-okx", version = "0.1.0" }
bothan-band = { path = "bothan-band", version = "0.1.0" }

anyhow = "1.0.86"
bothan-binance = { path = "bothan-binance", version = "0.1.1" }
bothan-bitfinex = { path = "bothan-bitfinex", version = "0.1.1" }
bothan-bybit = { path = "bothan-bybit", version = "0.1.1" }
bothan-coinbase = { path = "bothan-coinbase", version = "0.1.1" }
bothan-coingecko = { path = "bothan-coingecko", version = "0.1.1" }
bothan-coinmarketcap = { path = "bothan-coinmarketcap", version = "0.1.1" }
bothan-htx = { path = "bothan-htx", version = "0.1.1" }
bothan-kraken = { path = "bothan-kraken", version = "0.1.1" }
bothan-okx = { path = "bothan-okx", version = "0.1.1" }
bothan-band = { path = "bothan-band", version = "0.1.1" }
async-trait = "0.1.77"
bincode = "2.0.1"
chrono = "0.4.39"
Expand All @@ -46,8 +44,6 @@ mockito = "1.4.0"
num-traits = "0.2.19"
opentelemetry = { version = "0.28.0", features = ["metrics"] }
prost = "0.13.1"
protoc-gen-prost = "0.4.0"
protoc-gen-tonic = "0.4.1"
rand = "0.8.5"
reqwest = { version = "0.12.3", features = ["json"] }
rust_decimal = "1.10.2"
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ This project comprises primarily of 6 main components:
- `bothan-{exchange}` - Exchange-specific implementations
- [`proto`](proto/) - Protocol buffer definitions

## Supported Data Sources
## Supported Crypto Data Sources

- [Binance](bothan-binance)
- [Bitfinex](bothan-bitfinex)
Expand All @@ -38,6 +38,12 @@ This project comprises primarily of 6 main components:
- [Band/kiwi](bothan-band)
- [Band/macaw](bothan-band)

## Supported Forex Data Sources

- [Band/owlet](bothan-band)
- [Band/fieldfare](bothan-band)
- [Band/xenops](bothan-band)

## Features

- **Unified API**: Consistent interface across all supported exchanges
Expand Down
2 changes: 1 addition & 1 deletion bothan-api/client/rust-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bothan-client"
version = "0.1.0"
version = "0.1.1"
description = "Rust client for the Bothan API"
authors.workspace = true
edition.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion bothan-api/server-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bothan-api-cli"
version = "0.1.0"
version = "0.1.1"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
23 changes: 23 additions & 0 deletions bothan-api/server-cli/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ enabled = false
# The threshold in seconds after which data is considered stale.
stale_threshold = 300

# Manager configuration for handling forex data sources
[manager.forex]
# The threshold in seconds after which data is considered stale.
stale_threshold = 7200

# Configuration for the data sources that the manager will use.
# If any of these [manager.crypto.source] sections (e.g., section manager.crypto.source.binance) are removed,
# that specific source will not be used in bothan.
Expand Down Expand Up @@ -114,6 +119,24 @@ url = "https://macaw.bandchain.org"
# Update interval for Band Macaw source
update_interval = "1m"

[manager.forex.source.band_owlet]
# URL for Band Owlet source
url = "https://owlet.bandchain.org"
# Update interval for Band Owlet source
update_interval = "1m"

[manager.forex.source.band_fieldfare]
# URL for Band Fieldfare source
url = "https://fieldfare.bandchain.org"
# Update interval for Band Fieldfare source
update_interval = "1m"

[manager.forex.source.band_xenops]
# URL for Band Xenops source
url = "https://xenops.bandchain.org"
# Update interval for Band Xenops source
update_interval = "1m"

# Telemetry configuration
[telemetry]
# Enable or disable telemetry.
Expand Down
61 changes: 48 additions & 13 deletions bothan-api/server-cli/src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! ## Features
//!
//! - Query prices from Binance, Bitfinex, Bybit, Coinbase, CoinGecko, CoinMarketCap, HTX, Kraken, OKX
//! - Query prices from Binance, Bitfinex, Bybit, Coinbase, CoinGecko, CoinMarketCap, HTX, Kraken, OKX, Band (Kiwi, Macaw, Owlet, Fieldfare, Xenops)
//! - Customizable timeout and query IDs
//! - Pretty-printed table output
//!
Expand Down Expand Up @@ -124,55 +124,90 @@ pub enum QuerySubCommand {
#[clap(flatten)]
args: QueryArgs,
},
/// Query Band/owlet prices
#[clap(name = "band/owlet")]
BandOwlet {
#[clap(flatten)]
args: QueryArgs,
},
/// Query Band/fieldfare prices
#[clap(name = "band/fieldfare")]
BandFieldfare {
#[clap(flatten)]
args: QueryArgs,
},
/// Query Band/xenops prices
#[clap(name = "band/xenops")]
BandXenops {
#[clap(flatten)]
args: QueryArgs,
},
}

impl QueryCli {
pub async fn run(&self, app_config: AppConfig) -> anyhow::Result<()> {
let source_config = app_config.manager.crypto.source;
let crypto_config = app_config.manager.crypto.and_then(|c| c.source);
let forex_config = app_config.manager.forex.and_then(|f| f.source);
let config_err = anyhow!("Config is missing. Please check your config.toml.");
match &self.subcommand {
QuerySubCommand::Binance { args } => {
let opts = source_config.binance.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.binance).ok_or(config_err)?;
query_binance(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::Bitfinex { args } => {
let opts = source_config.bitfinex.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.bitfinex).ok_or(config_err)?;
query_bitfinex(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::Bybit { args } => {
let opts = source_config.bybit.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.bybit).ok_or(config_err)?;
query_bybit(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::Coinbase { args } => {
let opts = source_config.coinbase.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.coinbase).ok_or(config_err)?;
query_coinbase(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::CoinGecko { args } => {
let opts = source_config.coingecko.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.coingecko).ok_or(config_err)?;
query_coingecko(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::CoinMarketCap { args } => {
let opts = source_config.coinmarketcap.ok_or(config_err)?;
let opts = crypto_config
.and_then(|c| c.coinmarketcap)
.ok_or(config_err)?;
query_coinmarketcap(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::Htx { args } => {
let opts = source_config.htx.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.htx).ok_or(config_err)?;
query_htx(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::Kraken { args } => {
let opts = source_config.kraken.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.kraken).ok_or(config_err)?;
query_kraken(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::Okx { args } => {
let opts = source_config.okx.ok_or(config_err)?;
let opts = crypto_config.and_then(|c| c.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)?;
let opts = crypto_config.and_then(|c| c.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)?;
let opts = crypto_config.and_then(|c| c.band_macaw).ok_or(config_err)?;
query_band(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::BandOwlet { args } => {
let opts = forex_config.and_then(|f| f.band_owlet).ok_or(config_err)?;
query_band(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::BandFieldfare { args } => {
let opts = forex_config
.and_then(|f| f.band_fieldfare)
.ok_or(config_err)?;
query_band(opts, &args.query_ids, args.timeout).await?;
}
QuerySubCommand::BandXenops { args } => {
let opts = forex_config.and_then(|f| f.band_xenops).ok_or(config_err)?;
query_band(opts, &args.query_ids, args.timeout).await?;
}
}
Expand Down
Loading
Loading