C4 architecture
The system from context to containers to components.
Level 1: System context
flowchart TB cust["Customer"] -->|wallet| dara staff["Dara staff"] -->|"admin console"| dara signer["Human signer"] -->|"signatures only"| dara pub["Public and auditors"] -->|"Dara Scan"| dara dara["DARA PLATFORM"] -->|"own RPC nodes"| stellar["Stellar network"] staff -.->|"records deposits and payouts"| bank["Bank"] att["Attestation provider"] -.->|"figures entered by staff"| dara eco["Wallets and explorers"] -->|"reads stellar.toml"| dara
No hosted service is in the production path. Bank movements, attestations and prices are entered by staff with approval.
Level 2: Containers
flowchart TB
subgraph web["Next.js apps"]
landing["Landing and stellar.toml"]
wallet["Wallet"]
admin["Admin console"]
scan["Dara Scan"]
docs["Docs"]
end
subgraph go["Go backend: one image"]
api["Customer API"]
apiadm["Admin API"]
worker["Worker: transactions, indexer, reconciliation, gate"]
scanapi["Scan API: read-only role"]
end
pg[("PostgreSQL")]
vault["Vault Transit: online keys"]
rpc["Two Stellar RPC nodes"]
lake[("Galexie data lake")]
obs["Prometheus, Alertmanager, Grafana, Loki, Tempo"]
net(("Stellar network"))
wallet --> api
admin --> apiadm
scan --> scanapi
landing --> scanapi
api --> pg
apiadm --> pg
scanapi --> pg
worker --> pg
worker -->|sign| vault
worker --> rpc
worker -.->|backfill| lake
rpc --> net
worker -.-> obs
The APIs write intents to PostgreSQL. Only the worker signs and talks to Stellar. The docs app has no backend dependency.
Level 3: Backend components
flowchart LR http["httpapi"] --> trading http --> customers http --> cash http --> issuance http --> clawback trading --> pricing trading --> ledger cash --> ledger issuance --> reserve issuance --> ledger clawback --> ledger trading --> tx["txmanager"] issuance --> tx clawback --> tx customers --> tx tx --> signer tx --> gw["stellar gateway"] indexer --> gw recon["reconciliation"] --> ledger recon --> gw recon --> indexer recon --> incident incident --> gate gw --> gate gate --> trading
The packages live in backend/internal.
| Component | Responsibility |
|---|---|
ledger | Double-entry, append-only source of truth for what customers own |
txmanager | Turns intents into attempts and signed envelopes, and never rebuilds an unknown attempt early |
gate | Closes trading when any safety check fails |
reconciliation | Compares chain, ledger and backing. It never corrects anything itself |
indexer | Reads every ledger in order and raises a critical incident on anything unexplained |
reserve | Reads backing through ReserveCapacityProvider, so a future capacity engine can plug in |
Details: Stellar architecture.