Skip to content

Commit 504ad6d

Browse files
tanut32039Tanut Lertwarachai
andauthored
[Feat] add forex (#141)
* add forex * fix copilot comment * add name * add forex stale time * fix copilot comment * add serde default to forex config * add macro deserialize comment * refactor macro * update stale_threshold * fix test failed * change mod * change prefix logic * fix bitfinex and update version * add no run on bitfinex doctests * let forex be optional * let forex and crypto be optinal * delet serde default * default_stale_threshold from 3600 to 7200 --------- Co-authored-by: Tanut Lertwarachai <tanutlertwarachai@Tanuts-MacBook-Pro.local>
1 parent f85e3a4 commit 504ad6d

50 files changed

Lines changed: 698 additions & 388 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 17 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,20 @@ resolver = "2"
1717

1818
[workspace.dependencies]
1919
bothan-api = { path = "bothan-api/server" }
20-
bothan-core = { path = "bothan-core", version = "0.1.0" }
21-
bothan-client = { path = "bothan-api/client/rust-client", version = "0.1.0" }
22-
bothan-lib = { path = "bothan-lib", version = "0.1.0" }
20+
bothan-core = { path = "bothan-core", version = "0.1.1" }
21+
bothan-client = { path = "bothan-api/client/rust-client", version = "0.1.1" }
22+
bothan-lib = { path = "bothan-lib", version = "0.1.1" }
2323

24-
bothan-binance = { path = "bothan-binance", version = "0.1.0" }
25-
bothan-bitfinex = { path = "bothan-bitfinex", version = "0.1.0" }
26-
bothan-bybit = { path = "bothan-bybit", version = "0.1.0" }
27-
bothan-coinbase = { path = "bothan-coinbase", version = "0.1.0" }
28-
bothan-coingecko = { path = "bothan-coingecko", version = "0.1.0" }
29-
bothan-coinmarketcap = { path = "bothan-coinmarketcap", version = "0.1.0" }
30-
bothan-htx = { path = "bothan-htx", version = "0.1.0" }
31-
bothan-kraken = { path = "bothan-kraken", version = "0.1.0" }
32-
bothan-okx = { path = "bothan-okx", version = "0.1.0" }
33-
bothan-band = { path = "bothan-band", version = "0.1.0" }
34-
35-
anyhow = "1.0.86"
24+
bothan-binance = { path = "bothan-binance", version = "0.1.1" }
25+
bothan-bitfinex = { path = "bothan-bitfinex", version = "0.1.1" }
26+
bothan-bybit = { path = "bothan-bybit", version = "0.1.1" }
27+
bothan-coinbase = { path = "bothan-coinbase", version = "0.1.1" }
28+
bothan-coingecko = { path = "bothan-coingecko", version = "0.1.1" }
29+
bothan-coinmarketcap = { path = "bothan-coinmarketcap", version = "0.1.1" }
30+
bothan-htx = { path = "bothan-htx", version = "0.1.1" }
31+
bothan-kraken = { path = "bothan-kraken", version = "0.1.1" }
32+
bothan-okx = { path = "bothan-okx", version = "0.1.1" }
33+
bothan-band = { path = "bothan-band", version = "0.1.1" }
3634
async-trait = "0.1.77"
3735
bincode = "2.0.1"
3836
chrono = "0.4.39"
@@ -46,8 +44,6 @@ mockito = "1.4.0"
4644
num-traits = "0.2.19"
4745
opentelemetry = { version = "0.28.0", features = ["metrics"] }
4846
prost = "0.13.1"
49-
protoc-gen-prost = "0.4.0"
50-
protoc-gen-tonic = "0.4.1"
5147
rand = "0.8.5"
5248
reqwest = { version = "0.12.3", features = ["json"] }
5349
rust_decimal = "1.10.2"

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ This project comprises primarily of 6 main components:
2323
- `bothan-{exchange}` - Exchange-specific implementations
2424
- [`proto`](proto/) - Protocol buffer definitions
2525

26-
## Supported Data Sources
26+
## Supported Crypto Data Sources
2727

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

41+
## Supported Forex Data Sources
42+
43+
- [Band/owlet](bothan-band)
44+
- [Band/fieldfare](bothan-band)
45+
- [Band/xenops](bothan-band)
46+
4147
## Features
4248

4349
- **Unified API**: Consistent interface across all supported exchanges

bothan-api/client/rust-client/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bothan-client"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
description = "Rust client for the Bothan API"
55
authors.workspace = true
66
edition.workspace = true

bothan-api/server-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bothan-api-cli"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition.workspace = true
55
license.workspace = true
66
repository.workspace = true

bothan-api/server-cli/config.example.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ enabled = false
4141
# The threshold in seconds after which data is considered stale.
4242
stale_threshold = 300
4343

44+
# Manager configuration for handling forex data sources
45+
[manager.forex]
46+
# The threshold in seconds after which data is considered stale.
47+
stale_threshold = 7200
48+
4449
# Configuration for the data sources that the manager will use.
4550
# If any of these [manager.crypto.source] sections (e.g., section manager.crypto.source.binance) are removed,
4651
# that specific source will not be used in bothan.
@@ -114,6 +119,24 @@ url = "https://macaw.bandchain.org"
114119
# Update interval for Band Macaw source
115120
update_interval = "1m"
116121

122+
[manager.forex.source.band_owlet]
123+
# URL for Band Owlet source
124+
url = "https://owlet.bandchain.org"
125+
# Update interval for Band Owlet source
126+
update_interval = "1m"
127+
128+
[manager.forex.source.band_fieldfare]
129+
# URL for Band Fieldfare source
130+
url = "https://fieldfare.bandchain.org"
131+
# Update interval for Band Fieldfare source
132+
update_interval = "1m"
133+
134+
[manager.forex.source.band_xenops]
135+
# URL for Band Xenops source
136+
url = "https://xenops.bandchain.org"
137+
# Update interval for Band Xenops source
138+
update_interval = "1m"
139+
117140
# Telemetry configuration
118141
[telemetry]
119142
# Enable or disable telemetry.

bothan-api/server-cli/src/commands/query.rs

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//!
77
//! ## Features
88
//!
9-
//! - Query prices from Binance, Bitfinex, Bybit, Coinbase, CoinGecko, CoinMarketCap, HTX, Kraken, OKX
9+
//! - Query prices from Binance, Bitfinex, Bybit, Coinbase, CoinGecko, CoinMarketCap, HTX, Kraken, OKX, Band (Kiwi, Macaw, Owlet, Fieldfare, Xenops)
1010
//! - Customizable timeout and query IDs
1111
//! - Pretty-printed table output
1212
//!
@@ -124,55 +124,90 @@ pub enum QuerySubCommand {
124124
#[clap(flatten)]
125125
args: QueryArgs,
126126
},
127+
/// Query Band/owlet prices
128+
#[clap(name = "band/owlet")]
129+
BandOwlet {
130+
#[clap(flatten)]
131+
args: QueryArgs,
132+
},
133+
/// Query Band/fieldfare prices
134+
#[clap(name = "band/fieldfare")]
135+
BandFieldfare {
136+
#[clap(flatten)]
137+
args: QueryArgs,
138+
},
139+
/// Query Band/xenops prices
140+
#[clap(name = "band/xenops")]
141+
BandXenops {
142+
#[clap(flatten)]
143+
args: QueryArgs,
144+
},
127145
}
128146

129147
impl QueryCli {
130148
pub async fn run(&self, app_config: AppConfig) -> anyhow::Result<()> {
131-
let source_config = app_config.manager.crypto.source;
149+
let crypto_config = app_config.manager.crypto.and_then(|c| c.source);
150+
let forex_config = app_config.manager.forex.and_then(|f| f.source);
132151
let config_err = anyhow!("Config is missing. Please check your config.toml.");
133152
match &self.subcommand {
134153
QuerySubCommand::Binance { args } => {
135-
let opts = source_config.binance.ok_or(config_err)?;
154+
let opts = crypto_config.and_then(|c| c.binance).ok_or(config_err)?;
136155
query_binance(opts, &args.query_ids, args.timeout).await?;
137156
}
138157
QuerySubCommand::Bitfinex { args } => {
139-
let opts = source_config.bitfinex.ok_or(config_err)?;
158+
let opts = crypto_config.and_then(|c| c.bitfinex).ok_or(config_err)?;
140159
query_bitfinex(opts, &args.query_ids, args.timeout).await?;
141160
}
142161
QuerySubCommand::Bybit { args } => {
143-
let opts = source_config.bybit.ok_or(config_err)?;
162+
let opts = crypto_config.and_then(|c| c.bybit).ok_or(config_err)?;
144163
query_bybit(opts, &args.query_ids, args.timeout).await?;
145164
}
146165
QuerySubCommand::Coinbase { args } => {
147-
let opts = source_config.coinbase.ok_or(config_err)?;
166+
let opts = crypto_config.and_then(|c| c.coinbase).ok_or(config_err)?;
148167
query_coinbase(opts, &args.query_ids, args.timeout).await?;
149168
}
150169
QuerySubCommand::CoinGecko { args } => {
151-
let opts = source_config.coingecko.ok_or(config_err)?;
170+
let opts = crypto_config.and_then(|c| c.coingecko).ok_or(config_err)?;
152171
query_coingecko(opts, &args.query_ids, args.timeout).await?;
153172
}
154173
QuerySubCommand::CoinMarketCap { args } => {
155-
let opts = source_config.coinmarketcap.ok_or(config_err)?;
174+
let opts = crypto_config
175+
.and_then(|c| c.coinmarketcap)
176+
.ok_or(config_err)?;
156177
query_coinmarketcap(opts, &args.query_ids, args.timeout).await?;
157178
}
158179
QuerySubCommand::Htx { args } => {
159-
let opts = source_config.htx.ok_or(config_err)?;
180+
let opts = crypto_config.and_then(|c| c.htx).ok_or(config_err)?;
160181
query_htx(opts, &args.query_ids, args.timeout).await?;
161182
}
162183
QuerySubCommand::Kraken { args } => {
163-
let opts = source_config.kraken.ok_or(config_err)?;
184+
let opts = crypto_config.and_then(|c| c.kraken).ok_or(config_err)?;
164185
query_kraken(opts, &args.query_ids, args.timeout).await?;
165186
}
166187
QuerySubCommand::Okx { args } => {
167-
let opts = source_config.okx.ok_or(config_err)?;
188+
let opts = crypto_config.and_then(|c| c.okx).ok_or(config_err)?;
168189
query_okx(opts, &args.query_ids, args.timeout).await?;
169190
}
170191
QuerySubCommand::BandKiwi { args } => {
171-
let opts = source_config.band_kiwi.ok_or(config_err)?;
192+
let opts = crypto_config.and_then(|c| c.band_kiwi).ok_or(config_err)?;
172193
query_band(opts, &args.query_ids, args.timeout).await?;
173194
}
174195
QuerySubCommand::BandMacaw { args } => {
175-
let opts = source_config.band_macaw.ok_or(config_err)?;
196+
let opts = crypto_config.and_then(|c| c.band_macaw).ok_or(config_err)?;
197+
query_band(opts, &args.query_ids, args.timeout).await?;
198+
}
199+
QuerySubCommand::BandOwlet { args } => {
200+
let opts = forex_config.and_then(|f| f.band_owlet).ok_or(config_err)?;
201+
query_band(opts, &args.query_ids, args.timeout).await?;
202+
}
203+
QuerySubCommand::BandFieldfare { args } => {
204+
let opts = forex_config
205+
.and_then(|f| f.band_fieldfare)
206+
.ok_or(config_err)?;
207+
query_band(opts, &args.query_ids, args.timeout).await?;
208+
}
209+
QuerySubCommand::BandXenops { args } => {
210+
let opts = forex_config.and_then(|f| f.band_xenops).ok_or(config_err)?;
176211
query_band(opts, &args.query_ids, args.timeout).await?;
177212
}
178213
}

0 commit comments

Comments
 (0)