use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use solana_sdk::pubkey::Pubkey;
#[cfg(feature = "redis")]
use redis_derive::{FromRedisValue, ToRedisArgs};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AuthResponse {
pub token: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct SupplyResponse {
pub result: String,
}
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub struct ChatSendMessageResponse {
pub status: String,
pub message: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct User {
pub authority: String,
pub username: String,
pub profile_photo_url: Option<String>,
pub discord_user: Option<DiscordUser>,
pub updated_at: NaiveDateTime,
pub risk_score: i64,
pub is_banned: bool,
pub role: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "redis", derive(FromRedisValue, ToRedisArgs))]
pub struct ChatNotification {
pub authority: String,
pub username: String,
pub text: String,
pub id: u64,
pub ts: i64,
pub profile_photo_url: Option<String>,
pub role: Option<String>,
pub discord_user_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reply_to_id: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reply_to_text: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reply_to_username: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reactions: Option<ChatReactions>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "redis", derive(FromRedisValue, ToRedisArgs))]
pub struct ChatReactions {
#[serde(default, skip_serializing_if = "is_zero")]
pub thumbs_up: u32, #[serde(default, skip_serializing_if = "is_zero")]
pub heart: u32, #[serde(default, skip_serializing_if = "is_zero")]
pub laughing: u32, #[serde(default, skip_serializing_if = "is_zero")]
pub surprised: u32, #[serde(default, skip_serializing_if = "is_zero")]
pub sad: u32, #[serde(default, skip_serializing_if = "is_zero")]
pub fire: u32, }
fn is_zero(n: &u32) -> bool {
*n == 0
}
impl ChatReactions {
pub fn is_empty(&self) -> bool {
self.thumbs_up == 0
&& self.heart == 0
&& self.laughing == 0
&& self.surprised == 0
&& self.sad == 0
&& self.fire == 0
}
pub fn get(&self, emoji: &str) -> u32 {
match emoji {
"👍" => self.thumbs_up,
"❤️" | "❤" => self.heart,
"😂" => self.laughing,
"😮" => self.surprised,
"😢" => self.sad,
"🔥" => self.fire,
_ => 0,
}
}
pub fn set(&mut self, emoji: &str, count: u32) {
match emoji {
"👍" => self.thumbs_up = count,
"❤️" | "❤" => self.heart = count,
"😂" => self.laughing = count,
"😮" => self.surprised = count,
"😢" => self.sad = count,
"🔥" => self.fire = count,
_ => {}
}
}
}
pub const ALLOWED_REACTION_EMOJI: [&str; 6] = ["👍", "❤️", "😂", "😮", "😢", "🔥"];
pub fn is_valid_reaction_emoji(emoji: &str) -> bool {
if emoji == "❤" {
return true;
}
ALLOWED_REACTION_EMOJI.contains(&emoji)
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ResetNotification {
pub block_id: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "redis", derive(FromRedisValue, ToRedisArgs))]
pub struct DeployNotification {
pub authority: String,
pub amount: u64,
pub mask: u64,
pub round_id: u64,
pub signer: String,
pub strategy: u64,
pub total_squares: u64,
pub ts: i64,
pub sig: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ReactionNotification {
pub message_id: u64,
pub emoji: String,
pub count: u32,
pub action: String, }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct TypingUser {
pub authority: String,
pub username: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct TypingNotification {
pub users: Vec<TypingUser>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum Notification {
Chat(ChatNotification),
ChatBatch(Vec<ChatNotification>),
Reset(ResetNotification),
Deploy(DeployNotification),
Reaction(ReactionNotification),
Typing(TypingNotification),
}
impl Notification {
pub fn id(&self) -> String {
match self {
Notification::Chat(chat) => chat.id.to_string(),
Notification::ChatBatch(_) => "chat_batch".to_string(),
Notification::Reset(reset) => reset.block_id.to_string(),
Notification::Deploy(deploy) => deploy.sig.clone(),
Notification::Reaction(reaction) => {
format!("{}:{}", reaction.message_id, reaction.emoji)
}
Notification::Typing(_) => "typing".to_string(),
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ChatReactResponse {
pub status: String,
pub action: String, pub message_id: u64,
pub emoji: String,
pub count: u32, }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ChatTypingResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ChatHistoryResponse {
pub messages: Vec<ChatNotification>,
pub has_more: bool,
pub oldest_id: Option<u64>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct DailyRevenue {
pub day: String,
pub revenue: i64,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct UsernameValidationResponse {
pub valid: bool,
pub error: Option<String>,
}
impl UsernameValidationResponse {
pub fn valid() -> Self {
Self {
valid: true,
error: None,
}
}
pub fn invalid(error: String) -> Self {
Self {
valid: false,
error: Some(error),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DiscordAuthResponse {
pub access_token: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GoogleUser {
pub email: String,
pub name: String,
pub picture: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GoogleAuthResponse {
pub jwt: String,
pub user: GoogleUser,
}
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
pub struct DiscordUser {
pub id: String,
pub username: String,
pub discriminator: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub global_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub avatar: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub verified: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OreBalance {
pub wallet: u64,
pub staked: u64,
pub unrefined: u64,
pub refined: u64,
pub lifetime_deployed_sol: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct LeaderboardEntry {
pub authority: String,
pub amount: u64,
pub username: Option<String>,
pub profile_picture_url: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ResetEventResponse {
pub disc: u8,
pub round_id: u64,
pub start_slot: u64,
pub end_slot: u64,
pub winning_square: u64,
pub top_miner: Pubkey,
pub num_winners: u64,
pub motherlode: u64,
pub total_deployed: u64,
pub total_vaulted: u64,
pub total_winnings: u64,
pub total_minted: u64,
pub ts: i64,
pub rng: u64,
pub deployed_winning_square: u64,
pub top_miner_username: Option<String>,
pub top_miner_profile_photo: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct DeployHistoryEvent {
pub sig: String,
pub authority: String,
pub signer: String,
pub amount: u64,
pub mask: i64,
pub round_id: i64,
pub total_squares: i64,
pub ts: i64,
pub winning_square: i64,
pub top_miner: String,
pub rewards_sol: u64,
pub rewards_ore: u64,
pub total_winnings_sol: u64,
pub deployed_winning_square: u64,
pub motherlode: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct RoundWinner {
pub authority: String,
pub username: Option<String>,
pub profile_photo_url: Option<String>,
pub deployed_on_winning: u64,
pub combined_mask: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct RoundWinnersResponse {
pub round_id: u64,
pub winning_square: u64,
pub total_on_winning: u64,
pub total_winnings: u64,
pub winners: Vec<RoundWinner>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct RoundMiner {
pub authority: String,
pub username: Option<String>,
pub profile_photo_url: Option<String>,
pub total_deployed: u64,
pub combined_mask: u64,
pub rewards: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct RoundMinersResponse {
pub round_id: u64,
pub miners: Vec<RoundMiner>,
#[serde(skip_serializing_if = "Option::is_none")]
pub authority: Option<RoundMiner>,
#[serde(skip_serializing_if = "Option::is_none")]
pub authority_rank: Option<u64>,
}