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 LpEventsParams {
#[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 pool: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub provider: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dex: Option<TradeDex>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcLpEvent {
pub event: String,
pub pool: String,
pub dex: String,
#[serde(default)]
pub fee_tier: Option<i64>,
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
#[serde(default)]
pub token_decimals: Option<i64>,
#[serde(default)]
pub launchpad: Option<String>,
#[serde(default)]
pub provider: Option<String>,
#[serde(default)]
pub provider_is_token_deployer: bool,
#[serde(default)]
pub provider_deployer_tier: Option<String>,
#[serde(default)]
pub provider_kol_name: Option<String>,
#[serde(default)]
pub liquidity: Option<String>,
#[serde(default)]
pub amount0: Option<String>,
#[serde(default)]
pub amount1: Option<String>,
#[serde(default)]
pub token0: Option<String>,
#[serde(default)]
pub token1: Option<String>,
#[serde(default)]
pub token_amount_raw: Option<String>,
#[serde(default)]
pub quote_token: Option<String>,
#[serde(default)]
pub quote_amount_raw: Option<String>,
pub block_number: i64,
pub block_time: String,
pub tx_hash: String,
pub log_index: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct LpEventsCoverage {
#[serde(default)]
pub events: Vec<String>,
#[serde(default)]
pub adds_persisted: bool,
#[serde(default)]
pub note: Option<String>,
#[serde(default)]
pub since: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct LpEventsResponse {
pub chain: String,
pub events: Vec<RhcLpEvent>,
#[serde(default)]
pub count: u32,
#[serde(default)]
pub has_more: bool,
#[serde(default)]
pub next_before: Option<String>,
#[serde(default)]
pub coverage: Option<LpEventsCoverage>,
}
#[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, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum EquitiesSort {
Volume,
Trades,
MarketCap,
LastTrade,
Symbol,
}
impl EquitiesSort {
pub fn as_str(&self) -> &'static str {
match self {
Self::Volume => "volume",
Self::Trades => "trades",
Self::MarketCap => "market_cap",
Self::LastTrade => "last_trade",
Self::Symbol => "symbol",
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct EquitiesParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub sort: Option<EquitiesSort>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub q: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcEquity {
pub token_address: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub onchain_name: Option<String>,
#[serde(default)]
pub asset_class: Option<String>,
#[serde(default)]
pub verified: bool,
#[serde(default)]
pub issuer_beacon: Option<String>,
#[serde(default)]
pub decimals: Option<i64>,
#[serde(default)]
pub listed_at: Option<String>,
#[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 liquidity_usd: Option<f64>,
#[serde(default)]
pub liquidity_basis: Option<String>,
#[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 trades_24h: i64,
#[serde(default)]
pub volume_eth_24h: f64,
#[serde(default)]
pub buys_24h: i64,
#[serde(default)]
pub sells_24h: i64,
#[serde(default)]
pub buyers_24h: i64,
#[serde(default)]
pub sellers_24h: i64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct EquitiesIdentity {
#[serde(default)]
pub method: Option<String>,
#[serde(default)]
pub issuer_beacon: Option<String>,
#[serde(default)]
pub note: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct EquitiesResponse {
pub chain: String,
pub equities: Vec<RhcEquity>,
#[serde(default)]
pub count: u32,
#[serde(default)]
pub total_equities: u32,
#[serde(default)]
pub sort: Option<String>,
#[serde(default)]
pub identity: Option<EquitiesIdentity>,
#[serde(default)]
pub stats_window: Option<String>,
#[serde(default)]
pub stats_as_of: Option<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, Deserialize)]
pub struct HolderGrowthWindow {
#[serde(default)]
pub cutoff_block: Option<i64>,
#[serde(default)]
pub entered: Option<i64>,
#[serde(default)]
pub entered_still_holding: Option<i64>,
#[serde(default)]
pub exited: Option<i64>,
#[serde(default)]
pub net: Option<i64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct HolderGrowth {
#[serde(rename = "1h", default)]
pub h1: Option<HolderGrowthWindow>,
#[serde(rename = "24h", default)]
pub h24: Option<HolderGrowthWindow>,
#[serde(rename = "7d", default)]
pub d7: Option<HolderGrowthWindow>,
#[serde(default)]
pub note: Option<String>,
}
#[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,
#[serde(default)]
pub expires_at: Option<String>,
#[serde(default)]
pub next_refresh_at: Option<String>,
#[serde(default)]
pub rotated: Option<bool>,
#[serde(default)]
pub lifetime: 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>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DeliveryMode {
Webhook,
Websocket,
Both,
}
impl DeliveryMode {
pub fn as_str(&self) -> &'static str {
match self {
Self::Webhook => "webhook",
Self::Websocket => "websocket",
Self::Both => "both",
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcDeletedResponse {
pub chain: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum CopyTradeOnlyAction {
Buy,
Sell,
Both,
}
impl CopyTradeOnlyAction {
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "buy",
Self::Sell => "sell",
Self::Both => "both",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CopyTradeSizingMode {
Fixed,
Proportional,
PercentSource,
}
impl CopyTradeSizingMode {
pub fn as_str(&self) -> &'static str {
match self {
Self::Fixed => "fixed",
Self::Proportional => "proportional",
Self::PercentSource => "percent_source",
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcCopyTradeSubscription {
pub id: i64,
#[serde(default)]
pub name: Option<String>,
pub source_wallets: Vec<String>,
pub min_trade_eth: f64,
pub only_action: CopyTradeOnlyAction,
pub sizing_mode: CopyTradeSizingMode,
pub sizing_amount: f64,
pub delivery_mode: DeliveryMode,
#[serde(default)]
pub webhook_url: Option<String>,
pub is_active: bool,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CopyTradeListResponse {
pub chain: String,
pub subscriptions: Vec<RhcCopyTradeSubscription>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CopyTradeCreateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub source_wallets: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_trade_eth: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub only_action: Option<CopyTradeOnlyAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sizing_mode: Option<CopyTradeSizingMode>,
pub sizing_amount: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CopyTradeCreateResponse {
pub chain: String,
pub subscription: RhcCopyTradeSubscription,
#[serde(default)]
pub webhook_secret: Option<String>,
pub note: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CopyTradeGetResponse {
pub chain: String,
pub subscription: RhcCopyTradeSubscription,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CopyTradeUpdateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_wallets: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_trade_eth: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub only_action: Option<CopyTradeOnlyAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sizing_mode: Option<CopyTradeSizingMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sizing_amount: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CopyTradeSignalsParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub subscription_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcCopyTradeSignal {
pub id: i64,
pub subscription_id: i64,
pub fired_at: String,
pub source_wallet: String,
pub action: TradeAction,
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
#[serde(default)]
pub token_name: Option<String>,
#[serde(default)]
pub source_eth_amount: Option<f64>,
#[serde(default)]
pub suggested_eth_amount: Option<f64>,
#[serde(default)]
pub price_usd: Option<f64>,
#[serde(default)]
pub dex: Option<String>,
pub tx_hash: String,
pub delivered: bool,
#[serde(default)]
pub delivered_at: Option<String>,
}
#[derive(Debug, Clone, Default, Deserialize)]
pub struct CopyTradeSignalsResponse {
pub chain: String,
pub signals: Vec<RhcCopyTradeSignal>,
#[serde(default)]
pub count: u32,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum PriceAlertStatus {
Watching,
Dipped,
Recovered,
Expired,
}
impl PriceAlertStatus {
pub fn as_str(&self) -> &'static str {
match self {
Self::Watching => "watching",
Self::Dipped => "dipped",
Self::Recovered => "recovered",
Self::Expired => "expired",
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcPriceAlert {
pub id: i64,
#[serde(default)]
pub name: Option<String>,
pub token_address: String,
#[serde(default)]
pub token_symbol: Option<String>,
pub baseline_mc_usd: f64,
pub drop_pct: f64,
#[serde(default)]
pub recovery_pct: Option<f64>,
pub status: PriceAlertStatus,
#[serde(default)]
pub dip_low_mc_usd: Option<f64>,
#[serde(default)]
pub dip_fired_at: Option<String>,
pub delivery_mode: DeliveryMode,
#[serde(default)]
pub webhook_url: Option<String>,
pub is_active: bool,
pub expires_at: String,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PriceAlertListResponse {
pub chain: String,
pub alerts: Vec<RhcPriceAlert>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct PriceAlertCreateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub token_address: String,
pub drop_pct: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub recovery_pct: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PriceAlertEvaluation {
pub mode: String,
pub interval_seconds: i64,
pub note: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PriceAlertCreateResponse {
pub chain: String,
pub alert: RhcPriceAlert,
#[serde(default)]
pub webhook_secret: Option<String>,
pub evaluation: PriceAlertEvaluation,
pub note: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PriceAlertGetResponse {
pub chain: String,
pub alert: RhcPriceAlert,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct PriceAlertUpdateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum PriceAlertEventType {
Dip,
Recovery,
}
impl PriceAlertEventType {
pub fn as_str(&self) -> &'static str {
match self {
Self::Dip => "dip",
Self::Recovery => "recovery",
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct PriceAlertEventsParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub alert_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_type: Option<PriceAlertEventType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcPriceAlertEvent {
pub id: i64,
pub alert_id: i64,
pub event_type: PriceAlertEventType,
pub fired_at: String,
pub token_address: String,
pub baseline_mc_usd: f64,
pub current_mc_usd: f64,
#[serde(default)]
pub drop_pct_actual: Option<f64>,
#[serde(default)]
pub dip_low_mc_usd: Option<f64>,
#[serde(default)]
pub recovery_pct_actual: Option<f64>,
pub delivered: bool,
#[serde(default)]
pub delivered_at: Option<String>,
}
#[derive(Debug, Clone, Default, Deserialize)]
pub struct PriceAlertEventsResponse {
pub chain: String,
pub events: Vec<RhcPriceAlertEvent>,
#[serde(default)]
pub count: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcCoordinationAlertRule {
pub id: String,
#[serde(default)]
pub name: Option<String>,
pub min_kols: i64,
pub window_minutes: i64,
pub min_score: i64,
pub cooldown_min: i64,
pub score_jump_break: i64,
#[serde(default)]
pub min_mc_usd: Option<f64>,
#[serde(default)]
pub max_mc_usd: Option<f64>,
pub delivery_mode: DeliveryMode,
#[serde(default)]
pub webhook_url: Option<String>,
pub is_active: bool,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationAlertListResponse {
pub chain: String,
pub rules: Vec<RhcCoordinationAlertRule>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CoordinationAlertCreateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_kols: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub window_minutes: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_score: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cooldown_min: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score_jump_break: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_mc_usd: Option<Option<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_mc_usd: Option<Option<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationAlertScoring {
pub score_version: String,
pub quality: String,
pub earliness: String,
pub note: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationAlertCreateResponse {
pub chain: String,
pub rule: RhcCoordinationAlertRule,
#[serde(default)]
pub webhook_secret: Option<String>,
pub scoring: CoordinationAlertScoring,
pub note: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CoordinationAlertGetResponse {
pub chain: String,
pub rule: RhcCoordinationAlertRule,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CoordinationAlertUpdateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_kols: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub window_minutes: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_score: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cooldown_min: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score_jump_break: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_mc_usd: Option<Option<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_mc_usd: Option<Option<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum FirstTouchStrategy {
Scalper,
DayTrader,
Swing,
Inactive,
Unscored,
}
impl FirstTouchStrategy {
pub fn as_str(&self) -> &'static str {
match self {
Self::Scalper => "scalper",
Self::DayTrader => "day_trader",
Self::Swing => "swing",
Self::Inactive => "inactive",
Self::Unscored => "unscored",
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct FirstTouchFilters {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub kol: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_first_buy_eth: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_kol_winrate: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub strategy: Option<FirstTouchStrategy>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_mc_usd: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_mc_usd: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RhcFirstTouchSubscription {
pub id: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub filters: FirstTouchFilters,
pub delivery_mode: DeliveryMode,
#[serde(default)]
pub webhook_url: Option<String>,
pub is_active: bool,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FirstTouchSubscriptionListResponse {
pub chain: String,
pub subscriptions: Vec<RhcFirstTouchSubscription>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct FirstTouchSubscriptionCreateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filters: Option<FirstTouchFilters>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FirstTouchSubscriptionCreateResponse {
pub chain: String,
pub subscription: RhcFirstTouchSubscription,
#[serde(default)]
pub webhook_secret: Option<String>,
pub note: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FirstTouchSubscriptionGetResponse {
pub chain: String,
pub subscription: RhcFirstTouchSubscription,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct FirstTouchSubscriptionUpdateParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filters: Option<FirstTouchFilters>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delivery_mode: Option<DeliveryMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<Option<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_active: Option<bool>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletStats {
pub first_seen: Option<String>,
pub last_seen: Option<String>,
pub total_trades: u64,
pub analyzed_trades: u64,
pub unattributed_trades: u64,
pub unsized_trades: u64,
pub buys: u64,
pub sells: u64,
pub bought_eth: f64,
pub sold_eth: f64,
pub realized_pnl_eth: f64,
pub unrealized_pnl_eth: f64,
pub total_pnl_eth: f64,
pub held_value_eth: f64,
pub unique_tokens: u64,
pub open_positions: u64,
pub window_days: u32,
pub partial: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletFlags {
pub is_kol: bool,
pub kol_name: Option<String>,
pub is_deployer: bool,
pub deployer_tier: Option<String>,
pub deployer_tokens: Option<u64>,
pub deployer_runner_rate: Option<f64>,
pub is_alpha_tracked: bool,
pub alpha_win_rate: Option<f64>,
pub alpha_net_eth: Option<f64>,
pub alpha_tokens_traded: Option<u64>,
pub likely_bot: Option<bool>,
pub is_dumper: bool,
#[serde(default)]
pub dump_cluster: serde_json::Value,
pub early_buyer_tokens: u64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletDerived {
pub win_rate: Option<f64>,
pub wins: u64,
pub losses: u64,
pub avg_trade_size_eth: Option<f64>,
pub is_active: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletProfileResponse {
pub chain: String,
pub address: String,
pub stats: WalletStats,
pub flags: WalletFlags,
#[serde(default)]
pub top_tokens: Vec<serde_json::Value>,
#[serde(default)]
pub recent_trades: Vec<serde_json::Value>,
pub derived: WalletDerived,
#[serde(default)]
pub stats_unavailable: bool,
#[serde(default)]
pub cache_hit: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OpenPosition {
pub token_address: String,
pub token_symbol: Option<String>,
pub token_name: Option<String>,
pub launchpad: Option<String>,
pub is_graduated: Option<bool>,
pub token_amount: f64,
pub cost_basis_eth: f64,
pub avg_entry_price_eth: f64,
pub current_price_eth: Option<f64>,
pub current_value_eth: Option<f64>,
pub unrealized_eth: Option<f64>,
pub unrealized_pct: Option<f64>,
pub current_mc_usd: Option<f64>,
pub liquidity_usd: Option<f64>,
pub liquidity_basis: String,
pub buys_in_position: u64,
pub realized_so_far_eth: f64,
pub first_buy_at: Option<String>,
pub last_buy_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ClosedPosition {
pub token_address: String,
pub token_symbol: Option<String>,
pub buy_count: u64,
pub sell_count: u64,
pub bought_eth: f64,
pub sold_eth: f64,
pub pnl_eth: f64,
pub roi_pct: Option<f64>,
pub hold_minutes: Option<i64>,
pub result: String,
pub first_trade: Option<String>,
pub last_trade: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PnlCurvePoint {
pub date: String,
pub day_pnl: f64,
pub cumulative_pnl: f64,
pub trades: u64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletPnlSummary {
pub realized_eth: f64,
pub unrealized_eth: f64,
pub total_pnl_eth: f64,
pub total_bought_eth: f64,
pub total_sold_eth: f64,
pub wins: u64,
pub losses: u64,
pub win_rate: Option<f64>,
pub profit_factor: Option<f64>,
pub avg_hold_minutes: Option<i64>,
pub median_hold_minutes: Option<i64>,
pub max_drawdown_eth: f64,
pub open_positions_count: u64,
pub closed_positions_count: u64,
pub total_tokens_traded: u64,
#[serde(default)]
pub best_realized: serde_json::Value,
#[serde(default)]
pub worst_realized: serde_json::Value,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletPnlNotes {
pub denomination: String,
pub cost_basis_observable_from: String,
pub data_through: Option<String>,
pub trades_seen: u64,
pub trades_analyzed: u64,
pub trades_unattributed: u64,
pub trades_unsized: u64,
pub partial: bool,
#[serde(default)]
pub partial_reason: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletPnlResponse {
pub chain: String,
pub address: String,
pub window_days: u32,
pub summary: WalletPnlSummary,
#[serde(default)]
pub pnl_curve: Vec<PnlCurvePoint>,
#[serde(default)]
pub closed_positions: Vec<ClosedPosition>,
#[serde(default)]
pub open_positions: Vec<OpenPosition>,
pub notes: WalletPnlNotes,
#[serde(default)]
pub cache_hit: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletPositionsSummary {
pub open_positions: u64,
pub total_cost_basis_eth: f64,
pub total_current_value_eth: f64,
pub total_unrealized_eth: f64,
pub unpriced_positions: u64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletPositionsResponse {
pub chain: String,
pub address: String,
pub window_days: u32,
pub summary: WalletPositionsSummary,
#[serde(default)]
pub positions: Vec<OpenPosition>,
#[serde(default)]
pub notes: serde_json::Value,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct WalletTradesParams {
#[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 since: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub action: Option<TradeAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTrade {
pub token_address: Option<String>,
pub token_symbol: Option<String>,
pub token_name: Option<String>,
pub launchpad: Option<String>,
pub action: Option<TradeAction>,
pub eth_amount: Option<f64>,
pub token_amount: Option<f64>,
pub price_native: Option<f64>,
pub price_usd: Option<f64>,
pub mc_usd_at_trade: Option<f64>,
pub dex: Option<String>,
pub pool: Option<String>,
pub router: Option<String>,
pub method_selector: Option<String>,
pub tx_hash: String,
pub log_index: i64,
pub block_number: u64,
pub block_time: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTradesResponse {
pub chain: String,
pub address: String,
#[serde(default)]
pub trades: Vec<WalletTrade>,
pub count: u64,
pub has_more: bool,
pub next_before: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrackedWallet {
pub wallet_address: String,
pub label: Option<String>,
pub added_at: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTrackerListResponse {
pub chain: String,
#[serde(default)]
pub wallets: Vec<TrackedWallet>,
pub count: u64,
pub limit: u64,
pub remaining: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct WalletTrackerAddParams {
pub wallet_address: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTrackerWalletResponse {
pub chain: String,
pub wallet: TrackedWallet,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTrackerRemovedResponse {
pub chain: String,
pub removed: String,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct WalletTrackerTradesParams {
#[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 wallet: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub action: Option<TradeAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrackedWalletTrade {
#[serde(flatten)]
pub trade: WalletTrade,
pub trader_eoa: Option<String>,
pub label: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTrackerTradesResponse {
pub chain: String,
#[serde(default)]
pub trades: Vec<TrackedWalletTrade>,
pub count: u64,
pub has_more: bool,
pub next_before: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct WalletTrackerSummaryParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wallet: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrackedWalletStats {
pub trades: u64,
pub buys: u64,
pub sells: u64,
pub buy_eth: f64,
pub sell_eth: f64,
pub net_eth: f64,
pub tokens_traded: u64,
pub last_trade_at: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct TrackedWalletSummary {
pub wallet_address: String,
pub label: Option<String>,
pub added_at: String,
pub stats: TrackedWalletStats,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WalletTrackerSummaryResponse {
pub chain: String,
pub period: String,
pub interval: String,
#[serde(default)]
pub stats_unavailable: bool,
#[serde(default)]
pub wallets: Vec<TrackedWalletSummary>,
}