Skip to content

ADR 02: Ports and Adapters (Hexagonal Architecture)

Status: Accepted Date: 2026-04-09

Substratum's architecture is heavily influenced by Ports and Adapters (Hexagonal Architecture). This ensures that the core domain logic is completely isolated from external concerns like the network, storage, and user interfaces.

The Core Domain (The Center)

The domain logic is the engine that manages the private IPFS node, handles the local Blockstore, and understands the Passport Receipt schema. It has no knowledge of how it is being called (CLI, REST, RPC) or where data is stored (Memory, Disk, Network).

Primary Ports (Inbound/Driving)

These are the interfaces that define how external actors talk to the Sidecar or Gateway.

  • Port: ManageVaults: Create, Delete, List vaults.
  • Port: ServeContent: Get file by CID.

Primary Adapters

These adapters implement the primary ports, translating external requests into domain calls.

  • Adapter: CLI: Translates terminal commands (e.g., substratum add <file>) into ManageVaults calls.
  • Adapter: REST API: Translates HTTP GET /ipfs/{cid} into ServeContent calls.
  • Adapter: RPC/gRPC: For a future GUI to talk to the daemon efficiently without HTTP overhead.

Secondary Ports (Outbound/Driven)

These are the interfaces that define how the Sidecar or Gateway talks to the outside world.

  • Port: Network: Send and receive blocks (CIDs).
  • Port: Storage: Save blocks to persistent storage.

Secondary Adapters

These adapters implement the secondary ports, translating domain logic into external actions.

  • Adapter: libp2p/Bitswap: Implements the Network port using the modular libp2p stack.
  • Adapter: FlatFile/RocksDB: Implements the Storage port using a local disk database.

Why This Matters

By strictly adhering to Ports and Adapters, we can swap out the storage layer (e.g., from RocksDB to PostgreSQL) or add a new user interface (e.g., a Tauri GUI) without touching a single line of the core domain logic.