Public Archive

A Public Archive is a structure that maps file paths to data addresses on the network. While it can be used to store a single file with its metadata, it is generally used to organize multiple files in a hierarchical structure to simulate directories. Public Archives support nested paths and store metadata (creation time, modification time, size) for each file.

The key feature of Public Archives is that they store references (addresses) to files already uploaded to the network. When you retrieve a Public Archive, you get the addresses of the files, which you can then use to download the actual file content. The archive itself is uploaded to the network as chunks, and can be retrieved using its address.

Structure

pub struct PublicArchive {
    // Path of the file in the directory -> (Data address, Metadata)
    map: BTreeMap<PathBuf, (DataAddress, Metadata)>,
}

Instance Methods

new() -> Self

Create a new empty Public Archive.

let archive = PublicArchive::new();

add_file(&mut self, path: PathBuf, data_addr: DataAddress, meta: Metadata)

Add a file to the archive with its network address and metadata.

archive.add_file(
    PathBuf::from("documents/report.pdf"),
    data_address,
    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, not the actual data on the network.

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);
}

addresses(&self) -> Vec<DataAddress>

Get all data addresses stored in the archive.

let addresses = archive.addresses();

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

Iterate over all items in the archive.

for (path, addr, metadata) in archive.iter() {
    println!("{}: {:?}", path.display(), addr);
}

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

Get direct access to the underlying map structure.

let map = archive.map();

merge(&mut self, other: &PublicArchive)

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<PublicArchive, rmp_serde::decode::Error>

Deserialize an archive from bytes.

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

Client Methods

archive_put_public(&self, archive: &PublicArchive, payment_option: PaymentOption) -> Result<(AttoTokens, ArchiveAddress), PutError>

Upload a Public Archive to the network. Returns the cost and the address where the archive can be retrieved.

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

archive_get_public(&self, addr: &ArchiveAddress) -> Result<PublicArchive, GetError>

Retrieve a Public Archive from the network using its address.

let archive = client.archive_get_public(&archive_address).await?;

archive_cost(&self, archive: &PublicArchive) -> Result<AttoTokens, CostError>

Calculate the cost to upload an archive without actually uploading it.

let cost = client.archive_cost(&archive).await?;

Example Usage

use autonomi::{Client, PublicArchive};
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 = PublicArchive::new();

    // Upload files and add them to the archive
    let file_path = PathBuf::from("document.pdf");
    let (_, file_addr) = client
        .file_content_upload_public(file_path.clone(), PaymentOption::from(&wallet))
        .await?;
    
    let metadata = Metadata {
        created: 1234567890,
        modified: 1234567890,
        size: 1024,
        extra: None,
    };
    
    archive.add_file(file_path, file_addr, metadata);

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

    println!("Archive uploaded for {} to address: {:?}", cost, archive_addr);

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

    // Later, retrieve the archive
    let retrieved_archive = client.archive_get_public(&archive_addr).await?;
    
    for (path, addr, meta) in retrieved_archive.iter() {
        println!("File: {} ({} bytes) at address: {:?}", 
                 path.display(), meta.size, addr);
    }

    Ok(())
}

See Also

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

  • Advanced Files Management - Advanced archive manipulation

  • Private Archive API Reference - Private archive operations