use crate::cli::common::write_json_output;
use clap::{Args, Subcommand};
use polymarket_hft::client::coingecko::{
Client, CoinDetailRequest, CoinHistoryRequest, CoinsListRequest, CoinsMarketsRequest,
ExchangesRequest, MarketChartRequest, OhlcRequest, SimplePriceRequest,
};
#[derive(Subcommand)]
pub enum CgCommands {
SimplePrice {
#[command(flatten)]
params: SimplePriceArgs,
},
SupportedVsCurrencies,
CoinsList {
#[command(flatten)]
params: CoinsListArgs,
},
CoinsMarkets {
#[command(flatten)]
params: CoinsMarketsArgs,
},
Trending,
Global,
Exchanges {
#[command(flatten)]
params: ExchangesArgs,
},
Coin {
#[command(flatten)]
params: CoinArgs,
},
MarketChart {
#[command(flatten)]
params: MarketChartArgs,
},
History {
#[command(flatten)]
params: HistoryArgs,
},
Ohlc {
#[command(flatten)]
params: OhlcArgs,
},
}
#[derive(Args, Debug, Clone)]
pub struct SimplePriceArgs {
#[arg(long)]
pub ids: String,
#[arg(long, default_value = "usd")]
pub vs_currencies: String,
#[arg(long)]
pub include_market_cap: bool,
#[arg(long)]
pub include_24hr_vol: bool,
#[arg(long)]
pub include_24hr_change: bool,
#[arg(long)]
pub include_last_updated_at: bool,
}
#[derive(Args, Debug, Clone, Default)]
pub struct CoinsListArgs {
#[arg(long)]
pub include_platform: bool,
#[arg(long)]
pub limit: Option<usize>,
}
#[derive(Args, Debug, Clone)]
pub struct CoinsMarketsArgs {
#[arg(long, default_value = "usd")]
pub vs_currency: String,
#[arg(long)]
pub ids: Option<String>,
#[arg(long)]
pub category: Option<String>,
#[arg(long)]
pub order: Option<String>,
#[arg(long)]
pub per_page: Option<u32>,
#[arg(long)]
pub page: Option<u32>,
#[arg(long)]
pub sparkline: bool,
#[arg(long)]
pub price_change_percentage: Option<String>,
}
#[derive(Args, Debug, Clone, Default)]
pub struct ExchangesArgs {
#[arg(long)]
pub per_page: Option<u32>,
#[arg(long)]
pub page: Option<u32>,
}
#[derive(Args, Debug, Clone)]
pub struct CoinArgs {
#[arg(long)]
pub id: String,
#[arg(long)]
pub no_localization: bool,
#[arg(long)]
pub no_tickers: bool,
#[arg(long)]
pub no_market_data: bool,
#[arg(long)]
pub no_community_data: bool,
#[arg(long)]
pub no_developer_data: bool,
}
#[derive(Args, Debug, Clone)]
pub struct MarketChartArgs {
#[arg(long)]
pub id: String,
#[arg(long, default_value = "usd")]
pub vs_currency: String,
#[arg(long, default_value = "7")]
pub days: String,
#[arg(long)]
pub interval: Option<String>,
}
#[derive(Args, Debug, Clone)]
pub struct HistoryArgs {
#[arg(long)]
pub id: String,
#[arg(long)]
pub date: String,
#[arg(long)]
pub no_localization: bool,
}
#[derive(Args, Debug, Clone)]
pub struct OhlcArgs {
#[arg(long)]
pub id: String,
#[arg(long, default_value = "usd")]
pub vs_currency: String,
#[arg(long, default_value = "7")]
pub days: String,
}
fn get_api_key() -> anyhow::Result<String> {
std::env::var("CG_API_KEY").map_err(|_| {
anyhow::anyhow!(
"CG_API_KEY environment variable not set. \
Get your free API key at https://www.coingecko.com/en/api"
)
})
}
pub async fn handle(command: &CgCommands) -> anyhow::Result<()> {
let api_key = get_api_key()?;
let client = Client::new(api_key);
match command {
CgCommands::SimplePrice { params } => {
let request = SimplePriceRequest {
ids: params.ids.clone(),
vs_currencies: params.vs_currencies.clone(),
include_market_cap: Some(params.include_market_cap),
include_24hr_vol: Some(params.include_24hr_vol),
include_24hr_change: Some(params.include_24hr_change),
include_last_updated_at: Some(params.include_last_updated_at),
};
let response = client.get_simple_price(request).await?;
write_json_output(&response)?;
}
CgCommands::SupportedVsCurrencies => {
let response = client.get_supported_vs_currencies().await?;
write_json_output(&response)?;
}
CgCommands::CoinsList { params } => {
let request = CoinsListRequest {
include_platform: if params.include_platform {
Some(true)
} else {
None
},
};
let response = client.get_coins_list(request).await?;
if let Some(limit) = params.limit {
let limited: Vec<_> = response.into_iter().take(limit).collect();
write_json_output(&limited)?;
} else {
write_json_output(&response)?;
}
}
CgCommands::CoinsMarkets { params } => {
let request = CoinsMarketsRequest {
vs_currency: params.vs_currency.clone(),
ids: params.ids.clone(),
category: params.category.clone(),
order: params.order.clone(),
per_page: params.per_page,
page: params.page,
sparkline: if params.sparkline { Some(true) } else { None },
price_change_percentage: params.price_change_percentage.clone(),
..Default::default()
};
let response = client.get_coins_markets(request).await?;
write_json_output(&response)?;
}
CgCommands::Trending => {
let response = client.get_trending().await?;
write_json_output(&response)?;
}
CgCommands::Global => {
let response = client.get_global().await?;
write_json_output(&response)?;
}
CgCommands::Exchanges { params } => {
let request = ExchangesRequest {
per_page: params.per_page,
page: params.page,
};
let response = client.get_exchanges(request).await?;
write_json_output(&response)?;
}
CgCommands::Coin { params } => {
let request = CoinDetailRequest {
id: params.id.clone(),
localization: if params.no_localization {
Some(false)
} else {
None
},
tickers: if params.no_tickers { Some(false) } else { None },
market_data: if params.no_market_data {
Some(false)
} else {
None
},
community_data: if params.no_community_data {
Some(false)
} else {
None
},
developer_data: if params.no_developer_data {
Some(false)
} else {
None
},
sparkline: None,
};
let response = client.get_coin(request).await?;
write_json_output(&response)?;
}
CgCommands::MarketChart { params } => {
let request = MarketChartRequest {
id: params.id.clone(),
vs_currency: params.vs_currency.clone(),
days: params.days.clone(),
interval: params.interval.clone(),
};
let response = client.get_coin_market_chart(request).await?;
write_json_output(&response)?;
}
CgCommands::History { params } => {
let request = CoinHistoryRequest {
id: params.id.clone(),
date: params.date.clone(),
localization: if params.no_localization {
Some(false)
} else {
None
},
};
let response = client.get_coin_history(request).await?;
write_json_output(&response)?;
}
CgCommands::Ohlc { params } => {
let request = OhlcRequest {
id: params.id.clone(),
vs_currency: params.vs_currency.clone(),
days: params.days.clone(),
};
let response = client.get_coin_ohlc(request).await?;
write_json_output(&response)?;
}
}
Ok(())
}