Storage Module Tutorial
In this tutorial, you will build a simple CLI application that uploads and downloads files over the Logos Storage network using the Logos Storage Module API.
We provide a Logos Storage App Skeleton that gives you a ready-made entry point with access to the LogosModules object (m_logos) and Qt-compatible synchronization utilities.
Prerequisites
- Nix package manager
- Git
Building the Skeleton App
-
Clone the skeleton repository:
Terminal window git clone https://github.com/logos-storage/logos-storage-app-skeleton.gitcd logos-storage-app-skeleton -
Build with Nix:
Terminal window nix build -
The compiled binary will be at
./result/bin/storage-app.
The skeleton provides an app_main entry point with access to the LogosModules object (referred to as m_logos in the API documentation). It also provides Qt-compatible synchronization utilities for blocking on asynchronous operations.
Initializing the Module
Before performing any operations, initialize the storage module with a JSON configuration string. See the Configuration Reference for all available options.
const QString jsonConfig = "{}";bool result = m_logos->storage_module.init(jsonConfig);Starting the Node
Start the node and listen for the completion event:
m_logos->storage_module.on("storageStart", [this](const QVariantList& data) { bool success = data[0].toBool(); if (!success) { QString error = data[1].toString(); // Handle error }});
bool result = m_logos->storage_module.start();Uploading a File
The simplest way to upload a file is with uploadUrl:
// Subscribe to eventsm_logos->storage_module.on("storageUploadDone", [this](const QVariantList& data) { bool success = data[0].toBool(); QString sessionId = data[1].toString(); QString cidOrError = data[2].toString();
if (success) { qDebug() << "Upload complete. CID:" << cidOrError; } else { qDebug() << "Upload failed:" << cidOrError; }});
m_logos->storage_module.on("storageUploadProgress", [this](const QVariantList& data) { bool success = data[0].toBool(); QString sessionId = data[1].toString(); int bytes = data[2].toInt(); qDebug() << "Uploaded" << bytes << "bytes";});
// Start the uploadQUrl fileUrl = QUrl::fromLocalFile("/path/to/myfile");LogosResult result = m_logos->storage_module.uploadUrl(fileUrl);The upload returns a CID (Content Identifier) — a string that uniquely identifies the file within the network.
Streaming Upload
For more control, use the streaming upload API:
// 1. Initialize the sessionLogosResult result = m_logos->storage_module.uploadInit(filename);QString sessionId = result.getValue<QString>();
// 2. Upload chunksQFile file(filepath);file.open(QIODevice::ReadOnly);int chunkSize = 1024 * 64;while (!file.atEnd()) { QByteArray chunk = file.read(chunkSize); result = m_logos->storage_module.uploadChunk(sessionId, chunk); if (!result.success) { // Handle error break; }}
// 3. Finalizeresult = m_logos->storage_module.uploadFinalize(sessionId);if (result.success) { QString cid = result.getValue<QString>(); qDebug() << "CID:" << cid;}Downloading a File
To download content, you need the CID and the Signed Peer Record (SPR) of a node that has the content:
// Subscribe to eventsm_logos->storage_module.on("storageDownloadDone", [this](const QVariantList& data) { bool success = data[0].toBool(); QString message = data[1].toString(); if (success) { qDebug() << "Download complete"; } else { qDebug() << "Download failed:" << message; }});
m_logos->storage_module.on("storageDownloadProgress", [this](const QVariantList& data) { bool success = data[0].toBool(); QString sessionId = data[1].toString(); int size = data[2].toInt(); qDebug() << "Downloaded" << size << "bytes";});
// Start the downloadQUrl destination = QUrl::fromLocalFile("/path/to/output");LogosResult result = m_logos->storage_module.downloadToUrl(cid, destination);Cleaning Up
Always stop the node before destroying resources:
LogosResult result = m_logos->storage_module.stop();// Wait for storageStop event...result = m_logos->storage_module.destroy();Headless Mode
The storage module can also be run from the command line without a UI:
./logos/bin/logoscore -m ./modules --load-modules storage_module \ -c "storage_module.init(@config.json)" \ -c "storage_module.start()" \ -c "storage_module.importFiles(/path/to/files)"Next Steps
- See the Storage Module API Reference for the complete list of methods and events / signals.
- If you need lower-level access or want to build bindings for another language, see the libstorage Tutorial.