use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum TradeAction {
Buy,
Sell,
}
impl TradeAction {
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "buy",
Self::Sell => "sell",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum KolLeaderboardPeriod {
#[serde(rename = "24h")]
H24,
#[serde(rename = "7d")]
D7,
#[serde(rename = "30d")]
D30,
}
impl KolLeaderboardPeriod {
pub fn as_str(&self) -> &'static str {
match self {
Self::H24 => "24h",
Self::D7 => "7d",
Self::D30 => "30d",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum HotTokensWindow {
#[serde(rename = "5m")]
M5,
#[serde(rename = "15m")]
M15,
#[serde(rename = "1h")]
H1,
#[serde(rename = "6h")]
H6,
#[serde(rename = "24h")]
H24,
}
impl HotTokensWindow {
pub fn as_str(&self) -> &'static str {
match self {
Self::M5 => "5m",
Self::M15 => "15m",
Self::H1 => "1h",
Self::H6 => "6h",
Self::H24 => "24h",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum TradeDex {
#[serde(rename = "uniswap-v2")]
UniswapV2,
#[serde(rename = "uniswap-v3")]
UniswapV3,
#[serde(rename = "uniswap-v4")]
UniswapV4,
}
impl TradeDex {
pub fn as_str(&self) -> &'static str {
match self {
Self::UniswapV2 => "uniswap-v2",
Self::UniswapV3 => "uniswap-v3",
Self::UniswapV4 => "uniswap-v4",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TokensSort {
LastTrade,
MarketCap,
Liquidity,
PeakMc,
}
impl TokensSort {
pub fn as_str(&self) -> &'static str {
match self {
Self::LastTrade => "last_trade",
Self::MarketCap => "market_cap",
Self::Liquidity => "liquidity",
Self::PeakMc => "peak_mc",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DeployerTier {
Elite,
Good,
Neutral,
Spammer,
}
impl DeployerTier {
pub fn as_str(&self) -> &'static str {
match self {
Self::Elite => "elite",
Self::Good => "good",
Self::Neutral => "neutral",
Self::Spammer => "spammer",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum DeployerLeaderboardSort {
GraduationRate,
RunnerRate,
TokensDeployed,
BestPeakMcUsd,
LastDeployAt,
}
impl DeployerLeaderboardSort {
pub fn as_str(&self) -> &'static str {
match self {
Self::GraduationRate => "graduation_rate",
Self::RunnerRate => "runner_rate",
Self::TokensDeployed => "tokens_deployed",
Self::BestPeakMcUsd => "best_peak_mc_usd",
Self::LastDeployAt => "last_deploy_at",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AlphaClassification {
All,
Human,
Bot,
SmartMoney,
}
impl AlphaClassification {
pub fn as_str(&self) -> &'static str {
match self {
Self::All => "all",
Self::Human => "human",
Self::Bot => "bot",
Self::SmartMoney => "smart_money",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AlphaIdentity {
All,
KnownKol,
Unknown,
}
impl AlphaIdentity {
pub fn as_str(&self) -> &'static str {
match self {
Self::All => "all",
Self::KnownKol => "known_kol",
Self::Unknown => "unknown",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AlphaSort {
NetEth,
WinRate,
Trades,
Tokens,
BuyEth,
MemecoinShare,
LastTradeAt,
}
impl AlphaSort {
pub fn as_str(&self) -> &'static str {
match self {
Self::NetEth => "net_eth",
Self::WinRate => "win_rate",
Self::Trades => "trades",
Self::Tokens => "tokens",
Self::BuyEth => "buy_eth",
Self::MemecoinShare => "memecoin_share",
Self::LastTradeAt => "last_trade_at",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum SortOrder {
Desc,
Asc,
}
impl SortOrder {
pub fn as_str(&self) -> &'static str {
match self {
Self::Desc => "desc",
Self::Asc => "asc",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum Confidence {
Low,
Medium,
High,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum QualitySignal {
Positive,
Neutral,
Negative,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BundleKind {
SameBlock,
None,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum BestTokensPeriod {
#[serde(rename = "24h")]
H24,
#[serde(rename = "7d")]
D7,
#[serde(rename = "30d")]
D30,
#[serde(rename = "all")]
All,
}
impl BestTokensPeriod {
pub fn as_str(&self) -> &'static str {
match self {
Self::H24 => "24h",
Self::D7 => "7d",
Self::D30 => "30d",
Self::All => "all",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum DeployerTokensSort {
FirstSeenAt,
PeakMcUsd,
}
impl DeployerTokensSort {
pub fn as_str(&self) -> &'static str {
match self {
Self::FirstSeenAt => "first_seen_at",
Self::PeakMcUsd => "peak_mc_usd",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum CoordinationPeriod {
#[serde(rename = "1h")]
H1,
#[serde(rename = "6h")]
H6,
#[serde(rename = "24h")]
H24,
#[serde(rename = "7d")]
D7,
}
impl CoordinationPeriod {
pub fn as_str(&self) -> &'static str {
match self {
Self::H1 => "1h",
Self::H6 => "6h",
Self::H24 => "24h",
Self::D7 => "7d",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum DeployerAlertType {
NewDeploy,
Graduated,
}
impl DeployerAlertType {
pub fn as_str(&self) -> &'static str {
match self {
Self::NewDeploy => "new_deploy",
Self::Graduated => "graduated",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DeployerAlertPriority {
High,
Medium,
}
impl DeployerAlertPriority {
pub fn as_str(&self) -> &'static str {
match self {
Self::High => "high",
Self::Medium => "medium",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum CoordinationSignal {
Accumulating,
Distributing,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum TrajectoryTrend {
Improving,
Declining,
Stable,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct KolFeedParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub action: Option<TradeAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_eth: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcKolTrade {
pub evm_address: String,
#[serde(default)]
pub kol_name: Option<String>,
#[serde(default)]
pub kol_twitter: Option<String>,
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub deployer_tier: Option<String>,
#[serde(default)]
pub token_age_minutes: Option<i64>,
pub action: TradeAction,
#[serde(default)]
pub eth_amount: Option<f64>,
#[serde(default)]
pub token_amount: Option<f64>,
#[serde(default)]
pub price_usd_at_trade: Option<f64>,
#[serde(default)]
pub market_cap_usd_at_trade: Option<f64>,
#[serde(default)]
pub current_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
#[serde(default)]
pub mc_multiple_since_trade: Option<f64>,
pub dex: String,
#[serde(default)]
pub pool: Option<String>,
pub tx_hash: String,
pub block_number: i64,
pub traded_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolFeedResponse {
pub chain: String,
pub trades: Vec<RhcKolTrade>,
pub count: u32,
#[serde(default)]
pub data_age_seconds: Option<i64>,
#[serde(default)]
pub next_before: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct KolLeaderboardParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<KolLeaderboardPeriod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolLeaderboardEntry {
#[serde(default)]
pub kol_name: Option<String>,
#[serde(default)]
pub kol_twitter: Option<String>,
pub trades: i64,
pub buys: i64,
pub sells: i64,
pub buy_eth: f64,
pub sell_eth: f64,
pub net_eth: f64,
pub tokens_traded: i64,
pub last_trade_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolLeaderboardResponse {
pub chain: String,
pub period: String,
pub leaderboard: Vec<KolLeaderboardEntry>,
pub count: u32,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct HotTokensParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub window: Option<HotTokensWindow>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct HotToken {
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub deployer_tier: Option<String>,
pub kols_buying: i64,
pub buys: i64,
pub sells: i64,
pub buy_eth: f64,
pub net_eth: f64,
#[serde(default)]
pub market_cap_usd: Option<f64>,
pub last_trade_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct HotTokensResponse {
pub chain: String,
pub window: String,
pub tokens: Vec<HotToken>,
pub count: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolProfileStats {
pub trades: i64,
pub buys: i64,
pub sells: i64,
pub buy_eth: f64,
pub sell_eth: f64,
pub net_eth: f64,
pub tokens_traded: i64,
pub window: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolProfileResponse {
pub chain: String,
pub evm_address: String,
#[serde(default)]
pub kol_name: Option<String>,
#[serde(default)]
pub kol_twitter: Option<String>,
pub stats: KolProfileStats,
#[serde(default)]
pub trades: Vec<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CoordinationParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<CoordinationPeriod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_kols: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_mc_usd: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_mc_usd: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationKol {
pub evm_address: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub twitter_url: Option<String>,
pub buy_eth: f64,
pub sell_eth: f64,
pub exited: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationToken {
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub deployer_tier: Option<String>,
#[serde(default)]
pub token_age_minutes: Option<i64>,
pub kol_count: i64,
pub total_buys: i64,
pub buy_eth: f64,
pub sell_eth: f64,
pub net_eth: f64,
pub signal: CoordinationSignal,
pub exited_count: i64,
pub holders_count: i64,
pub first_buy_at: String,
pub last_buy_at: String,
pub time_to_consensus_sec: i64,
#[serde(default)]
pub market_cap_usd_at_first_buy: Option<f64>,
#[serde(default)]
pub current_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
#[serde(default)]
pub kols: Vec<CoordinationKol>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationResponse {
pub chain: String,
pub coordination: Vec<CoordinationToken>,
pub count: u32,
pub period: String,
pub min_kols: i64,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct FirstTouchesParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_eth: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_age_max_min: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub launchpad: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_mc_usd: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_mc_usd: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FirstTouchKol {
#[serde(default)]
pub evm_address: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub twitter_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FirstTouchEvent {
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
pub first_buy_at: String,
#[serde(default)]
pub eth_amount: Option<f64>,
#[serde(default)]
pub token_amount: Option<f64>,
pub tx_hash: String,
#[serde(default)]
pub token_age_minutes: Option<i64>,
#[serde(default)]
pub market_cap_usd_at_first_buy: Option<f64>,
#[serde(default)]
pub price_usd_at_first_buy: Option<f64>,
#[serde(default)]
pub current_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
pub first_kol: FirstTouchKol,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FirstTouchesResponse {
pub chain: String,
pub events: Vec<FirstTouchEvent>,
pub count: u32,
#[serde(default)]
pub next_before: Option<String>,
#[serde(default)]
pub data_age_seconds: Option<i64>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct TradesParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dex: Option<TradeDex>,
#[serde(skip_serializing_if = "Option::is_none")]
pub action: Option<TradeAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_eth: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcTrade {
pub block_number: i64,
pub block_time: String,
pub tx_hash: String,
pub log_index: i64,
pub dex: String,
pub pool: String,
#[serde(default)]
pub trader: Option<String>,
#[serde(default)]
pub trader_eoa: Option<String>,
#[serde(default)]
pub router: Option<String>,
#[serde(default)]
pub token_address: Option<String>,
#[serde(default)]
pub action: Option<TradeAction>,
#[serde(default)]
pub eth_amount: Option<f64>,
#[serde(default)]
pub price_native: Option<f64>,
#[serde(default)]
pub price_usd: Option<f64>,
#[serde(default)]
pub mc_usd_at_trade: Option<f64>,
#[serde(default)]
pub gas_price: Option<f64>,
#[serde(default)]
pub tx_index: Option<i64>,
#[serde(default)]
pub method_selector: Option<String>,
#[serde(default)]
pub liquidity: Option<f64>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_kol: bool,
#[serde(default)]
pub kol_name: Option<String>,
#[serde(default)]
pub deployer_tier: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TradesResponse {
pub chain: String,
pub trades: Vec<RhcTrade>,
pub count: u32,
#[serde(default)]
pub next_before: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct TokensListParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort: Option<TokensSort>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_mc_usd: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_liquidity_usd: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub launchpad: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcTokenSummary {
pub token_address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub deployer_address: Option<String>,
#[serde(default)]
pub deployer_tier: Option<String>,
#[serde(default)]
pub price_usd: Option<f64>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub fdv_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
#[serde(default)]
pub drawdown_from_peak_pct: Option<i64>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
#[serde(default)]
pub primary_dex: Option<String>,
#[serde(default)]
pub primary_pool: Option<String>,
#[serde(default)]
pub last_trade_time: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokensListResponse {
pub chain: String,
pub tokens: Vec<RhcTokenSummary>,
pub count: u32,
pub sort: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokenDeployer {
pub address: String,
pub tier: String,
pub tokens_deployed: i64,
#[serde(default)]
pub graduation_rate: Option<f64>,
#[serde(default)]
pub runner_rate: Option<f64>,
pub runners: i64,
#[serde(default)]
pub best_peak_mc_usd: Option<f64>,
#[serde(default)]
pub launchpads: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokenKolActivity {
pub distinct_kols: i64,
#[serde(default)]
pub names: Vec<String>,
pub buys: i64,
pub sells: i64,
pub net_eth: f64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokenDetailResponse {
pub chain: String,
pub token_address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub decimals: Option<i64>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub graduated_pool: Option<String>,
#[serde(default)]
pub graduated_at: Option<String>,
#[serde(default)]
pub deployer_address: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub token_age_minutes: Option<i64>,
#[serde(default)]
pub price_usd: Option<f64>,
#[serde(default)]
pub price_native: Option<f64>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub fdv_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
#[serde(default)]
pub drawdown_from_peak_pct: Option<i64>,
#[serde(default)]
pub total_supply_raw: Option<String>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
#[serde(default)]
pub primary_dex: Option<String>,
#[serde(default)]
pub primary_pool: Option<String>,
#[serde(default)]
pub last_trade_time: Option<String>,
#[serde(default)]
pub deployer: Option<TokenDeployer>,
#[serde(default)]
pub deployer_other_tokens: Vec<String>,
#[serde(default)]
pub kol_activity: Option<TokenKolActivity>,
#[serde(default)]
pub pools: Vec<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct TopTradersParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct FlowParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub window: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct PeakHistoryParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub window: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub curve: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct HoldersParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CandlesParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub to: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcCandle {
pub bucket_start: String,
pub open_price_usd: f64,
pub high_price_usd: f64,
pub low_price_usd: f64,
pub close_price_usd: f64,
#[serde(default)]
pub open_mc_usd: Option<f64>,
#[serde(default)]
pub high_mc_usd: Option<f64>,
#[serde(default)]
pub low_mc_usd: Option<f64>,
#[serde(default)]
pub close_mc_usd: Option<f64>,
#[serde(default)]
pub close_liquidity_usd: Option<f64>,
#[serde(default)]
pub close_supply: Option<f64>,
pub volume_usd: f64,
#[serde(default)]
pub volume_buy_usd: Option<f64>,
#[serde(default)]
pub volume_sell_usd: Option<f64>,
pub trades: i64,
#[serde(default)]
pub buy_count: Option<i64>,
#[serde(default)]
pub sell_count: Option<i64>,
#[serde(default)]
pub dex: Option<String>,
#[serde(default)]
pub pool_address: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CandlesResponse {
pub chain: String,
pub token_address: String,
pub timeframe: String,
pub candles: Vec<RhcCandle>,
pub count: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolConsensus {
pub total_kol_buyers: i64,
pub total_kol_sellers: i64,
pub kol_exit_rate: f64,
pub net_flow_eth: f64,
pub total_buy_eth: f64,
pub total_sell_eth: f64,
#[serde(default)]
pub first_kol_buy_at: Option<String>,
#[serde(default)]
pub last_kol_buy_at: Option<String>,
#[serde(default)]
pub first_touch_wallet: Option<String>,
#[serde(default)]
pub first_touch_at: Option<String>,
#[serde(default)]
pub median_entry_mc_usd: Option<f64>,
#[serde(default)]
pub entry_mc_samples: i64,
pub total_trades: i64,
#[serde(default)]
pub buyers: Vec<String>,
#[serde(default)]
pub exited: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct KolConsensusResponse {
pub chain: String,
pub token_address: String,
#[serde(default)]
pub current_mc_usd: Option<f64>,
#[serde(default)]
pub current_price_usd: Option<f64>,
#[serde(default)]
pub consensus: Option<KolConsensus>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BuyerQualityBreakdown {
pub early_buyers_analyzed: i64,
pub alpha_wallet_count: i64,
pub kol_count: i64,
pub bundle_buyer_count: i64,
pub dump_cluster_count: i64,
pub recycled_early_buyer_count: i64,
#[serde(default)]
pub avg_historical_win_rate: Option<f64>,
pub bot_dominated: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BuyerQuality {
pub score: i64,
pub confidence: Confidence,
pub signal: QualitySignal,
pub breakdown: BuyerQualityBreakdown,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BuyerQualityCoverage {
#[serde(default)]
pub bundle_detection: Option<String>,
#[serde(default)]
pub dump_cluster_signal: Option<String>,
#[serde(default)]
pub note: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BuyerQualityResponse {
pub chain: String,
pub token_address: String,
#[serde(default)]
pub current_mc_usd: Option<f64>,
pub quality: BuyerQuality,
#[serde(default)]
pub coverage: Option<BuyerQualityCoverage>,
#[serde(default)]
pub note: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcBundle {
pub wallet_count: i64,
pub bundle_kind: BundleKind,
#[serde(default)]
pub held_ratio: Option<f64>,
#[serde(default)]
pub held_pct_of_supply: Option<f64>,
pub fully_exited: bool,
pub buy_volume: f64,
pub tokens_held: f64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcBundleWallet {
pub rank: i64,
pub wallet: String,
#[serde(default)]
pub held_ratio: Option<f64>,
pub has_sold: bool,
#[serde(default)]
pub is_kol: bool,
#[serde(default)]
pub win_rate: Option<f64>,
#[serde(default)]
pub likely_bot: Option<bool>,
#[serde(default)]
pub tokens_held: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcBundleResponse {
pub chain: String,
pub token_address: String,
pub bundle: RhcBundle,
#[serde(default)]
pub wallets: Vec<RhcBundleWallet>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct BatchAddressesRequest {
pub addresses: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokenBatchDeployer {
pub address: String,
#[serde(default)]
pub source: Option<String>,
#[serde(default)]
pub tier: Option<String>,
#[serde(default)]
pub tokens_deployed: Option<i64>,
#[serde(default)]
pub graduated: Option<i64>,
#[serde(default)]
pub graduation_rate: Option<f64>,
#[serde(default)]
pub runners: Option<i64>,
#[serde(default)]
pub runner_rate: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokenBatchEntry {
pub address: String,
pub found: bool,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub decimals: Option<i64>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub graduated_at: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub price_usd: Option<f64>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub fdv_usd: Option<f64>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
#[serde(default)]
pub primary_dex: Option<String>,
#[serde(default)]
pub last_trade_time: Option<String>,
#[serde(default)]
pub deployer: Option<TokenBatchDeployer>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TokenBatchResponse {
pub chain: String,
pub tokens: Vec<TokenBatchEntry>,
pub requested: i64,
pub found: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchBuyerQualityEntry {
pub chain: String,
pub token_address: String,
#[serde(default)]
pub current_mc_usd: Option<f64>,
#[serde(default)]
pub quality: Option<BuyerQuality>,
#[serde(default)]
pub note: Option<String>,
#[serde(default)]
pub error: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BatchBuyerQualityResponse {
pub chain: String,
pub tokens: Vec<BatchBuyerQualityEntry>,
pub requested: i64,
pub scored: i64,
pub max_addresses: i64,
#[serde(default)]
pub coverage: Option<BuyerQualityCoverage>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct DeployerLeaderboardParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub sort: Option<DeployerLeaderboardSort>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tier: Option<DeployerTier>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_tokens: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcDeployerRow {
pub deployer_address: String,
pub tokens_deployed: i64,
pub graduated: i64,
pub graduation_rate: f64,
pub runners: i64,
pub runner_rate: f64,
#[serde(default)]
pub best_peak_mc_usd: Option<f64>,
#[serde(default)]
pub launchpads: Vec<String>,
#[serde(default)]
pub first_deploy_at: Option<String>,
#[serde(default)]
pub last_deploy_at: Option<String>,
pub tier: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerLeaderboardResponse {
pub chain: String,
pub deployers: Vec<RhcDeployerRow>,
pub total: i64,
pub limit: i64,
pub offset: i64,
pub has_more: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcDeployer {
pub deployer_address: String,
pub tokens_deployed: i64,
pub curve_tokens: i64,
pub graduated: i64,
#[serde(default)]
pub bonding_rate: Option<f64>,
pub runners: i64,
pub runner_rate: f64,
#[serde(default)]
pub best_peak_mc_usd: Option<f64>,
#[serde(default)]
pub launchpads: Vec<String>,
#[serde(default)]
pub first_deploy_at: Option<String>,
#[serde(default)]
pub last_deploy_at: Option<String>,
pub tier: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcDeployerToken {
pub address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub graduated_at: Option<String>,
#[serde(default)]
pub graduated_pool: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerProfileResponse {
pub chain: String,
pub is_deployer: bool,
pub address: String,
#[serde(default)]
pub deployer: Option<RhcDeployer>,
#[serde(default)]
pub recent_tokens: Vec<RhcDeployerToken>,
#[serde(default)]
pub recent_tokens_count: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrajectoryStreak {
#[serde(rename = "type")]
pub kind: String,
pub count: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrajectoryWindow {
pub window_end: i64,
pub bond_rate: f64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrajectoryStretch {
pub start_index: i64,
pub end_index: i64,
pub bond_rate: f64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerTrajectory {
pub current_streak: TrajectoryStreak,
pub longest_bond_streak: i64,
pub longest_fail_streak: i64,
#[serde(default)]
pub rolling_bond_rates: Vec<TrajectoryWindow>,
pub trend: TrajectoryTrend,
#[serde(default)]
pub avg_days_between_deploys: Option<f64>,
#[serde(default)]
pub avg_recovery_tokens: Option<f64>,
#[serde(default)]
pub best_stretch: Option<TrajectoryStretch>,
#[serde(default)]
pub worst_stretch: Option<TrajectoryStretch>,
pub total_tokens_analyzed: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerTrajectoryResponse {
pub chain: String,
pub is_deployer: bool,
pub address: String,
#[serde(default)]
pub deployer: Option<RhcDeployerRow>,
#[serde(default)]
pub success_metric: Option<String>,
#[serde(default)]
pub trajectory: Option<DeployerTrajectory>,
#[serde(default)]
pub truncated: bool,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct DeployerTokensParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort: Option<DeployerTokensSort>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerTokenRow {
pub address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub deployer_source: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub graduated_at: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerTokensResponse {
pub chain: String,
pub is_deployer: bool,
pub address: String,
#[serde(default)]
pub deployer: Option<RhcDeployerRow>,
#[serde(default)]
pub tokens: Vec<DeployerTokenRow>,
pub total: i64,
pub limit: i64,
pub offset: i64,
pub has_more: bool,
#[serde(default)]
pub sort: Option<String>,
#[serde(default)]
pub sort_scope: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct BestTokensParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<BestTokensPeriod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BestTokenDeployer {
pub address: String,
pub tier: String,
#[serde(default)]
pub graduation_rate: Option<f64>,
#[serde(default)]
pub runner_rate: Option<f64>,
pub tokens_deployed: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BestToken {
pub address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
#[serde(default)]
pub deployer: Option<BestTokenDeployer>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct BestTokensResponse {
pub chain: String,
pub tokens: Vec<BestToken>,
pub period: String,
pub limit: i64,
pub reputable_deployers: i64,
#[serde(default)]
pub candidates_scanned: Option<i64>,
#[serde(default)]
pub truncated: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerTierCount {
pub deployers: i64,
pub tokens: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerTierRules {
#[serde(default)]
pub elite: Option<String>,
#[serde(default)]
pub good: Option<String>,
#[serde(default)]
pub spammer: Option<String>,
#[serde(default)]
pub neutral: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerStatsResponse {
pub chain: String,
pub total_deployers: i64,
pub total_tokens: i64,
pub reputable_deployers: i64,
#[serde(default)]
pub by_tier: HashMap<String, DeployerTierCount>,
#[serde(default)]
pub spam_token_share: Option<f64>,
pub alerts_24h: i64,
pub alerts_7d: i64,
pub tier_rules: DeployerTierRules,
pub graduation_definition: String,
pub runner_definition: String,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct DeployerAlertsParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub deployer_tier: Option<DeployerTier>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<DeployerAlertPriority>,
#[serde(skip_serializing_if = "Option::is_none")]
pub alert_type: Option<DeployerAlertType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub launchpad: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_mc: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub include_untradeable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcDeployerAlert {
pub id: String,
pub deployer_address: String,
#[serde(default)]
pub token_address: Option<String>,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
pub alert_type: DeployerAlertType,
#[serde(default)]
pub title: Option<String>,
#[serde(default)]
pub message: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub tier: Option<String>,
#[serde(default)]
pub tier_at_alert: Option<String>,
#[serde(default)]
pub tier_is_stale: bool,
#[serde(default)]
pub mc_at_alert: Option<f64>,
#[serde(default)]
pub current_mc_usd: Option<f64>,
#[serde(default)]
pub liquidity_usd: Option<f64>,
pub priority: DeployerAlertPriority,
pub is_active: bool,
pub created_at: String,
#[serde(default)]
pub event_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerAlertsResponse {
pub chain: String,
pub alerts: Vec<RhcDeployerAlert>,
pub limit: i64,
pub offset: i64,
pub tradability_filter: String,
#[serde(default)]
pub next_event_at: Option<String>,
#[serde(default)]
pub next_before: Option<String>,
#[serde(default)]
pub data_age_seconds: Option<i64>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct DeployerHistoryParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerHistoryToken {
pub address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub graduated_at: Option<String>,
#[serde(default)]
pub graduated_pool: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DeployerHistoryResponse {
pub chain: String,
pub is_deployer: bool,
pub address: String,
#[serde(default)]
pub deployer: Option<RhcDeployerRow>,
#[serde(default)]
pub tokens: Vec<DeployerHistoryToken>,
pub total: i64,
pub limit: i64,
pub offset: i64,
pub has_more: bool,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct RecentBondsParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub deployer_tier: Option<DeployerTier>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_peak: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RecentBondToken {
pub address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub is_graduated: Option<bool>,
#[serde(default)]
pub deployer_address: Option<String>,
#[serde(default)]
pub deployer_tier: Option<String>,
#[serde(default)]
pub first_seen_at: Option<String>,
#[serde(default)]
pub market_cap_usd: Option<f64>,
#[serde(default)]
pub peak_mc_usd: Option<f64>,
#[serde(default)]
pub peak_mc_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RecentBondsResponse {
pub chain: String,
pub graduation_mc: i64,
pub tokens: Vec<RecentBondToken>,
pub limit: i64,
#[serde(default)]
pub next_peak_mc_at: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct AlphaWalletsParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub classification: Option<AlphaClassification>,
#[serde(skip_serializing_if = "Option::is_none")]
pub identity: Option<AlphaIdentity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_memecoin_share: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_avg_mc_usd: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_net_eth: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_win_rate: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_win_rate: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_trades: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_tokens: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_buy_eth: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub active_hours: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort: Option<AlphaSort>,
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<SortOrder>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcAlphaWallet {
pub wallet: String,
pub classification: String,
pub is_known_kol: bool,
pub trades: i64,
pub tokens: i64,
pub buy_eth: f64,
pub sell_eth: f64,
pub net_eth: f64,
#[serde(default)]
pub win_rate: Option<f64>,
#[serde(default)]
pub memecoin_share: Option<f64>,
#[serde(default)]
pub avg_trade_mc_usd: Option<f64>,
#[serde(default)]
pub last_trade_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AlphaWalletsResponse {
pub chain: String,
pub wallets: Vec<RhcAlphaWallet>,
pub total: i64,
pub limit: i64,
pub offset: i64,
pub has_more: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct StreamToken {
pub token: String,
pub expires_at: String,
#[serde(default)]
pub next_refresh_at: Option<String>,
pub ws_url: String,
#[serde(default)]
pub dex_ws_url: Option<String>,
#[serde(default)]
pub usage: Option<String>,
#[serde(default, rename = "_rid")]
pub _rid: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct StreamSession {
pub id: String,
pub service: String,
pub tier: String,
pub channels: Vec<String>,
pub connected_at: String,
#[serde(default)]
pub remote_ip: Option<String>,
pub messages_sent: u64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct StreamSessionsResponse {
pub sessions: Vec<StreamSession>,
pub count: u32,
#[serde(default, rename = "_rid")]
pub _rid: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct StreamSessionEvicted {
pub evicted: bool,
pub id: String,
#[serde(default, rename = "_rid")]
pub _rid: Option<String>,
}