Skip to content
Logo

Technical architecture

Bloom is a Rust workspace split into focused crates around a daemon, virtual filesystem, wallet transaction engine, and chain integrations.

Runtime shape

agent or user

    ├─ mounted filesystem: /bloom
    │     │
    │     ├─ shell reads:  ls /bloom/chains, cat /bloom/status/daemon.json
    │     └─ shell writes: echo ... > /bloom/wallets/<name>/chains/<chain>/outbox/new.tx


bloom daemon

    ├─ VFS router and handlers
    ├─ wallet transaction engine
    ├─ encrypted keystore and signer
    ├─ chain RPC pool and Etherscan-backed metadata
    ├─ DeFi routing via Enso
    ├─ watch executor
    └─ audit log and policy enforcement

bloom serve --mount /bloom runs a long-lived daemon and exposes the mounted filesystem. Standard shell reads and writes share daemon state including unlock cache, watches, DeFi sessions, Etherscan cache, and policy/audit state.

NFS mount surface

Bloom exposes the VFS over NFS v4.1. The local /bloom mount is not a separate API from the VFS router; it is the normal filesystem surface backed by Bloom's daemon, handlers, policy checks, and audit model.

This matters because Bloom should fit into ordinary Unix and infrastructure workflows rather than asking every agent or app to speak a custom CLI protocol. Over time, Bloom expects to rely more on this NFS layer for:

  • Unix permission boundaries and familiar file ownership/mode semantics;
  • Docker and hypervisor use cases where /bloom can be shared into containers, VMs, or sandboxes as a mounted volume;
  • multi-process workflows where different tools read plans, inspect state, and stage intents through the same mounted tree;
  • safer automation patterns that can be constrained with standard filesystem access controls before Bloom's own policy layer evaluates an action.

This area is still active work. Examples, experiments, and contributions around NFS permissions, container/VM volume sharing, and operational deployment patterns are welcome.

Core crates

CrateResponsibility
bloomCLI binary; thin client and driver for the in-process daemon.
bloom-daemonWires home dir, config, chains, keystore, VFS, IPC, ENS, and watch executor.
bloom-vfsPath router, handler trait, per-path caching, vendored docs, and handler modules.
bloom-chainRPC pool and per-chain engine for heads, blocks, addresses, and ERC-20 reads.
bloom-txStage, simulate, sign, broadcast, nonce management, and policy enforcement.
bloom-keystoreEncrypted local key storage and signer.
bloom-defiEnso Shortcuts client and natural-language intent parser.
bloom-watchSubscription registry and polling executor with rotated event logs.
bloom-mountNFSv4 mount adapter behind the mount feature.
bloom-toolsKeccak, SHA-256, Blake3, hex, base64, ABI, RLP, units, and EIP-712 helpers.
bloom-etherscanEtherscan v2 multichain client with on-disk TTL cache.
bloom-ensENS namehash, forward, reverse, text, and contenthash resolution.
bloom-pricesDefiLlama keyless price oracle.
bloom-protoShared types for paths, config, audit, address book, intents, policy, plans, and units.
bloom-itIntegration-test harness crate.

Data flow for a transaction

  1. Agent writes an intent to a wallet outbox path under /bloom.
  2. The VFS router dispatches to wallet handlers.
  3. The transaction engine parses the intent and resolves chain, recipient, gas, value, calldata, and nonce defaults.
  4. Simulation and policy checks run.
  5. Bloom writes a pending directory with intent.json, plan.md, policy_check.json, and control files.
  6. User or agent reads the plan.
  7. Confirmation unlocks the signer and broadcasts only if policy still permits it.
  8. The pending entry moves to sent/ and links to chain transaction paths.

Backend boundaries

Some surfaces are direct RPC reads. Others use Etherscan v2 where an indexer is required today. The live backend declaration is exposed under /bloom/status/backends/<feature> and /bloom/status/backends/summary.json.

The future indexer backend is reserved but intentionally returns a clear not-implemented error today.