Private Archive

A Private Archive provides enhanced privacy by keeping data maps within the archive itself rather than referencing them on the network. Unlike Public Archives which reference files through their network addresses, Private Archives contain the complete data maps within the archive structure. Like Public Archives, they support nested paths to simulate directories and store metadata for each file.

The key difference is that Private Archives embed the DataMapChunk directly in the archive, meaning the archive contains all the information needed to reconstruct the files without needing to fetch additional data maps from the network. This makes the archive self-contained and ensures that file organization and structure remain private.

Structure

pub struct PrivateArchive {
    // Path of the file in the directory -> (DataMap chunk, Metadata)
    map: BTreeMap<PathBuf, (DataMapChunk, Metadata)>,
}

Instance Methods

new() -> Self

Create a new empty Private Archive.

let archive = PrivateArchive::new();

add_file(&mut self, path: PathBuf, data_map: DataMapChunk, meta: Metadata)

Add a file to the archive with its data map and metadata.

archive.add_file(
    PathBuf::from("documents/report.pdf"),
    data_map_chunk,
    metadata
);

rename_file(&mut self, old_path: &Path, new_path: &Path) -> Result<(), RenameError>

Rename a file within the archive. This only changes the path in the archive structure.

archive.rename_file(
    Path::new("old/path/file.txt"),
    Path::new("new/path/file.txt")
)?;

files(&self) -> Vec<(PathBuf, Metadata)>

Get a list of all files in the archive with their metadata.

let file_list = archive.files();
for (path, metadata) in file_list {
    println!("{}: {} bytes", path.display(), metadata.size);
}

data_maps(&self) -> Vec<DataMapChunk>

Get all data map chunks stored in the archive.

let data_maps = archive.data_maps();

iter(&self) -> impl Iterator<Item = (&PathBuf, &DataMapChunk, &Metadata)>

Iterate over all items in the archive.

for (path, data_map, metadata) in archive.iter() {
    println!("{}: {} bytes", path.display(), metadata.size);
}

map(&self) -> &BTreeMap<PathBuf, (DataMapChunk, Metadata)>

Get direct access to the underlying map structure.

let map = archive.map();

merge(&mut self, other: &PrivateArchive)

Merge another archive into this one. Files from the other archive will be added to this archive.

archive.merge(&other_archive);

to_bytes(&self) -> Result<Bytes, rmp_serde::encode::Error>

Serialize the archive to bytes for storage.

let bytes = archive.to_bytes()?;

from_bytes(data: Bytes) -> Result<PrivateArchive, rmp_serde::decode::Error>

Deserialize an archive from bytes.

let archive = PrivateArchive::from_bytes(bytes)?;

Client Methods

archive_put(&self, archive: &PrivateArchive, payment_option: PaymentOption) -> Result<(AttoTokens, PrivateArchiveDataMap), PutError>

Upload a Private Archive to the network. Returns the cost and the data map needed to retrieve the archive. This data map should be kept private.

let (cost, archive_data_map) = client
    .archive_put(&archive, PaymentOption::Wallet(wallet))
    .await?;

archive_get(&self, addr: &PrivateArchiveDataMap) -> Result<PrivateArchive, GetError>

Retrieve a Private Archive from the network using its data map.

let archive = client.archive_get(&archive_data_map).await?;

Example Usage

use autonomi::{Client, PrivateArchive};
use autonomi::client::files::Metadata;
use autonomi::client::payment::PaymentOption;
use test_utils::evm::get_funded_wallet;
use std::path::PathBuf;
use eyre::Result;

#[tokio::main]
async fn main() -> Result<()> {
    let client = Client::init_local().await?;
    let wallet = get_funded_wallet();

    // Create a new archive
    let mut archive = PrivateArchive::new();

    // Upload files and add them to the archive
    let file_path = PathBuf::from("sensitive_document.pdf");
    let (_, data_map) = client
        .file_content_upload(file_path.clone(), PaymentOption::from(&wallet))
        .await?;
    
    let metadata = Metadata {
        created: 1234567890,
        modified: 1234567890,
        size: 1024,
        extra: Some(r#"{"encrypted": true, "algorithm": "AES-256"}"#.to_string()),
    };
    
    archive.add_file(file_path, data_map, metadata);

    // Upload the archive
    let (cost, archive_data_map) = client
        .archive_put(&archive, PaymentOption::from(&wallet))
        .await?;

    println!("Private archive uploaded for {}", cost);
    // IMPORTANT: Store archive_data_map securely - it's needed to retrieve the archive

    // Wait for network replication
    tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;

    // Later, retrieve the archive using the data map
    let retrieved_archive = client.archive_get(&archive_data_map).await?;
    
    for (path, _, meta) in retrieved_archive.iter() {
        println!("File: {} ({} bytes)", path.display(), meta.size);
    }

    Ok(())
}

Privacy Considerations

  • The PrivateArchiveDataMap returned from archive_put must be kept secret - anyone with this data map can retrieve and decrypt the archive

  • Unlike Public Archives, the data maps are embedded within the archive, making the file structure itself private

  • Consider storing the archive data map in a Vault for secure long-term storage

See Also

  • Files API - High-level file upload/download operations

  • Advanced Files Management - Advanced archive manipulation

  • Public Archive API Reference - Public archive operations

  • Vault API Reference - Secure storage for private data maps