#![doc = include_str!("README.md")]
#[cfg(feature = "http")]
pub mod client;
#[cfg(feature = "native-auth")]
pub mod native;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::shared::PubkeyStr;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub id: String,
pub wallet_address: String,
pub linked_account: LinkedAccount,
pub privy_id: Option<String>,
pub embedded_wallet: Option<EmbeddedWallet>,
pub x_username: Option<String>,
pub x_user_id: Option<String>,
pub x_display_name: Option<String>,
pub google_email: Option<String>,
pub auth_method: AuthMethod,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AuthMethod {
Privy,
Lightcone,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LinkedAccount {
pub id: String,
#[serde(rename = "type")]
pub account_type: LinkedAccountType,
pub chain: Option<ChainType>,
pub address: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum LinkedAccountType {
Wallet,
TwitterOauth,
GoogleOauth,
}
impl LinkedAccountType {
pub fn as_str(&self) -> &'static str {
match self {
Self::Wallet => "wallet",
Self::TwitterOauth => "twitter_oauth",
Self::GoogleOauth => "google_oauth",
}
}
pub fn text(&self) -> &'static str {
match self {
Self::Wallet => "Solana",
Self::TwitterOauth => "X",
Self::GoogleOauth => "Google",
}
}
}
impl std::fmt::Display for LinkedAccountType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct EmbeddedWallet {
pub privy_id: String,
pub chain: ChainType,
pub address: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ChainType {
Solana,
Ethereum,
}
impl ChainType {
pub fn as_str(&self) -> &'static str {
match self {
Self::Solana => "solana",
Self::Ethereum => "ethereum",
}
}
}
impl std::fmt::Display for ChainType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthCredentials {
pub user_id: String,
pub wallet_address: PubkeyStr,
pub expires_at: DateTime<Utc>,
}
impl AuthCredentials {
pub fn is_authenticated(&self) -> bool {
Utc::now() < self.expires_at
}
}
pub fn generate_signin_message(nonce: &str) -> Vec<u8> {
let message = format!("Sign in to Lightcone\nNonce: {}", nonce);
message.into_bytes()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoginRequest {
pub message: String,
pub signature_bs58: String,
pub pubkey_bytes: Vec<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub use_embedded_wallet: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoginResponse {
pub user_id: String,
pub wallet_address: String,
pub expires_at: i64,
pub linked_account: LinkedAccount,
pub privy_id: Option<String>,
pub embedded_wallet: Option<EmbeddedWallet>,
pub x_username: Option<String>,
pub x_user_id: Option<String>,
pub x_display_name: Option<String>,
pub google_email: Option<String>,
pub auth_method: AuthMethod,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MeResponse {
pub user_id: String,
pub wallet_address: String,
pub linked_account: LinkedAccount,
pub privy_id: Option<String>,
pub embedded_wallet: Option<EmbeddedWallet>,
pub x_username: Option<String>,
pub x_user_id: Option<String>,
pub x_display_name: Option<String>,
pub google_email: Option<String>,
pub expires_at: i64,
pub auth_method: AuthMethod,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NonceResponse {
pub nonce: String,
}