| Crates.io | mutant |
| lib.rs | mutant |
| version | 0.6.2 |
| created_at | 2025-04-12 18:20:58.406799+00 |
| updated_at | 2025-05-10 11:00:32.004731+00 |
| description | Command-line interface for MutAnt distributed mutable key value storage over Autonomi network |
| homepage | |
| repository | https://github.com/Champii/MutAnt |
| max_upload_size | |
| id | 1631142 |
| size | 125,676 |
Mutant is a decentralized P2P mutable key-value storage system built on the Autonomi network, featuring chunking, encryption, resumable uploads, pad recycling, daemon architecture, and background task management with a powerful async Rust API + CLI.
Note: No LLMs were harmed in the making of this project.
get, put, rm).tokio for high-performance non-blocking operations.mutant-lib) or via the mutant CLI.ant CLI configured with a wallet (see below)This will install rustup
$> curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
This will install the latest stable version of the Rust toolchain and cargo
$> rustup install nightly
ant WalletBefore using mutant to actually store data, you need to have an ant wallet configured for the target network (Mainnet by default, or Devnet if using the --local flag). If you don't have ant installed, you can get it using antup:
$> curl -sSf https://raw.githubusercontent.com/maidsafe/antup/main/install.sh | sh
This will install the ant CLI and configure it for the Mainnet.
$> antup client
Once ant is installed, if you haven't already, you can import your existing Ethereum/ANT wallet's private key using the ant CLI:
$> ant wallet import YOUR_PRIVATE_KEY_HERE
Replace YOUR_PRIVATE_KEY_HERE with your actual private key. mutant will automatically detect and use this wallet.
Alternatively, you can create a new empty wallet using ant wallet create and fund it with the necessary ANT or ETH later.
MutAnt will look for your ant wallets and ask you which one you want to use if you have multiple on the first run, then save your choice in ~/.config/mutant/config.json.
$> cargo install mutant-daemon
$> cargo install mutant
You can fetch the daily meme of the day with the following command:
$> mutant get -p a420224971527d61ce6ee21d850a07c243498c95808697e8fac23f461545656933016697d10b805c0fa26b50eb3532b2 daily_meme.jpg
MutAnt includes the mutant command for convenient command-line access. When run without arguments, it defaults to listing your stored keys.
CLI Usage Examples:
$> mutant --help
Usage: mutant [OPTIONS] [COMMAND]
Commands:
put Store a value associated with a key
get Retrieve a value associated with a key
rm Remove a key-value pair
ls List stored keys
stats Show storage statistics
tasks Manage background tasks
daemon Manage the daemon
sync Synchronize local index cache with remote storage
purge Perform a get check on scratchpads that should have been created but failed at some point. Removes the pads that are not found.
import Import scratchpad private key from a file
export Export all scratchpad private key to a file
health-check Perform a health check on scratchpads that should have been created but cannot be retrieved. Recycles the pads that are not found.
help Print this message or the help of the given subcommand(s)
Options:
-q, --quiet Suppress progress bar output
-h, --help Print help
-V, --version Print version
Basic Usage:
# Store a the file `data.txt` under the name `mykey`
$> mutant put mykey data.txt
# Get a value and save to a file
$> mutant get mykey fetched_data.txt
# Run operations in the background
$> mutant put my_file large_file.zip --background
# Remove a value
$> mutant rm mykey
# Store data publicly (no encryption) under a name
$> mutant put -p my_key my_file.ext
1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
# Get your own public data by name
$> mutant get my_key output.txt
# Get public data by address
$> mutant get -p 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef output.txt
# You can update public data by using the same key
$> mutant put -p my_key my_updated_file.ext
# Start the daemon (happens automatically when needed)
$> mutant daemon start
# Check daemon status
$> mutant daemon status
# List background tasks
$> mutant tasks list
# Get details of a specific task
$> mutant tasks get <task_id>
# Stop a running task
$> mutant tasks stop <task_id>
# List stored keys
$> mutant ls
Key Pads Size Status Address/Info
----------------------------------------------------------------------
dwarf 265 1.03 GiB Ready Private
nothing_here 2 3.28 KiB Ready Public: ac09242b5c5658dd313e37b08cba4810346bc8ce75f32d9330b20f142c941fa47a396077e91acfb990edab5430e3245
zorglub 10 100.00 KiB 61% (6/10) Private
# List stored keys with fetch history
$> mutant ls --history
# Sync local index with remote storage
$> mutant sync
# View storage statistics
$> mutant stats
Storage Statistics:
-------------------
Total Keys: 2
Total Pads Managed: 270
Occupied (Private): 267
Free Pads: 3
Pending Verify Pads: 0
# Perform health check on a specific key with recycling enabled
$> mutant health-check mykey --recycle
Add mutant-lib and its dependencies to your Cargo.toml:
[dependencies]
mutant-lib = "0.6.2" # Or the version you need
tokio = { version = "1", features = ["full"] }
Library Example:
This example demonstrates initializing the necessary components and performing basic private store/fetch operations. It assumes you have an ant wallet setup.
use mutant_lib::{MutAnt, MutAntConfig, Error};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Replace with your actual private key (hex format, with or without 0x prefix)
let private_key_hex = "0xYOUR_PRIVATE_KEY_HEX";
let mut mutant = MutAnt::init(private_key_hex).await?;
mutant.put("greeting", b"hello world", StorageMode::Medium, false).await?;
let fetched_value = mutant.get("greeting").await?;
println!("Fetched value: {}", String::from_utf8_lossy(&fetched_value));
mutant.rm("greeting").await?;
Ok(())
}
If your application only needs to retrieve publicly stored data (using store_public) and doesn't need to manage private data, you can initialize a lightweight MutAnt instance without a private key using MutAnt::init_public():
use mutant_lib::{MutAnt, Error};
use mutant_lib::storage::ScratchpadAddress;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Initialize a public fetcher instance (defaults to Mainnet)
let public_fetcher = MutAnt::init_public().await?;
// Assume you have the public address from elsewhere
let address_hex = "..."; // Replace with actual public address hex
let public_address = ScratchpadAddress::from_hex(address_hex)?;
// Fetch the public data
match public_fetcher.get_public(public_address).await {
Ok(data) => println!("Fetched public data: {} bytes", data.len()),
Err(e) => eprintln!("Failed to fetch public data: {}", e),
}
Ok(())
}
This keyless instance is optimized for fetching public data and cannot perform operations requiring a private key (like `put`, `rm`, `ls`, etc).
### Using the Daemon and Client
For most applications, it's recommended to use the daemon architecture:
```rust
use mutant_client::MutantClient;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Connect to the daemon (must be running)
let mut client = MutantClient::new();
client.connect("ws://localhost:3030/ws").await?;
// Start a put operation in the background
let (start_task, progress_rx) = client.put(
"my_key",
"path/to/file.txt",
mutant_protocol::StorageMode::Medium,
false, // not public
false, // verify
).await?;
// Monitor progress (optional)
tokio::spawn(async move {
while let Ok(progress) = progress_rx.recv().await {
println!("Progress: {:?}", progress);
}
});
// Wait for the task to complete
let result = start_task.await?;
println!("Task completed: {:?}", result);
Ok(())
}
If you find this project useful, you can donate to support its development. <3
ETH/ANT 0x3376C33FdC0c885cef483690ffDd1e0Ff0Eb026c