Architecture & Wallets
Bounded Contexts
In-process module lifecycle, contracts, and boundary enforcement in Alexandria.
Bounded Contexts
Alexandria organizes features into distinct bounded contexts located in internal/. Each module is self-contained and acts as an independent composition root for its domain.
Module Contract
Every bounded context implements a consistent public lifecycle contract:
type Module interface {
Start(ctx context.Context) error
Close() error
Ready() bool
}Each module exposes:
Depsstruct: Explicit external requirements (database pool, logger, router group, shared event bus).New(deps Deps) (*Module, error): Assembles internal services, repositories, and private adapters.Start(ctx context.Context): Spawns background workers, establishes links with external dependencies, and registers routes.Close(): Gracefully releases resources, flushes buffers, and closes outbound connections.
Existing Contexts
1. ssi-auth (internal/ssi-auth)
Responsible for decentralized identity, verifiable credentials, and cryptographic signing:
- Exposes
/.well-known/did.jsonfor DID resolution. - Coordinates key management and attestation.
- Interacts with wallet adapters through the driven
wallet.Walletport.
2. auth-proxy (internal/auth-proxy)
Secures the HTTP boundary and manages authentication:
- Terminates OpenID Connect authorization code flows with PKCE.
- Issues, verifies, and encrypts
HttpOnlysession cookies. - Performs token introspection against Zitadel.
- Protects downstream
/api/v1routes.
Boundary Enforcement
Package boundaries are maintained by convention:
- Modules do not import each other's internal implementation packages (e.g.,
internal/auth-proxynever importsinternal/ssi-auth/fafnir). - Cross-context communication is mediated through public interfaces or shared events.
- Because seams are strictly maintained as Go interfaces, migrating any bounded context into a standalone network microservice in the future requires zero internal refactoring.