#networking #key #mutant #mut-ant

mutant-lib

Core library for MutAnt distributed mutable key value storage over Autonomi network

5 releases (3 breaking)

new 0.4.1 Apr 19, 2025
0.4.0 Apr 19, 2025
0.3.0 Apr 18, 2025
0.2.0 Apr 14, 2025
0.1.1 Apr 12, 2025

#202 in #key

Download history 46/week @ 2025-04-06 254/week @ 2025-04-13

300 downloads per month
Used in mutant

LGPL-3.0-only and GPL-3.0 licenses

350KB
6.5K SLoC

MutAnt

MutAnt is a private, mutable key-value store built on Autonomi network scratchpads, offering resilient, cost-efficient, and async-first storage.

Why MutAnt?

Addressing on-chain storage limitations, MutAnt:

  • Splits large data into scratchpad-sized chunks.
  • Resumes interrupted transfers automatically.
  • Recycles freed pads to reduce costs.
  • Caches index locally for fast lookups and syncs remotely.
  • Adapts to business logic with pluggable backends.

Key Highlights

  • Chunk Management: Configurable pad sizes with automatic chunking and reassembly.
  • Resumption & Retries: Transparent retry logic and transfer continuation.
  • Cost Efficiency: Reuses freed pads to minimize redundant on-chain writes.
  • Flexible Interfaces: Rust SDK (mutant-lib) and CLI tool (mutant).
  • Async-First: Built on tokio and async/await.
  • Extensible Architecture: Modular design allows custom network layers.

Quickstart

Add to Cargo.toml:

mutant-lib = "0.4.0"
use mutant_lib::MutAnt;
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    // Use a dummy private key for doctest purposes.
    let key_hex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".to_string();

    let mut ant = MutAnt::init(key_hex).await?;

    ant.store("file1".to_string(), b"hello").await?;

    let data = ant.fetch("file1").await?;

    println!("Fetched: {}", String::from_utf8_lossy(&data));
    Ok(())
}

Fetching Public Data (without a private key)

If you only need to fetch data that was stored publicly (using store_public), you can initialize a lightweight MutAnt instance without providing a private key:

use mutant_lib::MutAnt;
use autonomi::ScratchpadAddress;
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize for public fetching (defaults to Mainnet)
    let public_fetcher = MutAnt::init_public().await?;

    // You need the public address of the data (obtained elsewhere)
    let public_address = ScratchpadAddress::from_hex("...")?;

    // Fetch the public data
    let data = public_fetcher.fetch_public(public_address, None).await?;

    println!("Fetched public data: {} bytes", data.len());
    Ok(())
}

Note: An instance created with init_public can only be used for fetch_public. Other operations requiring a private key (like store, fetch private data, remove, etc.) will fail.

Resources & Support

Dependencies

~76–115MB
~2M SLoC