A simple command-line tool to upload and download files to Walrus decentralized storage.
- Upload files to Walrus with configurable storage epochs
- Download blobs from Walrus by blob ID
- List all locally tracked uploads in a table or JSON format
- Estimate cost before uploading
- Support for deletable blobs with configurable epochs
- Send blob objects to a specific Sui address
- Local metadata tracking at
~/.waldrop/metadata.json
- Rust (1.70+)
- Access to a Walrus publisher and aggregator (testnet URLs provided by default)
git clone https://github.com/waldrop-labs/waldrop-cli
cd waldrop-cli
cargo install --path .The waldrop binary will be installed to ~/.cargo/bin/. Make sure it's in your $PATH.
cargo build --release
# Binary available at ./target/release/waldropCreate a .env file in the project root (or set environment variables):
cp .env.example .env| Variable | Default | Description |
|---|---|---|
WALRUS_PUBLISHER_URL |
https://publisher.walrus-testnet.walrus.space |
Walrus publisher endpoint for uploads |
WALRUS_AGGREGATOR_URL |
https://aggregator.walrus-testnet.walrus.space |
Walrus aggregator endpoint for downloads |
WALDROP_DATA_DIR |
~/.waldrop |
Directory for local metadata storage |
RUST_LOG |
info |
Log level (debug, info, warn, error) |
waldrop upload <FILE> [OPTIONS]Options:
| Flag | Default | Description |
|---|---|---|
-e, --epochs <N> |
1 |
Number of storage epochs |
-d, --deletable |
true |
Store as a deletable blob |
-s, --send-object-to <ADDRESS> |
— | Send blob object to a Sui address |
Examples:
# Upload a file (deletable by default, 1 epoch)
waldrop upload photo.png
# Upload for 5 epochs
waldrop upload photo.png --epochs 5
# Upload for longer storage
waldrop upload photo.png --epochs 10
# Upload and send blob object to a Sui wallet
waldrop upload photo.png --send-object-to 0xYourSuiAddress
# Combine options
waldrop upload document.pdf --epochs 10 --send-object-to 0xAbc123Output:
✓ Uploaded photo.png
Object ID: 0xe91eee8c...
Blob ID: M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk
Size: 2.4 MB
Cost: 132300 MIST
Epochs: 1
End Epoch: 35
Deletable: yes
waldrop download <BLOB_ID> [OPTIONS]Options:
| Flag | Description |
|---|---|
-o, --output <PATH> |
Output file path (defaults to original filename if tracked locally) |
Examples:
# Download using blob ID (uses original filename if known)
waldrop download M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk
# Download to a specific path
waldrop download M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk --output ./downloads/photo.pngOutput:
✓ Downloaded photo.png
Blob ID: M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk
Size: 2.4 MB
Saved to: ./photo.png
waldrop list [OPTIONS]Options:
| Flag | Default | Description |
|---|---|---|
-f, --format <FORMAT> |
table |
Output format (table or json) |
Examples:
# Show as table
waldrop list
# Show as JSON
waldrop list --format jsonOutput (table):
+-------------------+-----------+--------+------------------+
| Blob ID | Name | Size | Uploaded |
+-------------------+-----------+--------+------------------+
| M4hsZGQ1oCktdz... | photo.png | 2.4 MB | 2026-02-27 14:30 |
| Xk9pLmNwRst2fg... | doc.pdf | 890 KB | 2026-02-26 09:15 |
+-------------------+-----------+--------+------------------+
waldrop cost <FILE> [OPTIONS]Options:
| Flag | Default | Description |
|---|---|---|
-e, --epochs <N> |
1 |
Number of storage epochs |
Examples:
# Estimate cost for 1 epoch
waldrop cost video.mp4
# Estimate cost for 5 epochs
waldrop cost video.mp4 --epochs 5Output:
Cost Estimate for video.mp4
File: video.mp4
Size: 256.00 MB
Storage Units: 256 MiB (encoded)
Epochs: 5
Current Epoch: 352
Per Epoch: 1,598,000 FROST/epoch
Total Cost: 7,990,000 FROST (0.007990 WAL)
Pricing fetched live from Walrus network
6,000 FROST/MiB/epoch + 62,000 metadata + 2,000 write
waldrop-cli/
├── src/
│ ├── main.rs # Entry point — parse args, dispatch commands
│ ├── cli.rs # Clap CLI definitions
│ ├── config.rs # Environment config loader
│ ├── error.rs # Custom error types
│ ├── commands/
│ │ ├── upload.rs # Upload file to Walrus
│ │ ├── download.rs # Download blob from Walrus
│ │ ├── list.rs # List tracked blobs
│ │ └── cost.rs # Estimate storage cost
│ ├── walrus/
│ │ ├── client.rs # HTTP client for Walrus API
│ │ └── types.rs # API response structs
│ └── store/
│ └── metadata.rs # Local JSON metadata store
├── tests/
│ └── cli_test.rs # Integration tests
├── .github/workflows/
│ └── ci.yml # CI pipeline
├── Cargo.toml
├── .env.example
-
Upload: Reads the file, sends raw bytes via HTTP PUT to the Walrus publisher. The publisher returns a blob ID (content-addressed hash). Metadata is saved locally to
~/.waldrop/metadata.json. -
Download: Fetches raw bytes from the Walrus aggregator using the blob ID. If the blob was previously uploaded through this CLI, the original filename is used automatically.
-
Walrus Network: The publisher and aggregator are two endpoints on the same Walrus network. Anything uploaded through any publisher is downloadable from any aggregator.
Walrus uses epoch-based storage. Blobs are stored for a specified number of epochs and can optionally be marked as deletable.
| Option | Flag | Description |
|---|---|---|
| Deletable | --deletable (default) |
Can be deleted by the owner before expiry |
| Epochs | --epochs <N> |
Number of epochs to store (default: 1) |
# Run during development
cargo run -- upload photo.png
cargo run -- list
# Run tests
cargo test
# Lint
cargo clippy -- -D warnings
# Format
cargo fmt- Rust
- clap — CLI argument parsing
- tokio — async runtime
- reqwest — HTTP client for Walrus API
- serde / serde_json — JSON serialization
- anyhow — error handling
- tracing — structured logging
- indicatif — progress spinners
- comfy-table — table output
- colored — terminal colors
- chrono — timestamps
Apache 2.0 — see LICENSE