mutant_lib/lib.rs
1//! # MutAnt
2//!
3//! MutAnt is a decentralized P2P mutable key-value storage system built on the Autonomi network, offering resilient, cost-efficient, and async-first storage with chunking, encryption, resumable uploads, and pad recycling.
4//!
5//! ## Why MutAnt?
6//! Addressing on-chain storage limitations, MutAnt:
7//! - **Splits** large data into scratchpad-sized chunks.
8//! - **Resumes** interrupted transfers automatically.
9//! - **Recycles** freed pads to reduce costs.
10//! - **Caches** index locally for fast lookups and syncs remotely.
11//! - **Encrypts** private data for secure storage.
12//! - **Processes** operations in the background with task management.
13//! - **Adapts** to business logic with pluggable backends.
14//!
15//! ## Key Highlights
16//!
17//! - **Chunk Management**: Configurable pad sizes with automatic chunking and reassembly.
18//! - **Resumption & Retries**: Transparent retry logic and transfer continuation.
19//! - **Cost Efficiency**: Reuses freed pads to minimize redundant on-chain writes.
20//! - **Daemon Architecture**: Persistent daemon process handles network connections and operations.
21//! - **Background Processing**: Run operations in the background with task management.
22//! - **Public/Private Storage**: Store data publicly to share with others or privately with encryption.
23//! - **Health Checks**: Verify and repair stored data with automatic pad recycling.
24//! - **Flexible Interfaces**: Rust SDK (`mutant-lib`), WebSocket client (`mutant-client`), and CLI tool (`mutant`).
25//! - **Async-First**: Built on `tokio` and `async/await`.
26//! - **Extensible Architecture**: Modular design allows custom network layers.
27//!
28//! ## Ecosystem Components
29//!
30//! MutAnt consists of several components that work together:
31//!
32//! - **mutant-lib**: Core library handling chunking, encryption, and storage operations
33//! - **mutant-protocol**: Shared communication format definitions
34//! - **mutant-daemon**: Background service maintaining Autonomi connection
35//! - **mutant-client**: WebSocket client library for communicating with the daemon
36//! - **mutant-cli**: Command-line interface for end users
37//!
38//! ## Quickstart
39//!
40//! Add to `Cargo.toml`:
41//! ```toml
42//! mutant-lib = "0.6.0"
43//! ```
44//!
45//! ```rust,no_run
46//! use mutant_lib::MutAnt;
47//! use mutant_lib::storage::StorageMode;
48//! use anyhow::Result;
49//!
50//! #[tokio::main]
51//! async fn main() -> Result<()> {
52//! // Use a dummy private key for doctest purposes.
53//! let key_hex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
54//!
55//! let mut ant = MutAnt::init(key_hex).await?;
56//!
57//! // Store data with medium storage mode (2MB chunks)
58//! ant.put("file1", b"hello", StorageMode::Medium, false).await?;
59//!
60//! // Retrieve the stored data
61//! let data = ant.get("file1").await?;
62//!
63//! println!("Fetched: {}", String::from_utf8_lossy(&data));
64//! Ok(())
65//! }
66//! ```
67//!
68//! ### Fetching Public Data (without a private key)
69//!
70//! If you only need to fetch data that was stored publicly (using `put` with the public flag), you can
71//! initialize a lightweight `MutAnt` instance without providing a private key:
72//!
73//! ```rust,no_run
74//! use mutant_lib::MutAnt;
75//! use mutant_lib::storage::ScratchpadAddress;
76//! use anyhow::Result;
77//!
78//! #[tokio::main]
79//! async fn main() -> Result<()> {
80//! // Initialize for public fetching (defaults to Mainnet)
81//! let public_fetcher = MutAnt::init_public().await?;
82//!
83//! // You need the public address of the data (obtained elsewhere)
84//! let public_address = ScratchpadAddress::from_hex("...")?;
85//!
86//! // Fetch the public data
87//! let data = public_fetcher.get_public(&public_address).await?;
88//!
89//! println!("Fetched public data: {} bytes", data.len());
90//! Ok(())
91//! }
92//! ```
93//!
94//! **Note:** An instance created with `init_public` can *only* be used for `get_public`.
95//! Other operations requiring a private key (like `put`, `get`, `remove`, etc.)
96//! will fail.
97//!
98//! ### Using the Daemon and Client
99//!
100//! For most applications, it's recommended to use the daemon architecture:
101//!
102//! ```rust,no_run
103//! use mutant_client::MutantClient;
104//! use anyhow::Result;
105//!
106//! #[tokio::main]
107//! async fn main() -> Result<()> {
108//! // Connect to the daemon (must be running)
109//! let mut client = MutantClient::new();
110//! client.connect("ws://localhost:3030/ws").await?;
111//!
112//! // Start a put operation in the background
113//! let (start_task, progress_rx) = client.put(
114//! "my_key",
115//! "path/to/file.txt",
116//! mutant_protocol::StorageMode::Medium,
117//! false, // not public
118//! false, // verify
119//! ).await?;
120//!
121//! // Monitor progress (optional)
122//! tokio::spawn(async move {
123//! while let Ok(progress) = progress_rx.recv().await {
124//! println!("Progress: {:?}", progress);
125//! }
126//! });
127//!
128//! // Wait for the task to complete
129//! let result = start_task.await?;
130//! println!("Task completed: {:?}", result);
131//!
132//! Ok(())
133//! }
134//! ```
135//!
136//! ## Resources & Support
137//!
138//! - API docs : https://docs.rs/mutant_lib
139//! - CLI help : `mutant --help`
140//! - Repository : https://github.com/Champii/MutAnt
141//! - Issues : https://github.com/Champii/MutAnt/issues
142//!
143
144/// Provides the main API entry point for interacting with MutAnt.
145mod api;
146/// Manages indexing and search functionality for stored data.
147mod index;
148/// Contains network-related functionalities, including data persistence via scratchpads.
149mod network;
150/// Handles data structures and serialization/deserialization logic, including worker pools.
151mod ops;
152
153/// Defines custom error types used throughout the `mutant-lib`.
154mod internal_error;
155/// Defines events and callbacks used for asynchronous operations and progress reporting.
156mod internal_events;
157
158// Re-export main API entry point
159pub use crate::api::MutAnt;
160
161pub mod config {
162 pub use crate::network::NetworkChoice;
163}
164
165pub mod storage {
166 pub use super::network::{GetResult, PutResult};
167 pub use crate::index::master_index::IndexEntry;
168 pub use crate::index::pad_info::{PadInfo, PadStatus};
169 pub use autonomi::ScratchpadAddress;
170 pub use mutant_protocol::StorageMode;
171}
172
173pub mod error {
174 pub use crate::internal_error::Error;
175 pub use crate::ops::worker::PoolError;
176}
177
178pub mod events {
179 pub use mutant_protocol::{
180 GetCallback, GetEvent, HealthCheckCallback, HealthCheckEvent, InitCallback,
181 InitProgressEvent, PurgeCallback, PurgeEvent, PutCallback, PutEvent,
182 SyncCallback, SyncEvent, TaskProgress, TaskResult, TaskStatus, TaskType,
183 };
184}
185
186pub mod worker {
187 pub use crate::ops::worker::{AsyncTask, WorkerPoolConfig};
188}