The μCoin & μStore economy for μLearn, as a standalone service. Double-entry integer ledger, milestone emission with a published epoch schedule, partner coin pools with earn rules, invite staking, and a redemption store — coupled to μLearn core only by the event/API contract in INTEGRATION.md.
Design decisions and the full architecture live in docs/mucoin-integration-rfc.md. The one-line version: μLearn core emits signed events; this service turns them into coins; coins never flow back — nothing here can touch Karma, levels, or rankings.
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python manage.py migrate
.venv/bin/python manage.py seed_demo # epochs + TTS pilot + store catalog
.venv/bin/python manage.py test # 24 tests
.venv/bin/python manage.py runserverSQLite by default; set MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD/MYSQL_HOST
for MySQL (and install mysqlclient). In dev (DEBUG=1), the X-Debug-Muid
header stands in for a real μLearn JWT on learner endpoints.
Try it:
# Simulate a learner hitting Level 4 (signed the way core's dispatcher signs)
.venv/bin/python scripts/send_event.py user.level_up '{"muid": "anu", "old_level": 3, "new_level": 4}'
curl -s -H "X-Debug-Muid: anu" localhost:8000/api/v1/wallet # → 3 coins
curl -s localhost:8000/api/v1/economy/summary # board numbers| Endpoint | Auth | Purpose |
|---|---|---|
POST /api/v1/events/ingest |
HMAC (X-Mu-Signature) |
μLearn-core domain events (the faucet trigger) |
GET /api/v1/wallet · /wallet/history |
μLearn user JWT | Balance and statement |
GET/POST /api/v1/stakes |
μLearn user JWT | Invite staking (1 coin locked, 90-day window) |
GET /api/v1/store/items |
— | Catalog |
POST /api/v1/store/redeem · GET /orders |
μLearn user JWT | Redemption (burns coins) and order tracking |
GET /api/v1/partner/pools |
X-Partner-Key |
Pool balance + aggregated engagement (no learner PII) |
POST /api/v1/partner/events |
X-Partner-Key |
Partner-verified completions (e.g. TTS scoring) |
GET /api/v1/economy/summary |
— | Issued/circulating/burned/escrow, liability reserve, epoch |
/admin/ |
Django staff | Catalog, pools, policies; ledger is read-only |
- Ledger invariants are enforced in
ledger/services.post— balanced transactions, non-negative wallets/pools/escrow, idempotency by key. It is the only write path; nothing else creates ledger rows. - Daily job:
manage.py expire_stakes(cron or Celery beat) burns stakes past their 90-day window. - Secrets:
MULEARN_WEBHOOK_SECRET(event HMAC, shared with core's dispatcher) andMULEARN_JWT_SECRET(verifies μLearn user JWTs). SetDEBUG=0in production — it also closes theX-Debug-Muiddoor. - Emission schedule is data (
EmissionPolicyrows, seeded byseed_demo): epochs advance automatically on cumulative Level-4 mints.