scope/lib.rs
1//! # Scope Blockchain Analysis
2//!
3//! A command-line tool and library for blockchain data analysis,
4//! address book management, 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//! - **Address Book**: Track multiple addresses (wallets, contracts) 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//! - **Unified Insights**: Auto-detect addresses, transaction hashes, or tokens
40//! and run the appropriate analyses (`scope insights`).
41//!
42//! - **Compliance & Risk**: Risk scoring, transaction pattern detection, taint
43//! analysis, and compliance reporting (`scope compliance`).
44//!
45//! - **Shell Completion**: Tab-completion for bash, zsh, and fish
46//! (`scope completions <shell>`).
47//!
48//! - **Progress Indicators**: Spinners and progress bars for all long-running
49//! operations. Non-TTY aware (hidden in pipes).
50//!
51//! - **Error Remediation**: Actionable hints for common errors (invalid address,
52//! missing config, network failures, auth issues).
53//!
54//! - **USD Valuation**: Native token prices via DexScreener for all supported
55//! chains (ETH, SOL, BNB, MATIC, etc.).
56//!
57//! ## Supported Chains
58//!
59//! ### EVM-Compatible
60//!
61//! - Ethereum Mainnet
62//! - Polygon
63//! - Arbitrum
64//! - Optimism
65//! - Base
66//! - BSC (BNB Smart Chain)
67//!
68//! ### Non-EVM
69//!
70//! - Solana
71//! - Tron
72//!
73//! ## Quick Start (CLI)
74//!
75//! ```bash
76//! # Analyze an address
77//! scope address 0x742d35Cc6634C0532925a3b844Bc9e7595f1b3c2
78//!
79//! # Analyze a transaction
80//! scope tx 0xabc123...
81//!
82//! # Auto-detect and analyze any target
83//! scope insights 0xabc123...
84//!
85//! # Token DEX data
86//! scope crawl USDC --chain ethereum
87//!
88//! # Manage address book
89//! scope address-book add 0x742d... --label "Main Wallet"
90//! scope address-book list
91//!
92//! # Export data
93//! scope export --address 0x742d... --output history.json
94//!
95//! # Shell tab-completion
96//! scope completions zsh > ~/.zfunc/_scope
97//! ```
98//!
99//! ## Library Usage
100//!
101//! The Scope library can be used programmatically in your Rust applications:
102//!
103//! ```rust,no_run
104//! use scope::{Config, chains::EthereumClient};
105//!
106//! #[tokio::main]
107//! async fn main() -> scope::Result<()> {
108//! // Load configuration
109//! let config = Config::load(None)?;
110//!
111//! // Create a chain client
112//! let client = EthereumClient::new(&config.chains)?;
113//!
114//! // Query an address balance (with USD valuation)
115//! let mut balance = client.get_balance("0x742d35Cc6634C0532925a3b844Bc9e7595f1b3c2").await?;
116//! client.enrich_balance_usd(&mut balance).await;
117//! println!("Balance: {} (${:.2})", balance.formatted, balance.usd_value.unwrap_or(0.0));
118//!
119//! // Look up a transaction
120//! let tx = client.get_transaction("0xabc123...").await?;
121//! println!("From: {}, Status: {:?}", tx.from, tx.status);
122//!
123//! // Fetch ERC-20 token balances
124//! let tokens = client.get_erc20_balances("0x742d35Cc6634C0532925a3b844Bc9e7595f1b3c2").await?;
125//! for token in &tokens {
126//! println!("{}: {}", token.token.symbol, token.formatted_balance);
127//! }
128//!
129//! Ok(())
130//! }
131//! ```
132//!
133//! ## Configuration
134//!
135//! Scope reads configuration from `~/.config/scope/config.yaml`:
136//!
137//! ```yaml
138//! chains:
139//! # EVM chains
140//! ethereum_rpc: "https://mainnet.infura.io/v3/YOUR_KEY"
141//! bsc_rpc: "https://bsc-dataseed.binance.org"
142//!
143//! # Non-EVM chains
144//! solana_rpc: "https://api.mainnet-beta.solana.com"
145//! tron_api: "https://api.trongrid.io"
146//!
147//! api_keys:
148//! etherscan: "YOUR_ETHERSCAN_KEY"
149//! polygonscan: "YOUR_POLYGONSCAN_KEY"
150//! bscscan: "YOUR_BSCSCAN_KEY"
151//! solscan: "YOUR_SOLSCAN_KEY"
152//! tronscan: "YOUR_TRONSCAN_KEY"
153//!
154//! output:
155//! format: table # table, json, csv, markdown
156//! color: true
157//!
158//! address_book:
159//! data_dir: "~/.local/share/scope"
160//! ```
161//!
162//! ## Error Handling
163//!
164//! All fallible operations return [`Result<T>`], which uses [`ScopeError`]
165//! as the error type. This provides detailed error context for debugging
166//! and user-friendly error messages.
167//!
168//! ```rust
169//! use scope::{ScopeError, Result};
170//!
171//! fn validate_address(addr: &str) -> Result<()> {
172//! if !addr.starts_with("0x") || addr.len() != 42 {
173//! return Err(ScopeError::InvalidAddress(addr.to_string()));
174//! }
175//! Ok(())
176//! }
177//! ```
178//!
179//! ## Modules
180//!
181//! - [`chains`]: Blockchain client implementations (Ethereum/EVM, Solana, Tron, DexScreener)
182//! - [`cli`]: Command-line interface definitions (address, tx, crawl, monitor, market, address-book, export)
183//! - [`config`]: Configuration management
184//! - [`market`]: Peg and order book health for stablecoin markets
185//! - [`display`]: Terminal output utilities and markdown report generation
186//! - [`error`]: Error types and result aliases
187//! - [`tokens`]: Token alias storage for friendly name lookups
188
189// Re-export commonly used types at crate root
190pub use config::Config;
191pub use error::{ConfigError, Result, ScopeError};
192
193/// Blockchain client implementations.
194///
195/// Provides abstractions and concrete clients for interacting with
196/// blockchain networks. See `ChainClient` for the common
197/// interface and `EthereumClient` for EVM chain support.
198pub mod chains;
199
200/// Command-line interface definitions.
201///
202/// Contains argument structures and command handlers for the Scope CLI.
203/// This module is primarily used by the binary crate but is exposed
204/// for programmatic CLI invocation. It provides the main `Cli` struct
205/// and `Commands` enum that define all available commands.
206pub mod cli;
207
208/// Configuration management.
209///
210/// Handles loading, merging, and validation of configuration from
211/// multiple sources (CLI args, environment variables, config files).
212pub mod config;
213
214/// Display utilities for terminal output and reports.
215///
216/// Provides ASCII chart rendering and markdown report generation
217/// for token analytics data.
218pub mod display;
219
220/// Error types and result aliases.
221///
222/// Defines [`ScopeError`] for all error conditions and provides a
223/// convenient [`Result`] type alias.
224pub mod error;
225
226/// Token alias storage for saving token lookups.
227///
228/// Allows users to reference tokens by friendly names instead
229/// of full contract addresses.
230pub mod tokens;
231
232/// Compliance and risk analysis module.
233///
234/// Provides risk scoring, transaction taint analysis, pattern detection,
235/// and compliance reporting for blockchain addresses.
236pub mod compliance;
237
238/// Market module for peg and order book health analysis.
239///
240/// Fetches level-2 order book data from exchange APIs and runs
241/// configurable health checks for stablecoin markets.
242pub mod market;
243
244/// Web server module for browser-based UI.
245///
246/// Provides a locally hosted HTTP server with REST API endpoints
247/// and a web UI that mirrors all CLI functionality. Supports
248/// foreground and daemon modes.
249pub mod web;
250
251/// Library version string.
252pub const VERSION: &str = env!("CARGO_PKG_VERSION");
253
254/// Returns the library version.
255///
256/// # Examples
257///
258/// ```rust
259/// let version = scope::version();
260/// println!("Scope version: {}", version);
261/// ```
262pub fn version() -> &'static str {
263 VERSION
264}
265
266// ============================================================================
267// Integration Tests for Library API
268// ============================================================================
269
270#[cfg(test)]
271mod tests {
272 use super::*;
273
274 #[test]
275 fn test_version_not_empty() {
276 assert!(!version().is_empty());
277 }
278
279 #[test]
280 fn test_version_format() {
281 // Version should be semver-like (X.Y.Z)
282 let v = version();
283 let parts: Vec<&str> = v.split('.').collect();
284 assert!(parts.len() >= 2, "Version should have at least major.minor");
285 }
286
287 #[test]
288 fn test_config_reexport() {
289 // Verify Config is accessible from crate root
290 let config = Config::default();
291 assert!(config.chains.api_keys.is_empty());
292 }
293
294 #[test]
295 fn test_error_reexport() {
296 // Verify error types are accessible from crate root
297 let err = ScopeError::InvalidAddress("test".to_string());
298 assert!(err.to_string().contains("test"));
299 }
300
301 #[test]
302 fn test_result_type_alias() {
303 fn test_fn() -> Result<i32> {
304 Ok(42)
305 }
306 assert_eq!(test_fn().unwrap(), 42);
307 }
308
309 #[test]
310 fn test_config_error_reexport() {
311 use std::path::PathBuf;
312 let err = ConfigError::NotFound {
313 path: PathBuf::from("/test"),
314 };
315 assert!(err.to_string().contains("/test"));
316 }
317}