Balance Service
Global wallet model
Why @downcity/services stores balance by user instead of creating one wallet per downcity.
@downcity/services keeps balance by user, not by downcity.
By default, credits are USD-linked:
1 credit = 1 USD1 credit = 1,000,000 microcredits- user-facing
GET /v1/balance/mereturnsbalancein credits, plusmicrocredits,display, andconversion - admin and internal accounting fields still use microcredits
That means:
- user A spends inside downcity X
- user A spends inside downcity Y
- both consume the same shared balance
Why this fits Downcity better
The typical Downcity shape is:
- one Federation serving multiple products
- the same user moving across those products
- one shared AI account layer behind them
If balance is split per product, both product UX and operations become fragmented.
Does downcity still matter
Yes, but it belongs in ledger metadata rather than in the wallet primary key.
await balance.sub(ctx.user!.user_id, 10, {
note: "agent chat",
meta: {
city_id: ctx.downcity?.city_id,
model_id: ctx.variant?.id,
},
});That keeps the wallet global while still preserving where the spend came from.