pub const TOTALS_QUERY: &str = r#"query Totals {
totals {
tokens
orders
traders
settlements
volumeUsd
volumeEth
feesUsd
feesEth
}
}"#;
pub const LAST_DAYS_VOLUME_QUERY: &str = r#"query LastDaysVolume($days: Int!) {
dailyTotals(orderBy: timestamp, orderDirection: desc, first: $days) {
timestamp
volumeUsd
}
}"#;
pub const LAST_HOURS_VOLUME_QUERY: &str = r#"query LastHoursVolume($hours: Int!) {
hourlyTotals(orderBy: timestamp, orderDirection: desc, first: $hours) {
timestamp
volumeUsd
}
}"#;
pub(crate) const GET_TOTALS: &str =
"{ totals { tokens orders traders settlements volumeUsd volumeEth feesUsd feesEth } }";
pub(crate) const GET_LAST_DAYS_VOLUME: &str = "query($days:Int!){ dailyTotals(first:$days,orderBy:timestamp,orderDirection:desc){ timestamp volumeUsd } }";
pub(crate) const GET_LAST_HOURS_VOLUME: &str = "query($hours:Int!){ hourlyTotals(first:$hours,orderBy:timestamp,orderDirection:desc){ timestamp volumeUsd } }";
pub(crate) const GET_DAILY_TOTALS: &str = "query($n:Int!){ dailyTotals(first:$n,orderBy:timestamp,orderDirection:desc){ timestamp orders traders tokens settlements volumeEth volumeUsd feesEth feesUsd } }";
pub(crate) const GET_HOURLY_TOTALS: &str = "query($n:Int!){ hourlyTotals(first:$n,orderBy:timestamp,orderDirection:desc){ timestamp orders traders tokens settlements volumeEth volumeUsd feesEth feesUsd } }";
pub(crate) const GET_ORDERS_FOR_OWNER: &str = "query($owner:String!,$n:Int!){ orders(first:$n,where:{owner:$owner},orderBy:timestamp,orderDirection:desc){ id owner{id address} sellToken{id address name symbol decimals} buyToken{id address name symbol decimals} sellAmount buyAmount validTo appData feeAmount kind partiallyFillable status executedSellAmount executedSellAmountBeforeFees executedBuyAmount executedFeeAmount timestamp txHash isSignerSafe signingScheme uid } }";
pub(crate) const GET_ETH_PRICE: &str = "{ bundle(id:\"1\") { id ethPriceUSD } }";
pub(crate) const GET_TRADES: &str = "query($n:Int!){ trades(first:$n,orderBy:timestamp,orderDirection:desc){ id timestamp gasPrice feeAmount txHash settlement buyAmount sellAmount sellAmountBeforeFees buyToken{id address name symbol decimals} sellToken{id address name symbol decimals} owner{id address} order } }";
pub(crate) const GET_SETTLEMENTS: &str = "query($n:Int!){ settlements(first:$n,orderBy:firstTradeTimestamp,orderDirection:desc){ id txHash firstTradeTimestamp solver txCost txFeeInEth } }";
pub(crate) const GET_USER: &str = "query($id:String!){ user(id:$id){ id address firstTradeTimestamp numberOfTrades solvedAmountEth solvedAmountUsd } }";
pub(crate) const GET_TOKENS: &str = "query($n:Int!){ tokens(first:$n,orderBy:numberOfTrades,orderDirection:desc){ id address firstTradeTimestamp name symbol decimals totalVolume priceEth priceUsd numberOfTrades } }";
pub(crate) const GET_TOKEN: &str = "query($id:String!){ token(id:$id){ id address firstTradeTimestamp name symbol decimals totalVolume priceEth priceUsd numberOfTrades } }";
pub(crate) const GET_TOKEN_DAILY_TOTALS: &str = "query($token:String!,$n:Int!){ tokenDailyTotals(first:$n,where:{token:$token},orderBy:timestamp,orderDirection:desc){ id token{id address name symbol decimals} timestamp totalVolume totalVolumeUsd totalTrades openPrice closePrice higherPrice lowerPrice averagePrice } }";
pub(crate) const GET_TOKEN_HOURLY_TOTALS: &str = "query($token:String!,$n:Int!){ tokenHourlyTotals(first:$n,where:{token:$token},orderBy:timestamp,orderDirection:desc){ id token{id address name symbol decimals} timestamp totalVolume totalVolumeUsd totalTrades openPrice closePrice higherPrice lowerPrice averagePrice } }";
pub(crate) const GET_TOKEN_TRADING_EVENTS: &str = "query($token:String!,$n:Int!){ tokenTradingEvents(first:$n,where:{token:$token},orderBy:timestamp,orderDirection:desc){ id token{id address name symbol decimals} priceUsd timestamp } }";
pub(crate) const GET_PAIRS: &str = "query($n:Int!){ pairs(first:$n,orderBy:numberOfTrades,orderDirection:desc){ id token0{id address name symbol decimals} token1{id address name symbol decimals} volumeToken0 volumeToken1 numberOfTrades } }";
pub(crate) const GET_PAIR: &str = "query($id:String!){ pair(id:$id){ id token0{id address name symbol decimals} token1{id address name symbol decimals} volumeToken0 volumeToken1 numberOfTrades } }";
pub(crate) const GET_PAIR_DAILY_TOTALS: &str = "query($pair:String!,$n:Int!){ pairDailies(first:$n,where:{id_starts_with:$pair},orderBy:timestamp,orderDirection:desc){ id token0{id address name symbol decimals} token1{id address name symbol decimals} timestamp volumeToken0 volumeToken1 numberOfTrades } }";
pub(crate) const GET_PAIR_HOURLY_TOTALS: &str = "query($pair:String!,$n:Int!){ pairHourlies(first:$n,where:{id_starts_with:$pair},orderBy:timestamp,orderDirection:desc){ id token0{id address name symbol decimals} token1{id address name symbol decimals} timestamp volumeToken0 volumeToken1 numberOfTrades } }";
#[cfg(test)]
pub(crate) type QueryEntry = (&'static str, &'static str, &'static str);
#[cfg(test)]
pub(crate) const CRATE_QUERIES: &[QueryEntry] = &[
("get_totals", GET_TOTALS, "Total"),
("get_last_days_volume", GET_LAST_DAYS_VOLUME, "DailyTotal"),
("get_last_hours_volume", GET_LAST_HOURS_VOLUME, "HourlyTotal"),
("get_daily_totals", GET_DAILY_TOTALS, "DailyTotal"),
("get_hourly_totals", GET_HOURLY_TOTALS, "HourlyTotal"),
("get_orders_for_owner", GET_ORDERS_FOR_OWNER, "Order"),
("get_eth_price", GET_ETH_PRICE, "Bundle"),
("get_trades", GET_TRADES, "Trade"),
("get_settlements", GET_SETTLEMENTS, "Settlement"),
("get_user", GET_USER, "User"),
("get_tokens", GET_TOKENS, "Token"),
("get_token", GET_TOKEN, "Token"),
("get_token_daily_totals", GET_TOKEN_DAILY_TOTALS, "TokenDailyTotal"),
("get_token_hourly_totals", GET_TOKEN_HOURLY_TOTALS, "TokenHourlyTotal"),
("get_token_trading_events", GET_TOKEN_TRADING_EVENTS, "TokenTradingEvent"),
("get_pairs", GET_PAIRS, "Pair"),
("get_pair", GET_PAIR, "Pair"),
("get_pair_daily_totals", GET_PAIR_DAILY_TOTALS, "PairDaily"),
("get_pair_hourly_totals", GET_PAIR_HOURLY_TOTALS, "PairHourly"),
];
#[cfg(test)]
pub(crate) const PUBLIC_QUERIES: &[QueryEntry] = &[
("TOTALS_QUERY", TOTALS_QUERY, "Total"),
("LAST_DAYS_VOLUME_QUERY", LAST_DAYS_VOLUME_QUERY, "DailyTotal"),
("LAST_HOURS_VOLUME_QUERY", LAST_HOURS_VOLUME_QUERY, "HourlyTotal"),
];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn totals_query_contains_expected_fields() {
assert!(TOTALS_QUERY.contains("tokens"));
assert!(TOTALS_QUERY.contains("orders"));
assert!(TOTALS_QUERY.contains("traders"));
assert!(TOTALS_QUERY.contains("settlements"));
assert!(TOTALS_QUERY.contains("volumeUsd"));
assert!(TOTALS_QUERY.contains("volumeEth"));
assert!(TOTALS_QUERY.contains("feesUsd"));
assert!(TOTALS_QUERY.contains("feesEth"));
}
#[test]
fn last_days_volume_query_contains_variable() {
assert!(LAST_DAYS_VOLUME_QUERY.contains("$days: Int!"));
assert!(LAST_DAYS_VOLUME_QUERY.contains("dailyTotals"));
assert!(LAST_DAYS_VOLUME_QUERY.contains("volumeUsd"));
}
#[test]
fn last_hours_volume_query_contains_variable() {
assert!(LAST_HOURS_VOLUME_QUERY.contains("$hours: Int!"));
assert!(LAST_HOURS_VOLUME_QUERY.contains("hourlyTotals"));
assert!(LAST_HOURS_VOLUME_QUERY.contains("volumeUsd"));
}
#[test]
fn every_internal_query_is_registered_exactly_once() {
let names: Vec<&str> = CRATE_QUERIES.iter().map(|(name, _, _)| *name).collect();
let mut sorted = names.clone();
sorted.sort_unstable();
sorted.dedup();
assert_eq!(
names.len(),
sorted.len(),
"CRATE_QUERIES has duplicate helper names — every API method must register exactly \
once"
);
}
}