Engineering

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

Ledger

Double-entry ledger is the source of truth. Every movement is balanced across debit and credit accounts; balances are derived, never mutated in place.

Treasury

Float and liquidity accounts per currency and per rail, reconciled against provider statements.

Settlement

Durable settlement intents with lifecycle pending → in_flight → succeeded | failed | reversed. Methods: card_charge, card_push, on_chain.

Saga

card_to_crypto composes two legs with compensation. States: pending → leg1_in_flight → leg1_succeeded → leg2_in_flight → succeeded, or compensating → failed.

Identity

Human sessions (argon2id + opaque session cookie) and M2M API keys with RBAC scopes evaluated per route.

Audit

Append-only audit events chained by hash; a verification endpoint recomputes the chain to detect tampering.

Notifications

Transactional email through the notification service; verification, password reset, API key created and security alerts.

Webhooks

Outbound events signed HMAC-SHA256 in Stripe style (t=, v1=), delivered from a transactional outbox with retry.

Push

Device token registration → dispatch → Expo Push API → opaque payload {transfer_id} on iOS and Android.

Platform

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.