Skip to main content

scope/
lib.rs

1//! # Scope Blockchain Analysis
2//!
3//! A command-line tool and library for blockchain data analysis,
4//! portfolio tracking, and transaction investigation.
5//!
6//! ## Features
7//!
8//! - **Address Analysis**: Query balances (with USD valuation), transaction history,
9//!   and token holdings (ERC-20, SPL, TRC-20) for blockchain addresses across
10//!   multiple chains. Chain auto-detection from address format.
11//!
12//! - **Transaction Analysis**: Look up and decode blockchain transactions across
13//!   EVM chains (via Etherscan proxy API), Solana (via `getTransaction` RPC),
14//!   and Tron (via TronGrid). Includes receipt data, gas usage, and status.
15//!
16//! - **Token Crawling**: Crawl DEX data for any token with price, volume,
17//!   liquidity, holder analysis, and risk scoring. Markdown report generation.
18//!
19//! - **Token Discovery**: Browse trending and boosted tokens from DexScreener
20//!   (`scope discover`) — featured profiles, recent boosts, top boosts. No API key.
21//!
22//! - **Live Monitoring**: Real-time TUI dashboard with price/volume/candlestick
23//!   charts, buy/sell gauges, activity logs, and Unicode-rich visualization.
24//!
25//! - **Portfolio Management**: Track multiple addresses across chains with
26//!   labels, tags, and aggregated balance views including ERC-20, SPL, and
27//!   TRC-20 token balances.
28//!
29//! - **Data Export**: Export transaction history in JSON or CSV with date range
30//!   filtering. Chain auto-detection for addresses.
31//!
32//! - **Market Health**: Peg and order book health for stablecoin markets. Fetches
33//!   level-2 depth from Binance, Biconomy, or DEX liquidity (Ethereum/Solana via DexScreener).
34//!   Configurable health checks (peg safety, bid/ask ratio, depth thresholds).
35//!
36//! - **Token Health Suite**: Composite command (`scope token-health`) combining DEX analytics
37//!   with optional market/order book summary. Venues: binance, biconomy, eth, solana.
38//!
39//! - **USD Valuation**: Native token prices via DexScreener for all supported
40//!   chains (ETH, SOL, BNB, MATIC, etc.).
41//!
42//! ## Supported Chains
43//!
44//! ### EVM-Compatible
45//!
46//! - Ethereum Mainnet
47//! - Polygon
48//! - Arbitrum
49//! - Optimism
50//! - Base
51//! - BSC (BNB Smart Chain)
52//!
53//! ### Non-EVM
54//!
55//! - Solana
56//! - Tron
57//!
58//! ## Quick Start (CLI)
59//!
60//! ```bash
61//! # Analyze an address
62//! scope address 0x742d35Cc6634C0532925a3b844Bc9e7595f1b3c2
63//!
64//! # Analyze a transaction
65//! scope tx 0xabc123...
66//!
67//! # Manage portfolio
68//! scope portfolio add 0x742d... --label "Main Wallet"
69//! scope portfolio list
70//!
71//! # Export data
72//! scope export --address 0x742d... --output history.json
73//! ```
74//!
75//! ## Library Usage
76//!
77//! The Scope library can be used programmatically in your Rust applications:
78//!
79//! ```rust,no_run
80//! use scope::{Config, chains::EthereumClient};
81//!
82//! #[tokio::main]
83//! async fn main() -> scope::Result<()> {
84//!     // Load configuration
85//!     let config = Config::load(None)?;
86//!     
87//!     // Create a chain client
88//!     let client = EthereumClient::new(&config.chains)?;
89//!     
90//!     // Query an address balance (with USD valuation)
91//!     let mut balance = client.get_balance("0x742d35Cc6634C0532925a3b844Bc9e7595f1b3c2").await?;
92//!     client.enrich_balance_usd(&mut balance).await;
93//!     println!("Balance: {} (${:.2})", balance.formatted, balance.usd_value.unwrap_or(0.0));
94//!     
95//!     // Look up a transaction
96//!     let tx = client.get_transaction("0xabc123...").await?;
97//!     println!("From: {}, Status: {:?}", tx.from, tx.status);
98//!     
99//!     // Fetch ERC-20 token balances
100//!     let tokens = client.get_erc20_balances("0x742d35Cc6634C0532925a3b844Bc9e7595f1b3c2").await?;
101//!     for token in &tokens {
102//!         println!("{}: {}", token.token.symbol, token.formatted_balance);
103//!     }
104//!     
105//!     Ok(())
106//! }
107//! ```
108//!
109//! ## Configuration
110//!
111//! Scope reads configuration from `~/.config/scope/config.yaml`:
112//!
113//! ```yaml
114//! chains:
115//!   # EVM chains
116//!   ethereum_rpc: "https://mainnet.infura.io/v3/YOUR_KEY"
117//!   bsc_rpc: "https://bsc-dataseed.binance.org"
118//!
119//!   # Non-EVM chains
120//!   solana_rpc: "https://api.mainnet-beta.solana.com"
121//!   tron_api: "https://api.trongrid.io"
122//!
123//!   api_keys:
124//!     etherscan: "YOUR_ETHERSCAN_KEY"
125//!     polygonscan: "YOUR_POLYGONSCAN_KEY"
126//!     bscscan: "YOUR_BSCSCAN_KEY"
127//!     solscan: "YOUR_SOLSCAN_KEY"
128//!     tronscan: "YOUR_TRONSCAN_KEY"
129//!
130//! output:
131//!   format: table  # table, json, csv, markdown
132//!   color: true
133//!
134//! portfolio:
135//!   data_dir: "~/.local/share/scope"
136//! ```
137//!
138//! ## Error Handling
139//!
140//! All fallible operations return [`Result<T>`], which uses [`ScopeError`]
141//! as the error type. This provides detailed error context for debugging
142//! and user-friendly error messages.
143//!
144//! ```rust
145//! use scope::{ScopeError, Result};
146//!
147//! fn validate_address(addr: &str) -> Result<()> {
148//!     if !addr.starts_with("0x") || addr.len() != 42 {
149//!         return Err(ScopeError::InvalidAddress(addr.to_string()));
150//!     }
151//!     Ok(())
152//! }
153//! ```
154//!
155//! ## Modules
156//!
157//! - [`chains`]: Blockchain client implementations (Ethereum/EVM, Solana, Tron, DexScreener)
158//! - [`cli`]: Command-line interface definitions (address, tx, crawl, monitor, market, portfolio, export)
159//! - [`config`]: Configuration management
160//! - [`market`]: Peg and order book health for stablecoin markets
161//! - [`display`]: Terminal output utilities and markdown report generation
162//! - [`error`]: Error types and result aliases
163//! - [`tokens`]: Token alias storage for friendly name lookups
164
165// Re-export commonly used types at crate root
166pub use config::Config;
167pub use error::{ConfigError, Result, ScopeError};
168
169/// Blockchain client implementations.
170///
171/// Provides abstractions and concrete clients for interacting with
172/// blockchain networks. See `ChainClient` for the common
173/// interface and `EthereumClient` for EVM chain support.
174pub mod chains;
175
176/// Command-line interface definitions.
177///
178/// Contains argument structures and command handlers for the Scope CLI.
179/// This module is primarily used by the binary crate but is exposed
180/// for programmatic CLI invocation. It provides the main `Cli` struct
181/// and `Commands` enum that define all available commands.
182pub mod cli;
183
184/// Configuration management.
185///
186/// Handles loading, merging, and validation of configuration from
187/// multiple sources (CLI args, environment variables, config files).
188pub mod config;
189
190/// Display utilities for terminal output and reports.
191///
192/// Provides ASCII chart rendering and markdown report generation
193/// for token analytics data.
194pub mod display;
195
196/// Error types and result aliases.
197///
198/// Defines [`ScopeError`] for all error conditions and provides a
199/// convenient [`Result`] type alias.
200pub mod error;
201
202/// Token alias storage for saving token lookups.
203///
204/// Allows users to reference tokens by friendly names instead
205/// of full contract addresses.
206pub mod tokens;
207
208/// Compliance and risk analysis module.
209///
210/// Provides risk scoring, transaction taint analysis, pattern detection,
211/// and compliance reporting for blockchain addresses.
212pub mod compliance;
213
214/// Market module for peg and order book health analysis.
215///
216/// Fetches level-2 order book data from exchange APIs and runs
217/// configurable health checks for stablecoin markets.
218pub mod market;
219
220/// Library version string.
221pub const VERSION: &str = env!("CARGO_PKG_VERSION");
222
223/// Returns the library version.
224///
225/// # Examples
226///
227/// ```rust
228/// let version = scope::version();
229/// println!("Scope version: {}", version);
230/// ```
231pub fn version() -> &'static str {
232    VERSION
233}
234
235// ============================================================================
236// Integration Tests for Library API
237// ============================================================================
238
239#[cfg(test)]
240mod tests {
241    use super::*;
242
243    #[test]
244    fn test_version_not_empty() {
245        assert!(!version().is_empty());
246    }
247
248    #[test]
249    fn test_version_format() {
250        // Version should be semver-like (X.Y.Z)
251        let v = version();
252        let parts: Vec<&str> = v.split('.').collect();
253        assert!(parts.len() >= 2, "Version should have at least major.minor");
254    }
255
256    #[test]
257    fn test_config_reexport() {
258        // Verify Config is accessible from crate root
259        let config = Config::default();
260        assert!(config.chains.api_keys.is_empty());
261    }
262
263    #[test]
264    fn test_error_reexport() {
265        // Verify error types are accessible from crate root
266        let err = ScopeError::InvalidAddress("test".to_string());
267        assert!(err.to_string().contains("test"));
268    }
269
270    #[test]
271    fn test_result_type_alias() {
272        fn test_fn() -> Result<i32> {
273            Ok(42)
274        }
275        assert_eq!(test_fn().unwrap(), 42);
276    }
277
278    #[test]
279    fn test_config_error_reexport() {
280        use std::path::PathBuf;
281        let err = ConfigError::NotFound {
282            path: PathBuf::from("/test"),
283        };
284        assert!(err.to_string().contains("/test"));
285    }
286}