Skip to content

Releases: jesuspirate/chama

v3.5.0

15 Jun 14:49
v3.5.0
5773736

Choose a tag to compare

No stacking the deck

v3.5.0 · arbiter integrity — soft, additive, client-side.

Two guardrails around the one role that could quietly tilt a trade: the arbiter. You'll almost never see either — they only surface when something's off. No change to how an honest trade works.

What's protected

  • The judge has to be the assigned one. A trade's arbiter is meant to be assigned fairly, not hand-picked. The app now checks that on every trade — and if the seated arbiter isn't the one the trade should have drawn, it shows a loud warning (naming who's seated vs who should be) before you pay or deliver, and asks you to acknowledge the risk before you act. Backing out is never blocked, and an honest trade never trips it.

  • A community can't rubber-stamp itself. The green "verified" badge now refuses to appear when the people vouching for a trade's arbiters are themselves parties to the trade. Vouching has to come from someone who isn't in the deal.

Honest about the edge

Same-key self-vouching is closed. A determined two-identity setup (one key vouches, another trades) can still earn the badge — closing that fully needs the federation-owner credential, which is on the roadmap. We log it as a known item in our public threat model (INVARIANTS.md) rather than overclaim.

Compatibility

Client-side only — the escrow reducer and wire format are untouched (verified). No consensus change, nothing to coordinate, existing trades unaffected. By construction this release cannot strand a sat: its only failure modes are a mis-fired warning or a badge call.

Numbers

2,453 tests green; typecheck clean; classifiers verified live in the served bundle; hardened by an adversarial review that confirmed the consent layer is sufficient, caught a three-era assignment-history subtlety, and surfaced the residual above.

v3.4.0

12 Jun 22:58
v3.4.0
1a71c12

Choose a tag to compare

Nothing left behind

v3.4.0 · fund safety — soft & additive.

The release with no visible feature and the one you'll be glad is there. Five hardening fixes to the money path, so a hiccup, a race, or a closed tab can never quietly cost you sats. Honest trades are completely unaffected — this is pure safety net.

What's safer (under the hood)

  • Your wallet can't be raced. Every operation that touches your ecash now takes an exclusive lock — so two open tabs, or a background cleanup colliding with a payment, can't corrupt the one wallet they share.

  • "Done" means the money actually arrived. A payout is never reported as claimed unless your wallet was truly credited — no more "already spent" mistaken for success.

  • Stranded sats show up — loudly. If a payout's notes get stuck after a hiccup (a federation switch, a failed redeem), they now surface as a clear alarm with a one-tap export to safety, instead of sitting silently in storage where a data-clear could lose them.

  • Your cash is never wiped on a guess. The app refuses to clear a wallet whose balance it couldn't positively confirm is zero — if it can't check, it asks.

  • Claiming tries every path. Collecting your sats now tries every valid route before giving up, so one bad envelope can't strand a winner.

Compatibility

No escrow, vote, or wire-format changes — verified, the reducer is byte-for-byte untouched. Existing trades, balances, and listings are unaffected.

Numbers

2,426 tests green; typecheck clean; hardened by a 44-agent adversarial review that found and fixed 2 real issues before release — and honestly documented one low-probability residual in the code rather than hide it.

v3.3.1

12 Jun 02:19
v3.3.1
11784db

Choose a tag to compare

In your money

v3.3.1 · local-first polish + steadier connections — soft & additive.

Chama's tagline is local money, Bitcoin rails. This one makes the local money part real: the price and the payment methods now speak your community's currency and context instead of a generic global default. Plus a quiet fix to how connections clean up.

Local-first

  • The price is in your money. When your Chama has a local currency, the Bitcoin price quotes in it — BTC/KES, BTC/XOF — instead of always BTC/USD. (Falls back to USD when there's no rate available.)

  • Your payment methods come first. Me → Payment methods now leads with the rails people actually use where you are; a search reveals the full global catalog for the edge cases. Same on Create — compact local toggles, with "search more payment methods" when you need them.

Steadier connections

  • Connections clean up for real. Closing a relay connection now truly stops it, so a closed socket can't quietly schedule a reconnect behind your back. Hot-reload cleanup closes old sockets while keeping your Fedimint session intact.

  • Honest status. The bar now shows your selected Chama and its reconnect state instead of briefly pretending you hadn't picked one.

Under the hood

Pure UI + connectivity — no escrow, consensus, or wire-format changes.

v3.3.0

11 Jun 15:04
v3.3.0
87c236a

Choose a tag to compare

Quietly safer

v3.3.0 · consensus hardening — coordinated release, nothing visible changes.

Nothing to see here, and that's the point. Two under-the-hood tightenings to the trade engine that make edge cases safer without touching how you trade. Because they adjust consensus rules, this ships on its own (the v2.9 pattern) — update when you can, so every client is reading the same rulebook.

What changed (under the hood)

  • Dispute clock, bounded. A vote's self-stamped timestamp can no longer push a dispute's escalation timer absurdly far into the future. Honest trades are completely unaffected — this just closes a future-dating edge so an arbiter's window can't be frozen.

  • Arbiter fee, sanitized. A malformed arbiter fee on a crafted trade is now coerced into a safe [0, amount] range instead of trusted — closing a latent drain before fees ever pay out. Your real trades never touch this path, and a fee is clamped, never rejected, so nothing can strand mid-trade.

Compatibility

Coordinated release: these adjust consensus computation, but honest chains see zero difference — existing trades, balances, and listings replay identically. No wire-format change. Update promptly so all clients share the same rules.

Numbers

2,384 tests green (new invariant_* asserts pin both fixes); typecheck clean; the reducer changes were independently re-verified line-by-line before release.

v3.2.1

11 Jun 03:04
v3.2.1
d931287

Choose a tag to compare

Smoother

v3.2.1 · polish — soft & additive.

A small, comfortable one — no new machinery, just less friction in the places you touch every day.

What's better

  • More ways to get paid, easier to manage. Your saved payment methods in Me got a real rework — quicker to add, cleaner to manage, with more rails to choose from.

  • A simpler funding pane. The fund/lock step is tidier and reads at a glance instead of sprawling.

  • Trade IDs on every card. Each listing now shows its trade ID, so you can spot or reference a specific trade instantly.

  • Tidier trade chat. On a relisted trade, a participant whose hold expired no longer lingers in the chat — messages stay scoped to the people actually in the trade.

Under the hood

Pure UI + payments + chat-scoping polish — no escrow, vote, or wire-format changes. Existing trades, balances, and listings are untouched.

v3.2.0

10 Jun 20:29
v3.2.0
987db00

Choose a tag to compare

Your seat, your move

v3.2.0 · the trade room, in full — soft & additive.

v3.1 redrew the trade room around one question — what do I do right now? v3.2 finishes the job: now every seat sees that answer in every state, in its own color, and never reads a word that isn't true. Buyer, seller, or arbiter; building, locked, disputed, or done — the card tells you exactly your situation and your one move, the community arbiter watches over the whole trade, and your reputation finally shows up.

Compatibility: SOFT — additive only. No escrow, consensus, or wire-format change; pure UI. Existing trades, balances, listings, and communities are untouched.

🎴 One card, every seat, every state

  • The action card wears your role color in every state — buyer violet, seller orange, arbiter blue (error red stays sacred; visitors keep neutral tones).

  • Every move lives inside the card now — join, fund, vote, claim — so there's one place to look and one thing to do.

  • The full matrix tells the truth end to end: a marketplace seller waiting on a buyer's cart no longer reads "waiting to fund"; a refund winner never reads "released — your sats are yours"; a pool-backup arbiter stepping in is told "the assigned arbiter is absent — you hold the third key now."

🛡️ A guardian, not a bystander

  • The arbiter's card reframes to the truth: you watch over both sides the whole way — you only act if they disagree. The trade chat is one tap away for the arbiter at every stage (encrypted to all three from the first message), so a silent party can't game a settlement after the other side has performed.

  • During a dispute the room shifts: the header reads "A call is needed," the tally flips to amber VOTES ON RECORD, and the ruling buttons name the destination — Release → {name} / Refund → {name}, in the recipient's color.

👍 Reputation, made real

  • Rate your counterparty 👍/👎 on any settled trade — and now it actually lands and sticks (it quietly never did before).

  • Tap anyone's avatar in a trade to see their record — 👍 N · 👎 M · from K settled trades — and your own reputation card lives in Me. Verified-only: a rating counts only if it references a real settled trade you were part of.

🔧 Fixed & sharper

  • A trade past its deadline now reads honestly — "past deadline — a refund vote heals it" — instead of "locked and quiet" above a live refund button.

  • Your chat history stays whole across reloads (it used to collapse to the last message), oversized images fail loudly instead of vanishing, and sellers can tap 📦 Mark delivered.

  • A floating button on Browse to create a listing or step up as a community arbiter, with the application right there inline.

✅ Numbers

2,339 tests green; typecheck clean; zero escrow / consensus / wire logic touched. Hardened by a 24-agent adversarial review that caught and fixed 13 real findings before this shipped.

v3.1.0

09 Jun 23:03
v3.1.0
c9236b7

Choose a tag to compare

Know your move

v3.1.0 · the trade room, redrawn — soft & additive.

This is the release where a Chama trade stops being a wall of controls and becomes a room you can read. Every trade now answers one question first — what do I do right now? — and answers it in your own color. Underneath, every seller can open a storefront, and the Bitcoin/Global federation quietly steps back into the role it was always meant for: the rail, not the place.

Compatibility: SOFT — additive only. No escrow, consensus, or wire-format change; existing trades, balances, listings, and communities are untouched. Ship and forget.

🧭 The trade room, redrawn

The whole screen is rebuilt around four calm zones:

  • A progress spine — Reserved → Locked → Settled — with a sweeping beam that always points the way forward. Nothing moves backward; every message, receipt, and vote nudges you right.

  • One action card tells you the single thing to do right now, in your role's color — buyer violet, seller orange, arbiter blue. Your view wears your color.

  • An elastic deal slot that opens into the full cart while you build, shows the 2-of-3 trinity the moment it matters, and otherwise folds to a quiet one-liner.

  • Everything else — the "how your money's protected" explainer, chat, history — tucks into one-tap drawers, so the screen is loud about exactly one thing.

🏪 Every seller is a store

Creating a listing now asks one more thing — single, or a storefront? — named for what you're doing: One swap / Curated swaps, Single / Storefront, One loan / Loanbook, and Single bill / Monthly bills (recurring bills, coming soon). Storefront listings wear a storefront mark on Browse. Sell goods, anywhere, for sats — no BTCPay server, no Zaprite account, backed by your community's arbiters.

🌍 Honest places

  • You start with your country. "Global" is gone as a place to pick — the Bitcoin/Global federation steps back to being the quiet backup rail that powers countries without their own Chama yet.

  • Listings now carry their country, so an offer from anywhere shows its flag on every device — even the very first listing in a brand-new country.

  • A quick create + arbiter-recruitment on Browse, and a "run your own federation?" path that puts the people best placed to anchor a community — the ones who built the rails — front and center.

✨ Smaller, sharper

  • Leave cleanly. Joined a trade by mistake? Back out with one tap before anything's locked — nothing is at risk until sats move.

  • Dropped a confusing pre-lock payment nag that only added a step.

  • The arbiter now reads in its true sky-blue everywhere.

✅ Numbers

2,336 tests green; typecheck clean; zero escrow / consensus / wire logic touched (pure UI + listing-layer), adversarially reviewed stage by stage.

v3.0.0

08 Jun 18:45
v3.0.0
637ab56

Choose a tag to compare

Stands on its own

v3.0.0 · a milestone, not a migration — soft & additive.

Why 3.0: this is the release where Chama stops needing a village around it. You
can open the app cold, hold your own keys, pick your flag and currency, trade on
Bitcoin rails, recover your whole account from a single key — and now be tapped
on the shoulder the moment a trade needs you — without a local arbiter, and
without a Chama yet existing in your country. The major-version bump marks that
line being crossed, not a breaking change.

Compatibility: SOFT — additive only. No wire-format, trade-protocol, or
vote-acceptance change. Notifications are entirely client-side; the wrong-chama
fix is create-time labeling. Existing trades, balances, listings, and
communities are untouched — ship it and forget it.

🔔 Chama can reach you now

The gap that made Chama feel like a page you had to babysit is closed. It now
buzzes you when — and only when — a trade actually needs you:

  • Your counterparty locked the sats. The other side funded; your move.
  • Your payout is ready to claim. The trade resolved your way — come get it.
  • A dispute needs your ruling. (arbiters) Both sides voted and disagreed —
    you're up.
  • Settled, or timed out. The trade completed, or expired and refunded — so
    you can stop checking.

One switch in Me turns it all on or off. It asks for notification permission
only when you flip it on — no cold permission wall on first launch — and it
can't double-buzz: each moment fires once, and only after the app actually has
your state (no alert-storm when it reloads your history). Works on Android, in
the desktop app, and in the browser.

🛑 The wrong-chama guardrail now actually fires

The amber "you're off your home route" warning on Browse is a safety rail — it's
what stops you acting in a federation that isn't the listing's. It had a blind
spot: visiting a foreign listing could stamp a new listing with one chama's
LABEL but another chama's actual federation, so the chip read (say) "GBF" while
the off-route tint — which tracks the real fed — never lit up. Create-time now
keeps the label honest with the fed the sats are actually minted on, so the
guardrail fires every time it should. (#103)

🪟 Desktop, honestly labeled

  • Windows and Linux bundles are attached to the release, under
    plain-language, ordered names. Windows is unsigned for now, so it shows a
    one-time SmartScreen "unrecognized app" notice — click More info → Run
    anyway
    . Linux (deb / AppImage) runs clean.
  • The macOS dmg is held back on purpose. An unsigned, un-notarized Mac app
    hits Gatekeeper's "damaged" dead-end with no click-through for a normal user,
    so shipping it would just mislead people. It still builds every release as a
    validation gate, and goes public the moment it's signed + notarized. Until
    then, mobile (Zapstore) and the web app are the real surfaces.

✨ Two things that were bugging us

  • Toasts don't ghost anymore. The little confirmations — switching chama
    especially — were ~13% opaque and blended into whatever was behind them.
    They're solid now: an opaque card with a colored outline and a soft shadow,
    readable over anything.
  • Returning sign-in reads right. Pressing "I'm a returning Chama citizen"
    used to leave "Chama creates a private recovery key on this device…" sitting
    above the paste box — create-talk over a recover action. It now swaps to
    "Paste the recovery key you saved when you first set up Chama," and keeps the
    original line for people actually creating an account.

✅ Numbers

2,335 tests green (19 new, covering the notification core's role-aware
transitions and its fire-once dedup); typecheck clean; production build clean.

v2.10.0

08 Jun 12:42
v2.10.0
0dbf743

Choose a tag to compare

Your word, on the record

v2.10.0 · additive — ship and forget.

Compatibility: SOFT — additive only. A new ratings event kind (38123) that old
clients simply never query, plus onboarding and cosmetic UI. No wire-format,
trade-protocol, or vote-acceptance change. Existing trades, balances, listings,
and communities are untouched, and nothing here needs a coordinated update —
ship it and forget it.

Ratings — reputation, one tap at a time

  • Every settled trade now ends with a single 👍 / 👎 about the other party. One
    tap, never a form, never a blocker — and it's a GENERIC primitive: the same
    event rates a buyer, a seller, or an arbiter, so one system feeds everything
    that needs reputation.
  • It survives the rush. People bolt the moment they have their sats, so the
    rating isn't trapped on the success screen: every settled-but-unrated trade
    keeps a one-tap thumb in Me, so you can vouch (or warn) later. Rate now or rate
    next week — it lands in the same slot either way, and you can't stuff one trade.
  • It's a rating you can trust. A vote only counts if it references a SETTLED
    escrow the rater was actually a party to (same verify-don't-trust posture as
    the arbiter roster) — fake ratings on trades you weren't in, or that never
    settled, are dropped. The numbers you see are verified, not asserted.
  • It already does something: a seller who's earned a clean record (5 positive,
    none negative) graduates to subscription listings, and your own tally now
    shows in Me — including an arbiter's. The bigger consumers (rating-tiered
    arbiter assignment, amount caps) build on this keystone next.

Put yourself on the map

  • The "no Chama here yet — make one" tap during onboarding used to error out for
    new accounts (it tried to sign before you had a key). Now it does the right
    thing: it remembers your request, lands you on your own flag and currency, and
    the moment you sign in, reframes to "Sign in to put yourself on the map — we'll
    tell the Chama arbiters that {your country} wants in," then quietly publishes
    it. The generic "Chama not listed?" form behaves identically.
  • A quiet but important follow-through: a community shell you spin up before
    signing in now gets stamped with your key the instant you do — so even a brand-
    new country community can carry a verifiable arbiter roster down the line.

Polish

  • Two different federations no longer look the same on Browse. Each can carry its
    own chip accent — BLF reads indigo, GBF reads teal — hand-picked to never
    collide with the role colors or status pills. (The amber "off-route" tile
    still wins; that's routing, not identity.)
  • Desktop downloads got legible. The release page now lists the bundles in a
    sensible order with plain-language names — macOS, Windows, then the two Linux
    side by side — so a non-technical downloader knows which file is theirs.

Numbers

  • 2,316 tests green (the full union: v2.9's fix + 22 ratings + 17 onboarding
    assertions, run together for the first time); typecheck clean; production
    build clean. Ratings verified end-to-end; onboarding driven through a live
    first-run flow (request queued pre-login → account created → shell stamped →
    report published).

v2.9.0

08 Jun 11:08
v2.9.0
eefec06

Choose a tag to compare

v2.9.0 — Silence stops paying

Compatibility: COORDINATED — please update. No wire-format change (the events
are identical), but this release changes which arbiter votes the rules ACCEPT
during a disputed, expiring trade. Existing trades, balances, listings, and
communities are untouched, and a normal trade behaves exactly as before. The one
place it matters: a CONTESTED trade that reaches its deadline now resolves by an
arbiter's ruling instead of an automatic refund — and an old client would still
expect the old automatic refund. So everyone in a dispute should be on v2.9
before the deadline. The app now says so, in the trade, at exactly that moment.

The hole we closed

  • A seller could win by doing nothing. Seller locks the sats, buyer sends the
    fiat and votes to release — and then the seller simply goes quiet until the
    trade expires. The old expiry rule always refunded whoever locked, so the
    silent seller got the sats BACK while keeping the buyer's fiat. Both sides of
    the money, zero effort, no message required. That's now closed.

How it's closed

  • A standing "release" vote from the party who performed turns an expiry from an
    abandonment into a CONTEST. Once a performer has voted release and the other
    side stays silent past a short, trade-length-proportional deadline, the
    deadline no longer auto-refunds the locker — the assigned arbiter (or a backup,
    through the same gate) can rule on the merits. Showing up is the only way to
    win; silence isn't.
  • The safety valve that keeps this honest: if the arbiter rules REFUND — i.e.
    finds the performer didn't actually perform — the locker's refund completes
    normally. So a buyer can't vote "release" without paying to freeze a seller's
    sats forever; the worst they achieve is a trip to the arbiter, at the cost of
    their own reputation. Two-of-three is never weakened, and no settled vote is
    ever rewritten.
  • Abandonment still works the way it should: if nobody performed (the buyer
    never voted release), the deadline still auto-refunds the locker. The fix only
    bites when one side performed and the other ghosts.

In the trade, at the right moment

  • Once a release vote is standing on a locked trade, the expiry banner stops
    promising an automatic refund and reads: "At the deadline this goes to an
    arbiter, not an automatic refund. Make sure everyone in this trade is on the
    latest Chama, so the decision settles the same for all." Non-contested trades
    keep the familiar refund-at-expiry banner, untouched.

Why a coordinated release (the honest version)

  • Every change since v2.0 has been additive — new clients saw more, old clients
    saw less, nobody disagreed. This one is different: it changes a rule about
    which votes are valid, so a new client and an un-updated client could read the
    same contested-expired trade differently until both update. That's why this
    ships on its own, why the in-trade nudge exists, and why these notes lead with
    "please update." The new deadline is derived purely from the trade's own event
    chain (replay-deterministic, same discipline as arbiter substitution), so once
    everyone's updated, every client lands on the identical answer with no
    coordinator.

Numbers

  • 2,277 tests green (+22 for this fix: the theft closed, the freeze that can't
    happen, abandonment still refunds, the marketplace inversion, and the deadline
    always landing before expiry); typecheck clean; verified by an independent
    multi-angle adversarial review (theft / freeze / two-of-three integrity /
    cross-version divergence) that found nothing.