Skip to main content

mrls/
lib.rs

1//! # mrls - Moralis Web3 API Client
2//!
3//! A comprehensive Rust client for the [Moralis Web3 API](https://docs.moralis.io/).
4//!
5//! ## Features
6//!
7//! - **Wallet API** - Native balances, token balances, transactions, approvals, net worth, profitability
8//! - **Token API** - Metadata, prices, transfers, swaps, pairs, holders, stats, trending
9//! - **NFT API** - NFT metadata, transfers, owners, trades, floor prices, collections
10//! - **`DeFi` API** - Pair prices, reserves, positions, protocol summaries
11//! - **Block API** - Block data, timestamps, date-to-block lookups
12//! - **Transaction API** - Transaction details, decoded calls, internal transactions
13//! - **Resolve API** - ENS, Unstoppable Domains, domain resolution
14//! - **Market Data API** - Top tokens, movers, NFT collections, global stats
15//! - **Discovery API** - Token discovery, trending, analytics, scores
16//! - **Entities API** - Wallet/protocol/exchange labels and categories
17//!
18//! ## Quick Start
19//!
20//! ```no_run
21//! use mrls::Client;
22//!
23//! #[tokio::main]
24//! async fn main() -> Result<(), mrls::Error> {
25//!     // Create client from MORALIS_API_KEY env var
26//!     let client = Client::from_env()?;
27//!
28//!     // Get native balance
29//!     let balance = client.wallet().get_native_balance(
30//!         "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
31//!         Some("eth"),
32//!     ).await?;
33//!     println!("Balance: {} wei", balance.balance);
34//!
35//!     // Get token price
36//!     let price = client.token().get_price(
37//!         "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
38//!         Some("eth"),
39//!     ).await?;
40//!     println!("WETH Price: ${:?}", price.usd_price);
41//!
42//!     Ok(())
43//! }
44//! ```
45//!
46//! ## Error Handling
47//!
48//! The client provides specific error types for common API errors:
49//!
50//! ```no_run
51//! use mrls::{Client, Error};
52//! use mrls::error::DomainError;
53//!
54//! #[tokio::main]
55//! async fn main() {
56//!     let client = Client::from_env().unwrap();
57//!
58//!     // Premium endpoints require Starter or Pro plan
59//!     match client.discovery().get_token_score("0x...", Some("eth")).await {
60//!         Ok(score) => println!("Token score: {:?}", score),
61//!         Err(Error::Domain(DomainError::PlanRequired { required_plan, message })) => {
62//!             println!("Upgrade to {} plan: {}", required_plan, message);
63//!         }
64//!         Err(Error::RateLimited { retry_after, .. }) => {
65//!             println!("Rate limited, retry after {:?}", retry_after);
66//!         }
67//!         Err(Error::Domain(DomainError::Unauthorized)) => {
68//!             println!("Invalid API key");
69//!         }
70//!         Err(e) => println!("Other error: {}", e),
71//!     }
72//! }
73//! ```
74//!
75//! ### Plan Tiers
76//!
77//! Some endpoints require specific plan tiers:
78//!
79//! | Tier | Endpoints |
80//! |------|-----------|
81//! | **Free** | Most basic endpoints |
82//! | **Starter** | `get_token_score` |
83//! | **Pro** | Volume stats, token discovery, analytics, search |
84//!
85//! ## Automatic Retries
86//!
87//! Use the retry utilities for resilient API calls:
88//!
89//! ```no_run
90//! use mrls::{Client, with_retry, RetryConfig};
91//!
92//! #[tokio::main]
93//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
94//!     let client = Client::from_env()?;
95//!     let config = RetryConfig::default(); // 3 retries with exponential backoff
96//!
97//!     let result = with_retry(&config, || async {
98//!         client.wallet().get_native_balance(
99//!             "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
100//!             Some("eth"),
101//!         ).await
102//!     }).await?;
103//!
104//!     println!("Balance: {}", result.balance);
105//!     Ok(())
106//! }
107//! ```
108//!
109//! Preset configurations:
110//! - `RetryConfig::default()` - 3 retries, 100ms initial delay
111//! - `RetryConfig::quick()` - 2 retries, 50ms initial delay (interactive)
112//! - `RetryConfig::batch()` - 5 retries, 200ms initial delay (batch jobs)
113//! - `RetryConfig::none()` - No retries
114
115mod client;
116pub mod error;
117
118// API modules
119pub mod analytics;
120pub mod block;
121pub mod defi;
122pub mod discovery;
123pub mod entities;
124pub mod market;
125pub mod nft;
126pub mod resolve;
127pub mod token;
128pub mod transaction;
129pub mod utils;
130pub mod volume;
131pub mod wallet;
132
133// Re-exports
134pub use client::{Client, Config};
135pub use error::{Error, PlanTier};
136pub use yldfi_common::http::HttpClientConfig;
137pub use yldfi_common::{with_retry, with_simple_retry, RetryConfig, RetryError, RetryableError};
138
139/// Default base URL for the Moralis API
140pub const DEFAULT_BASE_URL: &str = "https://deep-index.moralis.io/api/v2.2";
141
142/// Create a config with an API key
143#[must_use]
144pub fn config_with_api_key(api_key: impl Into<String>) -> Config {
145    Config::new(api_key)
146}
147
148// API re-exports
149pub use analytics::{AnalyticsApi, AnalyticsQuery};
150pub use block::{BlockApi, BlockQuery};
151pub use defi::{DefiApi, DefiQuery};
152pub use discovery::{DiscoveryApi, DiscoveryQuery};
153pub use entities::{EntitiesApi, EntityQuery};
154pub use market::{MarketApi, MarketQuery};
155pub use nft::{NftApi, NftQuery};
156pub use resolve::ResolveApi;
157pub use token::TokenApi;
158pub use transaction::{TransactionApi, TransactionQuery};
159pub use utils::{UtilsApi, UtilsQuery};
160pub use volume::{VolumeApi, VolumeQuery};
161pub use wallet::{WalletApi, WalletQuery};
162
163/// Result type alias for this crate
164pub type Result<T> = std::result::Result<T, Error>;