scope/compliance/
etherscan.rs1use super::datasource::BlockchainDataClient;
7use super::risk::RiskEngine;
8
9pub const ETHERSCAN_KEY_ENV: &str = "ETHERSCAN_API_KEY";
11
12pub fn etherscan_key() -> Option<String> {
17 let configured = || {
18 crate::config::Config::load(None)
19 .ok()
20 .and_then(|c| c.chains.api_keys.get("etherscan").cloned())
21 };
22 key_from(std::env::var(ETHERSCAN_KEY_ENV).ok(), configured)
23}
24
25fn key_from(env: Option<String>, configured: impl FnOnce() -> Option<String>) -> Option<String> {
27 env.filter(|k| !k.trim().is_empty())
28 .or_else(configured)
29 .filter(|k| !k.trim().is_empty())
30}
31
32impl RiskEngine {
33 pub fn with_optional_client(client: Option<BlockchainDataClient>) -> Self {
36 match client {
37 Some(c) => Self::with_data_client(c),
38 None => Self::new(),
39 }
40 }
41
42 #[deprecated(
44 since = "0.8.0",
45 note = "pass the transport: use `RiskEngine::from_env_with_http`"
46 )]
47 pub fn from_env() -> Self {
48 Self::from_env_with_http(crate::http::shared::fallback())
49 }
50
51 pub fn from_env_with_http(http: std::sync::Arc<dyn crate::http::HttpClient>) -> Self {
53 Self::with_optional_client(BlockchainDataClient::from_env_opt_with_http(http))
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::compliance::datasource::DataSources;
61
62 #[test]
63 fn test_optional_client_picks_the_engine() {
64 let _basic = RiskEngine::with_optional_client(None);
66 let client = BlockchainDataClient::new_with_http(
67 DataSources::new("k".to_string()),
68 crate::http::test_transport(),
69 );
70 let _rich = RiskEngine::with_optional_client(Some(client));
71 assert_eq!(ETHERSCAN_KEY_ENV, "ETHERSCAN_API_KEY");
72 }
73
74 #[test]
75 fn test_the_variable_wins_and_the_config_key_is_the_fallback() {
76 let config = || Some("from-config".to_string());
77 assert_eq!(
78 key_from(Some("from-env".into()), config).as_deref(),
79 Some("from-env")
80 );
81 assert_eq!(key_from(None, config).as_deref(), Some("from-config"));
83 assert_eq!(
85 key_from(Some(" ".into()), config).as_deref(),
86 Some("from-config")
87 );
88 assert_eq!(key_from(None, || Some(String::new())), None);
89 }
90}