Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
refactor: harden clob dispatch, deduplicate output helpers, standardi…
…ze formatting
  • Loading branch information
suhailkakar committed Feb 25, 2026
commit fc1999afe39e692029fe7c37c003f1faf35c804d
10 changes: 7 additions & 3 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ use polymarket_client_sdk::{POLYGON, clob};

use crate::config;

pub const RPC_URL: &str = "https://polygon.drpc.org";
const DEFAULT_RPC_URL: &str = "https://polygon.drpc.org";

fn rpc_url() -> String {
std::env::var("POLYMARKET_RPC_URL").unwrap_or_else(|_| DEFAULT_RPC_URL.to_string())
}

fn parse_signature_type(s: &str) -> SignatureType {
match s {
Expand Down Expand Up @@ -53,7 +57,7 @@ pub async fn authenticate_with_signer(

pub async fn create_readonly_provider() -> Result<impl alloy::providers::Provider + Clone> {
ProviderBuilder::new()
.connect(RPC_URL)
.connect(&rpc_url())
.await
.context("Failed to connect to Polygon RPC")
}
Expand All @@ -68,7 +72,7 @@ pub async fn create_provider(
.with_chain_id(Some(POLYGON));
ProviderBuilder::new()
.wallet(signer)
.connect(RPC_URL)
.connect(&rpc_url())
.await
.context("Failed to connect to Polygon RPC with wallet")
}
Expand Down
192 changes: 160 additions & 32 deletions src/commands/clob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,14 +397,7 @@ pub enum CliSide {
Sell,
}

impl From<CliSide> for Side {
fn from(s: CliSide) -> Self {
match s {
CliSide::Buy => Side::Buy,
CliSide::Sell => Side::Sell,
}
}
}
super::enum_from!(CliSide => Side { Buy, Sell });

#[derive(Clone, Debug, clap::ValueEnum)]
pub enum CliInterval {
Expand All @@ -421,18 +414,7 @@ pub enum CliInterval {
Max,
}

impl From<CliInterval> for Interval {
fn from(i: CliInterval) -> Self {
match i {
CliInterval::OneMinute => Interval::OneMinute,
CliInterval::OneHour => Interval::OneHour,
CliInterval::SixHours => Interval::SixHours,
CliInterval::OneDay => Interval::OneDay,
CliInterval::OneWeek => Interval::OneWeek,
CliInterval::Max => Interval::Max,
}
}
}
super::enum_from!(CliInterval => Interval { OneMinute, OneHour, SixHours, OneDay, OneWeek, Max });

#[derive(Clone, Debug, clap::ValueEnum)]
pub enum CliOrderType {
Expand Down Expand Up @@ -463,14 +445,7 @@ pub enum CliAssetType {
Conditional,
}

impl From<CliAssetType> for AssetType {
fn from(a: CliAssetType) -> Self {
match a {
CliAssetType::Collateral => AssetType::Collateral,
CliAssetType::Conditional => AssetType::Conditional,
}
}
}
super::enum_from!(CliAssetType => AssetType { Collateral, Conditional });

fn parse_token_id(s: &str) -> Result<U256> {
U256::from_str(s).map_err(|_| anyhow::anyhow!("Invalid token ID: {s}"))
Expand Down Expand Up @@ -721,7 +696,35 @@ async fn execute_read(command: ClobCommand, output: &OutputFormat) -> Result<()>
print_geoblock(&result, output)?;
}

_ => unreachable!(),
// Trade, reward, and account commands are dispatched by execute() above.
ClobCommand::Orders { .. }
| ClobCommand::Order { .. }
| ClobCommand::CreateOrder { .. }
| ClobCommand::PostOrders { .. }
| ClobCommand::MarketOrder { .. }
| ClobCommand::Cancel { .. }
| ClobCommand::CancelOrders { .. }
| ClobCommand::CancelAll
| ClobCommand::CancelMarket { .. }
| ClobCommand::Trades { .. }
| ClobCommand::Balance { .. }
| ClobCommand::UpdateBalance { .. }
| ClobCommand::Notifications
| ClobCommand::DeleteNotifications { .. }
| ClobCommand::Rewards { .. }
| ClobCommand::Earnings { .. }
| ClobCommand::EarningsMarkets { .. }
| ClobCommand::RewardPercentages
| ClobCommand::CurrentRewards { .. }
| ClobCommand::MarketReward { .. }
| ClobCommand::OrderScoring { .. }
| ClobCommand::OrdersScoring { .. }
| ClobCommand::ApiKeys
| ClobCommand::DeleteApiKey
| ClobCommand::CreateApiKey
| ClobCommand::AccountStatus => {
unreachable!("execute() routes authenticated commands to other handlers")
}
}

Ok(())
Expand Down Expand Up @@ -938,7 +941,43 @@ async fn execute_trade(
}
}

_ => unreachable!(),
// Read, reward, and account commands are dispatched by execute() above.
ClobCommand::Ok
| ClobCommand::Price { .. }
| ClobCommand::BatchPrices { .. }
| ClobCommand::Midpoint { .. }
| ClobCommand::Midpoints { .. }
| ClobCommand::Spread { .. }
| ClobCommand::Spreads { .. }
| ClobCommand::Book { .. }
| ClobCommand::Books { .. }
| ClobCommand::LastTrade { .. }
| ClobCommand::LastTrades { .. }
| ClobCommand::Market { .. }
| ClobCommand::Markets { .. }
| ClobCommand::SamplingMarkets { .. }
| ClobCommand::SimplifiedMarkets { .. }
| ClobCommand::SamplingSimpMarkets { .. }
| ClobCommand::TickSize { .. }
| ClobCommand::FeeRate { .. }
| ClobCommand::NegRisk { .. }
| ClobCommand::PriceHistory { .. }
| ClobCommand::Time
| ClobCommand::Geoblock
| ClobCommand::Rewards { .. }
| ClobCommand::Earnings { .. }
| ClobCommand::EarningsMarkets { .. }
| ClobCommand::RewardPercentages
| ClobCommand::CurrentRewards { .. }
| ClobCommand::MarketReward { .. }
| ClobCommand::OrderScoring { .. }
| ClobCommand::OrdersScoring { .. }
| ClobCommand::ApiKeys
| ClobCommand::DeleteApiKey
| ClobCommand::CreateApiKey
| ClobCommand::AccountStatus => {
unreachable!("execute() routes non-trade commands to other handlers")
}
}

Ok(())
Expand Down Expand Up @@ -1006,7 +1045,49 @@ async fn execute_rewards(
print_orders_scoring(&result, output)?;
}

_ => unreachable!(),
// Read, trade, and account commands are dispatched by execute() above.
ClobCommand::Ok
| ClobCommand::Price { .. }
| ClobCommand::BatchPrices { .. }
| ClobCommand::Midpoint { .. }
| ClobCommand::Midpoints { .. }
| ClobCommand::Spread { .. }
| ClobCommand::Spreads { .. }
| ClobCommand::Book { .. }
| ClobCommand::Books { .. }
| ClobCommand::LastTrade { .. }
| ClobCommand::LastTrades { .. }
| ClobCommand::Market { .. }
| ClobCommand::Markets { .. }
| ClobCommand::SamplingMarkets { .. }
| ClobCommand::SimplifiedMarkets { .. }
| ClobCommand::SamplingSimpMarkets { .. }
| ClobCommand::TickSize { .. }
| ClobCommand::FeeRate { .. }
| ClobCommand::NegRisk { .. }
| ClobCommand::PriceHistory { .. }
| ClobCommand::Time
| ClobCommand::Geoblock
| ClobCommand::Orders { .. }
| ClobCommand::Order { .. }
| ClobCommand::CreateOrder { .. }
| ClobCommand::PostOrders { .. }
| ClobCommand::MarketOrder { .. }
| ClobCommand::Cancel { .. }
| ClobCommand::CancelOrders { .. }
| ClobCommand::CancelAll
| ClobCommand::CancelMarket { .. }
| ClobCommand::Trades { .. }
| ClobCommand::Balance { .. }
| ClobCommand::UpdateBalance { .. }
| ClobCommand::Notifications
| ClobCommand::DeleteNotifications { .. }
| ClobCommand::ApiKeys
| ClobCommand::DeleteApiKey
| ClobCommand::CreateApiKey
| ClobCommand::AccountStatus => {
unreachable!("execute() routes non-reward commands to other handlers")
}
}

Ok(())
Expand Down Expand Up @@ -1043,7 +1124,54 @@ async fn execute_account(
print_account_status(&result, output)?;
}

_ => unreachable!(),
// Read, trade, and reward commands are dispatched by execute() above.
ClobCommand::Ok
| ClobCommand::Price { .. }
| ClobCommand::BatchPrices { .. }
| ClobCommand::Midpoint { .. }
| ClobCommand::Midpoints { .. }
| ClobCommand::Spread { .. }
| ClobCommand::Spreads { .. }
| ClobCommand::Book { .. }
| ClobCommand::Books { .. }
| ClobCommand::LastTrade { .. }
| ClobCommand::LastTrades { .. }
| ClobCommand::Market { .. }
| ClobCommand::Markets { .. }
| ClobCommand::SamplingMarkets { .. }
| ClobCommand::SimplifiedMarkets { .. }
| ClobCommand::SamplingSimpMarkets { .. }
| ClobCommand::TickSize { .. }
| ClobCommand::FeeRate { .. }
| ClobCommand::NegRisk { .. }
| ClobCommand::PriceHistory { .. }
| ClobCommand::Time
| ClobCommand::Geoblock
| ClobCommand::Orders { .. }
| ClobCommand::Order { .. }
| ClobCommand::CreateOrder { .. }
| ClobCommand::PostOrders { .. }
| ClobCommand::MarketOrder { .. }
| ClobCommand::Cancel { .. }
| ClobCommand::CancelOrders { .. }
| ClobCommand::CancelAll
| ClobCommand::CancelMarket { .. }
| ClobCommand::Trades { .. }
| ClobCommand::Balance { .. }
| ClobCommand::UpdateBalance { .. }
| ClobCommand::Notifications
| ClobCommand::DeleteNotifications { .. }
| ClobCommand::Rewards { .. }
| ClobCommand::Earnings { .. }
| ClobCommand::EarningsMarkets { .. }
| ClobCommand::RewardPercentages
| ClobCommand::CurrentRewards { .. }
| ClobCommand::MarketReward { .. }
| ClobCommand::OrderScoring { .. }
| ClobCommand::OrdersScoring { .. }
| ClobCommand::CreateApiKey => {
unreachable!("execute() routes non-account commands to other handlers")
}
}

Ok(())
Expand Down
10 changes: 1 addition & 9 deletions src/commands/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,7 @@ pub enum EntityType {
Series,
}

impl From<EntityType> for ParentEntityType {
fn from(e: EntityType) -> Self {
match e {
EntityType::Event => ParentEntityType::Event,
EntityType::Market => ParentEntityType::Market,
EntityType::Series => ParentEntityType::Series,
}
}
}
super::enum_from!(EntityType => ParentEntityType { Event, Market, Series });

pub async fn execute(
client: &gamma::Client,
Expand Down
20 changes: 2 additions & 18 deletions src/commands/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,31 +164,15 @@ pub enum TimePeriod {
All,
}

impl From<TimePeriod> for polymarket_client_sdk::data::types::TimePeriod {
fn from(t: TimePeriod) -> Self {
match t {
TimePeriod::Day => Self::Day,
TimePeriod::Week => Self::Week,
TimePeriod::Month => Self::Month,
TimePeriod::All => Self::All,
}
}
}
super::enum_from!(TimePeriod => polymarket_client_sdk::data::types::TimePeriod { Day, Week, Month, All });

#[derive(Clone, Debug, clap::ValueEnum)]
pub enum OrderBy {
Pnl,
Vol,
}

impl From<OrderBy> for polymarket_client_sdk::data::types::LeaderboardOrderBy {
fn from(o: OrderBy) -> Self {
match o {
OrderBy::Pnl => Self::Pnl,
OrderBy::Vol => Self::Vol,
}
}
}
super::enum_from!(OrderBy => polymarket_client_sdk::data::types::LeaderboardOrderBy { Pnl, Vol });

pub async fn execute(client: &data::Client, args: DataArgs, output: OutputFormat) -> Result<()> {
match args.command {
Expand Down
13 changes: 13 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ pub mod tags;
pub mod upgrade;
pub mod wallet;

/// Implement `From<CliEnum>` for an SDK enum when variant names match 1:1.
macro_rules! enum_from {
($from:ty => $to:ty { $($variant:ident),+ $(,)? }) => {
impl From<$from> for $to {
fn from(v: $from) -> Self {
match v { $( <$from>::$variant => <$to>::$variant, )+ }
}
}
};
}

pub(crate) use enum_from;

pub fn is_numeric_id(id: &str) -> bool {
id.parse::<u64>().is_ok()
}
Expand Down
9 changes: 1 addition & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ async fn main() -> ExitCode {
let output = cli.output;

if let Err(e) = run(cli).await {
match output {
OutputFormat::Json => {
println!("{}", serde_json::json!({"error": e.to_string()}));
}
OutputFormat::Table => {
eprintln!("Error: {e}");
}
}
output::print_error(&e, output);
return ExitCode::FAILURE;
}

Expand Down
Loading
Loading