bursa
orderbooks for the suite's bank currencies, settled atomically — this page is also the git repo.
Clone
This site serves the repository over git's dumb-HTTP protocol as plain static files (plain files — there is no git server here, or any server at all):
git clone https://git.ardegazu.ro/bursa.git
cd bursa
What it is
bursa is a currency exchange with no exchange in it: one encrypted log holds the book, every member's replica runs the same matching fold, and a trade settles as two bank-held escrow locks under one hashlock — either both sides are paid or neither is. Banks come from banca; a match obliges nobody until the money locks. Installable PWA — works saved to an iOS home screen, safe-area aware.
How it works
- No server. Browsers are
libp2p peers: they meet through a
circuit-relay-v2 node, discover each other via gossipsub, and upgrade to
direct WebRTC. The room secret lives in the URL fragment (
#…) and never leaves the browser. - Everything is end-to-end encrypted. Every peer pair is noise-encrypted end-to-end (even while frames still cross the relay), and room membership is proved with an AES-256-GCM sealed hello derived from the room secret — an undecryptable hello means you're not in the room. TURN with ephemeral credentials covers the stubborn NATs.
- Hosting without an origin server. The client is a static Vite build served as plain files — there is no backend anywhere. This page you're reading works the same way.
What's in the repo
client/src/app/ — the app
TODO: what your app code does. TypeScript, no framework: typed wire protocol plus the app's own logic and UI.
client/src/net/ — the p2p layer
A thin js-libp2p assembly: relay bootstrap from
/.well-known/ap2p, a room-scoped protocol with a sealed-hello
membership handshake, reconnection, and the six-method surface the app
consumes.
deploy/ — the publish pipeline
publish-repo.sh builds this very site: landing page + bare
mirror exploded to loose objects (static file servers and git's dumb-HTTP protocol
agree on "every path must exist"), with an anonymity gate that refuses to
publish identity-bearing bytes.
Run it yourself
cd client && npm install && npm run dev # :4173
# open two tabs on the same #room URL
Deploy: npm run build, then publish client/dist/ as
static files anywhere — IPFS, a CDN, a folder behind nginx. It needs nothing but
a libp2p circuit relay it's allowed to talk to (see src/app/config.ts).
Guarantees & limits, honestly
- The relay operator sees connection metadata, opaque room ids, and frame sizes/timing. Not content, not names, not what was said.
- Anyone with the room link can join — capability model. Guard the link like you'd guard the room.
- TODO: any app-specific trust caveats (who referees, what a malicious member could do).
- MIT licensed. Built on WebRTC and WebCrypto.