Humanitarian cash programs need a secure bridge between field enrollment, donor reporting, and Soroban program rules—this API is that bridge.
ReliefFlow uses beneficiary-registry, aid-escrow, and fraud-challenge to encode eligibility, treasury tranches, and integrity workflows on-chain. Real-world programs also need PII-minimized databases, feature-phone OTP flows, NGO SSO, and donor dashboards—this Fastify service hosts those patterns without leaking secrets or bulk personal data into static frontend JS.
These come from the root README — shared context for why Stellar/Soroban exists here:
- Cash aid programs struggle with duplication, exclusion errors, and delayed reconciliation.
- Donors demand traceability without exposing vulnerable populations.
- Multiple agencies often lack interoperable accountability standards.
The smart contracts hold truth on-chain; they cannot safely hold ERP passwords, IoT vendor keys, bulk files, or cron jobs. That is this service’s job:
- PII boundary: National IDs and biometrics must stay in encrypted stores—never
NEXT_PUBLIC. - Field integrations: Mobile money aggregators and SMS gateways require server-side callbacks.
- Donor assurance: Aggregate reporting with cryptographic anchoring to milestones—computed here.
- Duplicate detection: Risk scoring across datasets belongs in controlled services with appeals workflows.
- Maintain beneficiary records with privacy-preserving design choices (
beneficiary-registry). - Run campaign treasuries with tranche logic (
aid-escrow). - Enable integrity workflows—challenges, appeals, audits (
fraud-challenge). - Publish impact views that aggregate outcomes without unsafe micro-data exposure.
- Enrollment APIs: Session-based intake with audit trails; optional duplicate-detection hooks.
- Tranche orchestration: Align treasury movements with
aid-escrowstates. - Integrity desk: Case management hooks feeding
fraud-challenge. - Webhooks: PSP settlement confirmations → chain reconciliation jobs.
| Crate | What the HTTP layer typically does |
|---|---|
beneficiary-registry |
Map operational beneficiary IDs to on-chain identifiers using minimal disclosure strategies. |
aid-escrow |
Coordinate funding rounds and releases with treasury approvals. |
fraud-challenge |
Attach investigator notes and outcomes to dispute flows—off-chain case file + on-chain resolution tx. |
| Layer | Choice |
|---|---|
| HTTP framework | Fastify 5 — low overhead, schema-friendly |
| Language | TypeScript (strict, ESM, verbatimModuleSyntax) |
| Config | Zod parsing in src/config/env.ts |
| Blockchain | Stellar Horizon + Soroban RPC (server-side keys only) |
| Consumers | apps/web, partner systems, cron workers |
apps/backend/
├── .env.example
├── package.json
├── tsconfig.json
├── README.md
└── src/
├── index.ts # Fastify bootstrap, CORS, route registration
├── config/env.ts # Typed environment
└── routes/
├── health.ts # GET /health
└── v1/index.ts # Versioned API surface (expand here)
- Node.js 20.x or 22.x (LTS)
- npm (or pnpm/yarn per org standard)
cd apps/backend
npm install
cp .env.example .env
# Edit .env — see tables below
npm run devDefault: http://localhost:8080 · Health: GET /health · Meta: GET /api/v1/meta
# Terminal A — API
cd apps/backend && npm run dev
# Terminal B — Web
cd apps/web && npm install && npm run devSet CORS_ORIGIN in .env to match the web origin (e.g. http://localhost:3000).
| Command | Purpose |
|---|---|
npm install |
Install dependencies |
npm run dev |
tsx watch — reload on change |
npm run build |
Compile to dist/ |
npm start |
Run compiled server |
npm run lint |
tsc --noEmit typecheck |
| Variable | Default | Purpose |
|---|---|---|
NODE_ENV |
development |
Environment name |
PORT |
8080 |
Listen port |
API_PREFIX |
/api/v1 |
Prefix for versioned routes |
CORS_ORIGIN |
http://localhost:3000 |
Browser origin allowed by CORS |
| Variable | Example | Purpose |
|---|---|---|
PII_DATABASE_URL |
(secret) | Encrypted Postgres/SQL—network isolated. |
PAYMENT_PROVIDER_* |
(secret) | Mobile money credentials. |
SOROBAN_RPC_URL |
https://… |
Chain access. |
| Method | Path | Description |
|---|---|---|
| GET | /health |
Liveness for load balancers & CI |
| GET | /api/v1/meta |
Service name / version |
POST /api/v1/enrollment/sessions— begin enrollment with consent artifacts.POST /api/v1/tranches/release— operator workflow prior to Soroban submit.GET /api/v1/impact/summary— donor-facing aggregates.
npm run lintCI should mirror this (see .github/workflows/ci.yml).
Add contract integration tests in the Rust workspace and API integration tests (e.g. vitest + supertest) as routes grow.
- Run behind TLS termination (load balancer or reverse proxy).
- Store signing keys in KMS/HSM, never in repo.
- Restrict Soroban RPC by IP allowlist or private gateway when possible.
- Emit structured logs (JSON) with request IDs for regulator audits (especially MediProof / CivicLedger / ReliefFlow).
See ../../CONTRIBUTING.md. Contract changes must stay aligned with this API’s eventual routes and ../../docs/SITE_MAP.md.
Match the repository license (Apache-2.0 suggested for OSS grants — confirm per org).
| Doc | Link |
|---|---|
| Monorepo overview | ../../README.md |
| Frontend | ../web/README.md |
| Architecture notes | ../../docs/layout-plan.md |
| Milestones → issues | ../../docs/milestones-issues.md |
Package: reliefflow-api · Slug: reliefflow