# portofel
The suite wallet: **all your money, from every bank you use, on one screen** —
live at **[portofel.ardegazu.ro](https://portofel.ardegazu.ro)**, repo published
at **[git.ardegazu.ro/portofel](https://git.ardegazu.ro/portofel)**.
[banca](https://git.ardegazu.ro/banca) shows one bank at a time; portofel holds
your whole **bank directory** — every capability link you've added — and opens
a headless banca member session per bank: one balance card each, the amount big,
the issuer visible, a **Send** button that pays any friend with an account
there (and says plainly, with the one honest offer, when a friend has none).
Installable PWA, safe-area aware, works from any static file host.
There is deliberately **no total across banks**: `<bankerA>.LEI` and
`<bankerB>.LEI` are different currencies with no exchange rate, so the wallet
is a list of per-currency rows with the issuer beside each — never one summed
number. And it looks like a wallet, not a chat: no rooms, no roster, no
composer — cards, amounts, a send sheet.
## Architecture
- **No server, and no room of its own.** A balance IS a fold over a bank's
encrypted OrbitDB log, so this app holds bank LINKS and replicates the logs
itself: `app/bankroom.cljs` opens ordinary banca member sessions — the same
rooms core ([ardegazu-rooms-kit](https://git.ardegazu.ro/rooms-kit)), banca's
salt for the bank's version, banca's fold compiled off the classpath from the
sha-pinned [ardegazu-banca](https://git.ardegazu.ro/banca) — one
implementation of BANK/1 and BANK/2, never a transcription. A portofel tab
and a banca tab in the same bank are indistinguishable on the wire.
- **The directory is the app's primary object** (`app/banks.cljs`, banca's
lobby shapes verbatim): links arrive by paste, by the bundled public banks,
by an explicit offer when a link lands in the URL fragment, by an explicit
import when banca shares its list through the identity record — and they
sync between your own devices over social-kit's sealed self-channel.
Forgetting a bank is not a withdrawal, and the screen says so.
- **A payment is banca's `pay`** — a wallet-kit order signed here, appended to
the bank's log, sequence slot taken from the fold (so a banca tab open on the
same bank stays coherent), provisional until the banker acknowledges it. The
interface speaks banca's money words — final / provisional / unpinned /
failed — and the three outstanding totals each carry their sentence.
- **ClojureScript, shadow-cljs builds** (deps.edn classpath, exact-pinned
compiler pair). `npm run dev` watches on :5173, `npm run build` produces a
static `client/dist/` with relative asset paths. The shared rooms core is
**not in this repo** — fix it in the kit, bump the pin here. Local and yours:
`lib/model.cljs` (the pure wallet decisions), `app/*`; vendored, never edited
here: `lib/mailbox.cljs`, `lib/selftest.cljs`, `i18n/runtime.cljs`
(dev/canon.tsv gates the drift).
- **Versioned PWA.** `client/version.json` is bumped by every release and the
in-app banner offers a one-tap update. Never flip the worker to
auto-update — the prompt+banner pair is the suite's update contract.
- **Hosting without an origin server.** `client/dist/` is pinned to IPFS, named
by IPNS and served straight from the gateway on the app's own domain
(DNSLink). The published repo works the same way
(`deploy/publish-repo.sh` + the shared `git.ardegazu.ro` source root).
## Develop
```bash
cd client && npm install && npm run dev # http://localhost:5173
```
(needs JVM ≥ 17 + the clojure CLI for shadow-cljs; `deps.edn` carries a `:dev`
alias with cider-nrepl, so `cider-jack-in-cljs` works out of the box)
From the suite workspace, `ardz dev portofel` stages the identity bridge and
serves the same watch, and `ardz relay` runs a local dev relay **plus mailbox**
on :9090 — needed to exercise offline delivery. Paste a bank link (mint one in
a dev banca) and the card walks connecting → folded → the balance.
`npm test` runs cljfmt, a full `:app` compile, the `:testlib` release and the
black-box suite (catalog parity + the no-`settled` and no-chat-vocabulary
gates, the paste/partition model, pending tracking, source hygiene).
## Deploy
```bash
ardz build portofel # shadow-cljs release + workbox → client/dist
ardz release portofel # bumps version.json, then pins to IPFS + IPNS
ardz publish-src portofel # anonymity-gated source mirror → git.ardegazu.ro
```
**Commit the `client/version.json` bump after every release**, or installed PWAs
never see the update banner.
Clone: `git clone https://git.ardegazu.ro/portofel.git`
MIT — see [LICENSE](LICENSE).