A secure, persistent key-value storage system with blockchain-like properties, implemented in Rust and compiled to WebAssembly.
- 🔒 Secure Storage: Data integrity protected with SHA-256 checksums
- 📝 Append-Only Ledger: Blockchain-like data structure
- 🔄 Cross-Platform: Native support for
wasm32
,x86_64
, andaarch64
- 🌐 Browser Ready: WebAssembly builds for browser environments
- 🏷️ Label Support: Organize data with multiple labels
- 📦 TypeScript Support: First-class TypeScript definitions
# Cargo.toml
[dependencies]
ledger-map = "0.4.2"
use ledger_map::LedgerMap;
// Create a new ledger map
let mut map = LedgerMap::new_with_path(None, None)
.expect("Failed to create LedgerMap");
// Store data
map.upsert("users", b"alice".to_vec(), b"data".to_vec())
.unwrap();
map.commit_block().unwrap();
// Retrieve data
let value = map.get("users", &b"alice".to_vec());
npm install @decent-stuff/ledger-map
import { WasmLedgerMap } from "@decent-stuff/ledger-map";
// Initialize
const ledger = new WasmLedgerMap();
await ledger.initialize();
// Store data
const key = new TextEncoder().encode("alice");
const value = new TextEncoder().encode("data");
ledger.beginBlock();
ledger.upsert("users", key, value);
ledger.commitBlock();
// Retrieve data
const retrieved = ledger.get("users", key);
Add to your Cargo.toml
:
[dependencies]
ledger-map = "0.4.2"
For specific features:
# For browser/WebAssembly support
ledger-map = { version = "0.4.2", features = ["browser"] }
# For Internet Computer support
ledger-map = { version = "0.4.2", features = ["ic"] }
# Using npm
npm install @decent-stuff/ledger-map
# Using yarn
yarn add @decent-stuff/ledger-map
# Using pnpm
pnpm add @decent-stuff/ledger-map
use ledger_map::{LedgerMap};
use env_logger::Env;
fn main() {
// Initialize logging (optional)
env_logger::try_init_from_env(Env::default().default_filter_or("info")).unwrap();
// Create LedgerMap with optional custom storage path
let mut ledger_map = LedgerMap::new_with_path(
None, // No specific labels to index
None // Use default storage path
).expect("Failed to create LedgerMap");
// Store data with labels
ledger_map.upsert("users", b"alice".to_vec(), b"data1".to_vec()).unwrap();
ledger_map.upsert("posts", b"post1".to_vec(), b"content".to_vec()).unwrap();
ledger_map.commit_block().unwrap();
// Query by label
let user_entries = ledger_map.iter(Some("users")).collect::<Vec<_>>();
let post_entries = ledger_map.iter(Some("posts")).collect::<Vec<_>>();
// Delete data
ledger_map.delete("users", b"alice".to_vec()).unwrap();
ledger_map.commit_block().unwrap();
}
import { WasmLedgerMap } from "@decent-stuff/ledger-map";
async function example() {
// Initialize
const ledger = new WasmLedgerMap();
await ledger.initialize(["users", "posts"]); // Pre-index labels
// Store data
const key = new TextEncoder().encode("user1");
const value = new TextEncoder().encode(JSON.stringify({ name: "Alice" }));
ledger.beginBlock();
ledger.upsert("users", key, value);
ledger.commitBlock();
// Retrieve data
const retrieved = ledger.get("users", key);
const userData = JSON.parse(new TextDecoder().decode(retrieved));
// Delete data
ledger.beginBlock();
ledger.delete("users", key);
ledger.commitBlock();
}
LedgerMap::new()
- Create a new ledger map with default settingsLedgerMap::new_with_path(labels: Option<&[&str]>, path: Option<PathBuf>)
- Create with custom settingsupsert(label: &str, key: Vec<u8>, value: Vec<u8>)
- Store or update a valueget(label: &str, key: &[u8]) -> Option<&Vec<u8>>
- Retrieve a valuedelete(label: &str, key: Vec<u8>)
- Delete a valuecommit_block()
- Commit pending changesiter(label: Option<&str>)
- Iterate over entries
initialize(labels?: string[])
- Initialize the ledgerupsert(label: string, key: Uint8Array, value: Uint8Array)
- Store or update a valueget(label: string, key: Uint8Array)
- Retrieve a valuedelete(label: string, key: Uint8Array)
- Delete a valuebeginBlock()
- Start a new block of operationscommitBlock()
- Commit the current blockgetBlocksCount()
- Get total number of blocksgetLatestBlockHash()
- Get latest block hashrefreshLedger()
- Reload from storage
We welcome contributions! Please see our Contributing Guidelines for details on how to:
- Set up the development environment
- Run tests
- Submit pull requests
- Follow our coding standards
cargo test
cargo test --features browser
cargo test --features ic
# Node.js tests
npm run test
# Browser tests
RUSTFLAGS='--cfg getrandom_backend="wasm_js"' wasm-pack test --chrome --features browser
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.