#![warn(missing_debug_implementations)]
#![warn(rust_2018_idioms)]
mod client;
pub mod api;
pub mod error;
pub mod types;
use std::sync::Arc;
use crate::api::{
alpha_wallets::AlphaWallets, deployer_hunter::DeployerHunter, kol::Kol, stream::Stream,
tokens::Tokens, trades::Trades,
};
use crate::client::HttpCore;
use crate::error::{Result, RobinhoodChainError};
pub use crate::error::RobinhoodChainError as Error;
#[derive(Debug, Clone)]
pub struct RobinhoodChain {
pub kol: Kol,
pub trades: Trades,
pub tokens: Tokens,
pub deployer_hunter: DeployerHunter,
pub alpha_wallets: AlphaWallets,
pub stream: Stream,
}
impl RobinhoodChain {
pub fn new(api_key: impl Into<String>) -> Result<Self> {
let api_key = api_key.into();
if !api_key.starts_with("msk_") {
eprintln!(
"\n[robinhood-chain] Missing or invalid API key.\n\
→ Get a free key at https://madeonsol.com/developer (RHC bundled into every tier)\n\
→ Then: robinhood_chain::RobinhoodChain::new(std::env::var(\"MADEONSOL_API_KEY\")?)?\n"
);
return Err(RobinhoodChainError::MissingApiKey);
}
let core = Arc::new(HttpCore::new(api_key));
Ok(Self {
kol: Kol { core: Arc::clone(&core) },
trades: Trades { core: Arc::clone(&core) },
tokens: Tokens { core: Arc::clone(&core) },
deployer_hunter: DeployerHunter { core: Arc::clone(&core) },
alpha_wallets: AlphaWallets { core: Arc::clone(&core) },
stream: Stream { core },
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rejects_missing_api_key() {
let err = RobinhoodChain::new("").unwrap_err();
assert!(matches!(err, RobinhoodChainError::MissingApiKey));
}
#[test]
fn rejects_wrong_prefix() {
let err = RobinhoodChain::new("sk_live_abc").unwrap_err();
assert!(matches!(err, RobinhoodChainError::MissingApiKey));
}
#[test]
fn accepts_valid_prefix() {
let client = RobinhoodChain::new("msk_test_abcdef").unwrap();
let _cloned = client.clone();
}
}