Digital infrastructure for Kenya's rotating credit associations (chamas/ROSCAs) — domain model, ledger, M-Pesa integration.
# chama-protocol
**Digital infrastructure for Kenya's rotating credit associations.**
A chama is a self-organized savings and investment group. Kenya has over 300,000 registered chamas — from neighbourhood welfare groups pooling KES 500 each to diaspora investment clubs managing millions of shillings from London, Dallas, and Nairobi simultaneously.
This library provides the core domain model for digitising chama operations. It is not a SaaS — it is the building block.
---
## What it models
```
Chama → Cycles → Rounds → Contributions
↓
Ledger (who paid, who owes, is the pot ready to disburse?)
```
- **Chama** — the group: members, officers, welfare fund
- **Member** — a seat in the rotation, phone number for M-Pesa
- **Cycle** — one complete rotation (everyone receives once)
- **Round** — one meeting: one person receives the pot
- **Contribution** — one payment, linked to an M-Pesa receipt
- **Ledger** — tracks contributions, identifies defaulters, determines when the pot is disbursable
---
## Quick start
```python
from chama.models import Chama, Member, Cycle, Round, CycleStatus
from chama.ledger import Ledger
from datetime import date, timedelta
# Build the group
chama = Chama(name="Umoja Investment Club")
members = [
Member("Grace Wanjiku", "0712000001", seat=1),
Member("Patrick Ochieng","0722000002", seat=2),
Member("Diana Mwangi", "0733000003", seat=3),
Member("Samuel Kimani", "0711000004", seat=4),
]
for m in members:
chama.add_member(m)
# Set up a cycle: KES 10,000 per member per round
cycle = Cycle(number=1, contribution_amount=10_000, start_date=date.today(), status=CycleStatus.ACTIVE)
for i, m in enumerate(chama.rotation_order(), start=1):
cycle.rounds.append(Round(
number=i,
recipient_id=m.id,
meeting_date=date.today() + timedelta(days=30 * (i-1)),
pot_amount=10_000 * chama.member_count, # KES 40,000 pot
))
chama.cycles.append(cycle)
# Record payments as M-Pesa receipts come in
ledger = Ledger(chama)
ledger.record_contribution(members[ …