Mika is a minimal decentralized storage prototype. A blob is split into k data shards plus m parity shards (systematic Reed–Solomon over GF(2^8)), distributed across storage nodes, and can be reconstructed from any k surviving shards.
Mika uses fjall (v3), an embeddable LSM-tree key-value store written in Rust, for on-disk sliver persistence. Fjall replaces the previous JSON file-based approach and provides:
- ACID transactions with crash safety
- LSM-tree storage for high write throughput
- Key-value separation for efficient large value storage
- Automatic compaction and garbage collection
- Concurrent reads with snapshot isolation
Mika is built as part of the kanari-sdk workspace. The SDK crates are pinned to tag v0.3.9-alpha:
| Crate | Purpose |
|---|---|
kanari-crypto |
Key generation (K256, P256, Ed25519, Dilithium, SPHINCS+), signing, verification, encryption |
kanari-types |
Rust bindings for Kanari Move modules (Address, Coin, Transfer, CurrencyMetadata) |
kanari-core |
BlockchainEngine for on-chain transaction execution, checkpoints, state roots |
kanari-rpc-client |
RPC client for interacting with kanari nodes |
kanari-common |
Config management, address handling, environment configuration |
Write certificates are signed using kanari_crypto::signatures::sign_message and verified with verify_signature_with_curve. Each certificate includes the signer's public key and curve type.
The signing keypair is loaded from the kanari config at ~/.kanari/kanari_config/:
kanari.yaml— config withkeystore_path,active_address, andenvskanari.keystore— encrypted keystore with private keys (password-protected)
KanariStorage::from_config(password, node_id):
- Loads config via
kanari_common::load_kanari_config() - Gets
active_addressviakanari_common::get_active_address() - Loads keystore from
keystore_pathin config - Decrypts the active address's private key with
kanari_crypto::encryption::decrypt_data()using your password - Derives the public key for verification
The kanari.yaml on this system has:
active_address: 0x3ba63b92aac5f2bff87e580e820b61faf1c5fe9ae12f0bc8addd931a340b3146keystore_path: C:\Users\TaroPukpui\.kanari\kanari_config\kanari.keystore
The StoragePayment trait (mika-storage::onchain) defines the interface for:
pay_storage_rent— pay storage rent via native KANARI coin transferanchor_blob— anchor blob metadata (owner, commitment, lease) on-chaintransfer_blob_ownership— transfer blob ownership with rent transfer
KanariStorage (mika-storage::kanari_integration) implements StoragePayment against kanari_core::BlockchainEngine. It wraps an in-memory or persistent BlockchainEngine and a signing keypair.
cargo build --releaseBinaries:
target/release/mika-cli— CLI tool (upload, download, proof, node, anchor)target/release/mika-node— storage node server
Build with on-chain support:
cargo build --release -p mika-cli --features onchaincargo run -p mika-node -- --node-id node-1 --data-dir ./mika-data --listen-addr 127.0.0.1:8080The node serves both APIs on the same port:
| API | Endpoints |
|---|---|
| Sliver API | GET /health, PUT/GET /slivers/{blob_id}/{shard_index}, GET /proofs/{blob_id}/{shard_index} |
| Web API | GET /, POST /api/v1/upload, GET /api/v1/download/{blob_id}, GET /api/v1/proof/{blob_id}/{shard_index}, GET /api/v1/blobs/{blob_id}, GET /api/v1/health |
Options:
--node-id— node identifier (defaultnode-1)--data-dir— on-disk data directory (default./mika-data)--listen-addr— listen address (default127.0.0.1:8080)
The web API includes CORS headers so browsers can call it directly. A single-page HTML frontend is served at GET /.
curl -X POST -F "file=@myfile.txt" http://127.0.0.1:8080/api/v1/uploadResponse:
{
"ok": true,
"blob_id": "27b8f6f78d134903727959b38de290371b6793a760055d669e11802b2bb896f7",
"filename": "myfile.txt",
"size": 32,
"shards": "3 data + 2 parity",
"nodes": 1
}curl http://127.0.0.1:8080/api/v1/download/27b8f6f7... > recovered.txtcurl http://127.0.0.1:8080/api/v1/proof/27b8f6f7.../0Response:
{
"blob_id": "27b8f6f7...",
"shard_index": 0,
"node_id": "node-1",
"epoch": 1794030586,
"sliver_digest": "7d8081c24869765dcb79490332667118681c3908ac719bee3a8dc54c5c4cb4fd",
"sliver_size": 11,
"original_len": 32,
"data_shards": 3,
"parity_shards": 2
}curl http://127.0.0.1:8080/api/v1/blobs/27b8f6f7...cargo run -p mika-cli -- <command> [options]Mika loads the signing keypair from the kanari config file managed by kanari-common:
C:\Users\TaroPukpui\.kanari\kanari_config\kanari.yaml
The config file should contain the user's private key hex string. This is used by
KanariStorage::from_config() for signing storage certificates and on-chain anchoring.
The config path is resolved via kanari_common::get_kanari_config_path() and
loaded via kanari_common::load_kanari_config().
cargo run -p mika-cli -- upload --file myfile.txt --nodes 127.0.0.1:8080 --data-shards 3 --parity-shards 2 --fee 1000cargo run -p mika-cli -- download <blob_id> --output out.txt --nodes 127.0.0.1:8080 --data-shards 3 --parity-shards 2cargo run -p mika-cli -- proof <blob_id> <shard_index> --node-addr 127.0.0.1:8080cargo run -p mika-cli -- features onchain -- anchor <blob_id> <owner_address> <commitment_hex> --password <keystore_password> --fee 1000The --password is used to decrypt your private key from kanari.keystore.
cargo run -p mika-cli -- node --node-id node-1 --data-dir ./mika-data --listen-addr 127.0.0.1:8080Slivers are stored in a fjall database at ./mika-data/ (or --data-dir). Data persists across separate CLI invocations and server restarts.
Each sliver is stored as a key-value pair in fjall:
- Key:
blob_id (32 bytes) || shard_index (4 bytes little-endian)= 36 bytes - Value: bcs-serialized
Sliverstruct
Prefix scans on blob_id bytes list all shard indices for a blob.
data_shards + parity_shards <= 256(GF(256) field size limit)data_shards > 0andparity_shards > 0- At least
kshards must be available to reconstruct
- Real node-to-node HTTP replication is not yet implemented (single node stores all shards locally).
- The web API uses fixed erasure parameters (3 data + 2 parity shards).
KanariStorage::anchor_blob,pay_storage_rent, andtransfer_blob_ownershipare stubs awaitingBlockchainEnginetransaction submission API.