Skip to content

Store and share a blob

Task: store a large binary (a file, an image) and make it available to other nodes in the context.

Blobs live outside CRDT state: you store the bytes once, get back a content BlobId, keep that small id in your state, and announce the blob so peers can fetch it. The replication model is in the blobs reference.

The SDK exposes a file-descriptor-style API in calimero_sdk::env:

StepFunctionReturns
Open a new blob for writingblob_create()fd (u64)
Append bytesblob_write(fd, &data)bytes written
Finish writingblob_close(fd)BlobId ([u8; 32])
Open an existing blobblob_open(&blob_id)fd
Read bytesblob_read(fd, &mut buf)bytes read

Write path: blob_createblob_write… → blob_close (the returned id is the content hash). Read path: blob_openblob_read… → blob_close.

Storing a blob keeps it local. env::blob_announce_to_context(&blob_id, &context_id) advertises it to the rest of the context so other nodes can discover and download it. This is apps/blobs:

use calimero_sdk::{app, env, BlobId};
pub fn upload_file(&mut self, name: String, blob_id: BlobId, size: u64) -> app::Result<String> {
let current_context = env::context_id();
if env::blob_announce_to_context(blob_id.as_ref(), &current_context) {
app::log!("Announced blob {} to network", blob_id);
} else {
app::log!("Warning: Failed to announce blob {}", blob_id);
}
// keep the small id + metadata in CRDT state; the bytes stay in the blob store
let file_id = format!("file_{}", self.file_counter.value()?);
self.file_counter.increment()?;
self.files.insert(file_id.clone(), /* FileRecord { blob_id, name, size, .. } */ )?;
Ok(file_id)
}

The full arc: write the bytes to get a content id, announce that id so the rest of the context learns the blob exists, then any peer opens it by id and streams the bytes — recomputing the id to confirm it got what it asked for.

Terminal window
# the BlobId comes back base58-encoded; store the metadata via your method
meroctl --node node1 call upload_file \
--context <context-id> \
--args '{"name": "notes.txt", "blob_id": "<base58-blob-id>", "size": 12}'