The scout toolkit
Four small Rust tools for using Swarm — the
decentralized storage network — without running a node. They share one
foundation, the scout library, and cover the everyday things people
actually do with storage: read, sync, publish, and keep secrets.
| Tool | Crate | What it does |
|---|---|---|
| scout | swarm-scout | a light client: read / write / feeds / encrypted sharing (CLI and library) |
| stash | swarm-stash | sync a folder ↔ Swarm — a feed-backed drive |
| perch | swarm-perch | publish a folder as a website with a stable URL |
| keep | swarm-keep | an encrypted secrets/notes vault |
cargo install swarm-scout swarm-stash swarm-perch swarm-keep
The "no-node" idea
Running a full Swarm (Bee) node means staking, syncing a reserve, and operating infrastructure. Most people who use Swarm don't want that — they want to fetch a file, publish a site, or back up a folder.
These tools split the two halves of that:
- Reads (
/bzz,/bytes, feeds) are served by any gateway — no node, stake, or stamp. By default they use the public Swarm gateway, so reading works out of the box. - Writes (uploads, feed updates, sharing) need a Bee node that holds a postage batch (a prepaid storage stamp). You point the tools at your own or a hosted node — "bring your own stamp."
See Getting started for both.
Who it's for / where you'd use them
- App & script developers —
swarm-scoutis a small library to read or write Swarm from a backend, CLI, bot, serverless function, or CI job, without the full node/client surface.stash/perch/keepare each ~150 lines on top of it — proof the library is the building block. - Site authors —
perchhosts a static site, docs, or dapp frontend on Swarm with a link that survives redeploys (decentralized hosting). - Anyone who wants durable storage —
stashfor folder backup/sync,keepfor portable, client-side-encrypted secrets.
Status & caveats
All four are early (v0.1–v0.6), single-author, and verified end-to-end
against a live Bee node (Sepolia testnet, Bee 2.7.2). They're not yet
mainnet-hardened at scale, and keep's encryption (ChaCha20-Poly1305),
while standard, is unaudited. Writes cost BZZ (postage). Treat them as
solid, working building blocks rather than turnkey products.
Getting started
Install
cargo install swarm-scout swarm-stash swarm-perch swarm-keep
# binaries: scout, stash, perch, keep
Reading needs nothing
Reads default to the public Swarm gateway, so this works immediately:
scout cat <reference> # print content
scout get <reference> out.bin # download to a file
Override the read endpoint with --gateway / $BEE_GATEWAY to use your
own node or a private gateway.
Writing needs a node + a postage batch
Uploading (and feeds, sharing, stash push, perch deploy, keep set)
requires a Bee node that holds a postage batch. Two pieces:
- A node. Run Bee
locally (defaults to
http://localhost:1633) or use a hosted one. Point the tools at it with--node/$BEE_NODE. - A postage batch. Buy one on the node — it prepays storage:
On a fresh testnet node a usable batch needscurl -s -XPOST "$BEE_NODE/stamps/<amount>/<depth>" # returns a batchIDamountabove the chain's current total and takes a couple of minutes to become usable. Pass the batch id with--stamp/$BEE_STAMP.
export BEE_NODE=http://localhost:1633
export BEE_STAMP=<batchID>
scout up notes.md # -> a reference
perch deploy ./site # -> a website URL
Environment variables
| Var | Used by | Meaning |
|---|---|---|
BEE_GATEWAY | all (reads) | read endpoint (default: public gateway) |
BEE_NODE | all (writes) | your Bee node for uploads (default: localhost:1633) |
BEE_STAMP | all (writes) | postage batch id |
Concepts in 30 seconds
- Reference — a content address (hex). Immutable: same bytes → same ref.
- Feed — a mutable pointer you own; the handle stays put while the content it serves changes. Powers stash/perch/keep's "latest version."
- Postage batch — prepaid storage; required to upload.
- ACT — Access Control Trie: encrypt content and grant/revoke specific
recipients (used by
scout share).
scout — the light client
scout is the foundation: a light client for Swarm as both a CLI and a
library (swarm-scout). It does the four things the other tools build
on — read, write, feeds, and encrypted sharing.
CLI
# read (no node)
scout cat <ref> [path] # print content (manifest-aware, /bzz)
scout get <ref> <out> [path] # download to a file
scout bytes <ref> # raw bytes (/bytes)
# write (node + stamp)
scout up <file> [--name n] --stamp <batch>
scout up-bytes <file> --stamp <batch>
scout up-dir <folder> [--index index.html] --stamp <batch> # browsable collection
# feeds (a stable handle that serves the latest content)
scout keygen
scout publish <ref> --key <hex> -t <topic> --stamp <batch> # -> feed handle
scout cat <feed-handle> # read latest
# sharing (encrypted + revocable, via ACT)
scout share <file> --to <pubkey> --stamp <batch> # -> a share id + refs
scout shares
scout grantees <id>
scout revoke <id> --grantee <pubkey> --stamp <batch>
scout fetch <file_ref> --publisher <pk> --history <h> # recipient decrypts
Library
use scout::LiteClient; #[tokio::main] async fn main() -> anyhow::Result<()> { // read-only, via a gateway let c = LiteClient::read("https://download.gateway.ethswarm.org")?; let bytes = c.cat("<reference>").await?; // add a write endpoint for uploads / feeds / sharing let c = LiteClient::read("http://localhost:1633")? .with_write("http://localhost:1633", "<postage-batch>")?; let r = c.up_bytes(b"hello".to_vec()).await?; let handle = c.publish("<feed-key-hex>", "my-topic", &r).await?; Ok(()) }
See examples/
and the API docs on docs.rs.
Where it fits
Reach for swarm-scout when a Rust project needs light Swarm I/O without
operating a node — backends, CLIs, bots, serverless, CI, data tooling.
stash, perch, and keep are all thin layers over it.
stash — folder sync
stash syncs a folder to Swarm and pulls it back anywhere. push uploads
every file, records a path → reference index, and points a feed at it —
so the printed handle is a stable address that always resolves to your
latest push. A tiny content-addressed drive.
stash keygen # a drive identity (save the key)
stash push <folder> --key <hex> -t <topic> --stamp <batch> # -> a handle
stash ls <handle> # list files
stash pull <handle> <out-dir> # restore the folder
Re-pushing under the same key+topic updates what the same handle
serves. ls/pull read from a gateway (no node); push needs a node +
stamp.
Use cases
- Backup / restore a working directory or config.
- Versioned datasets or build artifacts — each push is content-addressed.
- Dotfiles / small sync across machines (carry the key).
How it works
Each file is uploaded with scout, a JSON index maps paths to references,
and a feed makes that index mutable behind one handle. Nothing
stash-specific lives on Swarm — you could read the index and files with
scout directly.
perch — publish a website
perch publishes a folder as a website on Swarm. deploy uploads it as a
browsable Swarm collection (a mantaray manifest with an index document, so
bzz/<ref>/ renders your site) and prints the reference; with a feed it
gives a stable URL that survives re-deploys — "Netlify for Swarm."
# one-shot (the URL changes each deploy)
perch deploy ./site --stamp <batch>
# stable URL across re-deploys
perch keygen
perch deploy ./site --key <hex> -t <topic> --stamp <batch>
# -> open <gateway>/bzz/<handle>/ and re-deploy to update it
--index sets the default document (default index.html); nested assets
resolve normally.
Use cases
- Static sites & docs hosted decentrally (censorship-resistant).
- Dapp frontends — pin your UI to Swarm with a durable address.
- One-command publishing of a build output (
./dist,./public).
How it works
deploy is two scout calls: upload the directory as a native Swarm
collection, then optionally point a feed at that manifest so one address
always serves the latest deploy.
keep — encrypted vault
keep is an encrypted secrets/notes vault synced over Swarm. Your
key/value pairs are encrypted client-side (ChaCha20-Poly1305) — only
ciphertext ever reaches Swarm — and made mutable behind a feed, so the
vault follows you across machines.
keep init --stamp <batch> # create a vault (~/.keep/keep.json)
keep set api-token s3cr3t --stamp <batch>
keep get api-token # -> s3cr3t (read; no stamp)
keep list
keep rm api-token --stamp <batch>
Use cases
- CLI secret management — API tokens, keys, config secrets.
- Portable notes/secrets across machines (copy the config).
- A personal vault whose ciphertext is backed up on Swarm.
How it works & security
The vault is a JSON map encrypted under a key derived from a locally-stored
secret (~/.keep/keep.json); the ciphertext is uploaded to Swarm and a
feed points at the latest version. The config file is the only thing that
can decrypt your vault — copy it to use the vault elsewhere; lose it and
the data is unrecoverable, by design. Nothing readable is ever stored on
Swarm.
The encryption (ChaCha20-Poly1305) is standard but unaudited; treat
keepas a convenient personal vault, not a hardened secrets manager.