Agent-native compliance and settlement for African markets.
Afron is the regional on-ramp that lets x402-enabled AI agents pay African data and service providers with identity, sanctions, and audit trails built for machine traffic — plus optional NGN payout for partners who want local currency rather than holding stablecoins.
See docs/adr/0001-system-architecture.md for architecture decisions.
| Layer | What’s in |
|---|---|
| API | FastAPI, Postgres, Redis, Alembic |
| Settlement | x402 (Base / EIP-3009), compliance gate, NGN bridge |
| Discovery | Provider directory + reputation |
| Web | React + TypeScript + Tailwind (landing + partner console) |
docker compose up --build- API: http://localhost:8000
- Health: http://localhost:8000/api/v1/health
- Docs: http://localhost:8000/docs
Migrations run automatically on API container start (alembic upgrade head).
cd frontend
npm install
npm run dev- Landing: http://localhost:5173
- Partner console: http://localhost:5173/login
Vite proxies /api to http://127.0.0.1:8000. Start the API first.
Dashboard login: POST /api/v1/auth/dashboard/login (email + optional DASHBOARD_ACCESS_CODE).
python -m venv .venv
# Windows: .venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
docker compose up postgres redis -d
alembic upgrade head
uvicorn app.main:app --reloadWith Postgres up and migrations applied:
python scripts/seed_demo.py
# re-seed cleanly:
python scripts/seed_demo.py --resetCreates listed providers, completed settlements, NGN payouts, a flagged compliance item, and recomputes reputation — so the landing page stats and partner console trail look real.
Then:
uvicorn app.main:app --reloadcd frontend && npm run dev- Open http://localhost:5173 → login with any email → drill a transaction
pytestOptional live Postgres migration test:
set TEST_DATABASE_URL=postgresql+asyncpg://bridge:bridge@localhost:5432/agent_bridge
pytest app/tests/test_migrations.py -k postgres| Client | Scheme | Headers |
|---|---|---|
| Agents (machines) | API key + HMAC-SHA256 | X-API-Key, X-Timestamp, X-Signature |
| Dashboard (humans) | JWT Bearer | Authorization: Bearer <token> |
Canonical HMAC message:
METHOD\nPATH\nTIMESTAMP\nSHA256(body)
All config via env vars — see .env.example. Never commit secrets.
- Service: API (this repo, Dockerfile)
- Plugin: PostgreSQL in the same project
| Variable | Value |
|---|---|
DATABASE_URL |
Variable reference from Postgres → DATABASE_URL (private network preferred) |
JWT_SECRET_KEY |
Long random string |
APP_ENV |
prod |
APP_NAME |
Afron |
CORS_ORIGINS |
Your frontend origin(s) |
Afron auto-converts postgresql:// → postgresql+asyncpg://.
SSL is enabled for public Railway proxies; disabled for *.railway.internal (private).
- Entrypoint runs
alembic upgrade headthen listens on$PORT(Railway requirement). - Health:
/api/v1/health→"database":"ok".
- Deploy logs: search for
migrations failedordb_engine_init. - Confirm
DATABASE_URLis on the web/API service (Shared Variables / reference). - Prefer private URL (
postgres.railway.internal) over public TCP proxy when both services are on Railway. - Redeploy after latest
main(SSL + PORT fixes).
Use the Postgres public URL from your laptop if needed:
DATABASE_URL=postgresql+asyncpg://... python scripts/seed_demo.pyAfron — Africa + on-ramp. Tagline: The agent-native compliance and settlement bridge for African markets.