Architecture
HostraCore's architecture is built around a double-entry ledger as the source of truth, with settlement orchestration (3 methods, 4 providers), a card_to_crypto saga with compensation, tamper-evident audit, and ISO 8583 / ISO 20022 protocol depth.
System flow
graph TB
Client[Client / Mobile App] -->|POST /v1/quotes| Quotes[Quotes Service]
Client -->|POST /v1/transfers| Saga[Saga Orchestrator]
Saga -->|leg1: card_charge| Stripe[Stripe Provider]
Saga -->|leg2: on_chain| Crypto[Crypto Custodian]
Saga -->|compensate| Reverse[Settlement.Reverse]
Stripe --> Ledger[Double-Entry Ledger]
Crypto --> Ledger
Saga -->|events| Outbox[Transactional Outbox]
Outbox -->|HMAC POST| Webhook[Merchant Webhook]
Webhook -->|forward| Dispatch[/v1/notifications/dispatch]
Dispatch --> Expo[Expo Push API]
Expo --> Phone[Mobile Device]
Audit[Audit Hash-Chain] -->|records| All[All Operations]Modules
Double-entry ledger is the source of truth. Every movement is balanced across debit and credit accounts; balances are derived, never mutated in place.
Float and liquidity accounts per currency and per rail, reconciled against provider statements.
Durable settlement intents with lifecycle pending → in_flight → succeeded | failed | reversed. Methods: card_charge, card_push, on_chain.
card_to_crypto composes two legs with compensation. States: pending → leg1_in_flight → leg1_succeeded → leg2_in_flight → succeeded, or compensating → failed.
Human sessions (argon2id + opaque session cookie) and M2M API keys with RBAC scopes evaluated per route.
Append-only audit events chained by hash; a verification endpoint recomputes the chain to detect tampering.
Transactional email through the notification service; verification, password reset, API key created and security alerts.
Outbound events signed HMAC-SHA256 in Stripe style (t=, v1=), delivered from a transactional outbox with retry.
Device token registration → dispatch → Expo Push API → opaque payload {transfer_id} on iOS and Android.
Go 1.25, PostgreSQL (pgx v5), Redis (go-redis v9), RabbitMQ (amqp091), Docker, OpenTelemetry, Cloudflare.
Saga states
- pending — quote locked, transfer accepted, nothing executed yet.
- leg1_in_flight — card charge submitted to Stripe.
- leg1_succeeded — funds captured; ledger postings committed.
- leg2_in_flight — on-chain disbursement submitted to the custodian.
- succeeded — both legs terminal-committed; webhook emitted.
- compensating → failed — leg 2 failed; leg 1 is reversed and the saga terminates as failed.
Glossary
- settlement intent
- A durable record of the intention to move money, created before any provider call.
- lease
- Exclusive time-bounded ownership of an intent so only one worker executes it at a time.
- terminal CAS commit
- Compare-and-set write of the final state, so a state can never be committed twice.
- fencing token
- Monotonic token attached to a lease that invalidates writes from a stale owner (ABA protection).
- transactional outbox
- Events written in the same transaction as state, then published asynchronously — no lost events.
- saga
- A multi-step business transaction with explicit compensation instead of distributed locking.
- leg
- One provider-facing step of a saga, itself a settlement intent.
- compensation
- The reversing action for a completed leg when a later leg fails.
- double-entry ledger
- Every entry has equal and opposite postings; the ledger always balances.
- hash-chain audit
- Each audit record includes the hash of its predecessor, making silent edits detectable.