Every number has to prove itself.
Privvy Ledger makes two promises: the numbers in your ledger are right, and they stay on your phone. Both are engineering decisions rather than intentions, so here is the machinery behind them — in enough detail to argue with.
The statement states its own totals. The parser has to reproduce them exactly.
How do you know it read your statement correctly?
Reading a Nigerian bank statement
Each bank prints a different layout, so each needs its own row reconstruction — four are handled today, and more are added as real statement samples come in. The hardest is OPay's PDF, which scatters a row's description and its 24-digit reference across the lines above and below it, leaving about a quarter of rows with no text of their own. Rebuilding them is a claim-your-neighbour problem: a stray line belongs to whichever adjacent row is missing its description, and if both already have one, the line is reference noise. On the real 128-row sample, no row was left blank.
Why the numbers can be trusted
If any of it disagrees, you are told before a single row is written, and the import is not offered. The worst case is the ledger you already had, not a ledger that is quietly wrong. One limitation worth stating plainly: a row whose description is only partially inline keeps just that part, because letting it claim neighbouring lines risks stealing the row next to it. The merchant name survives, which is what the auto-tag rules match on.
Receipts, scanned without a network
The parser is a pure module with a regression harness whose fixtures are frozen text from real scans of Nigerian bank receipts — LAPO, GTCO, OPay, FirstBank, Access, PalmPay. Every format that ever parsed wrong is now a permanent test. Nothing from a scan is kept: the image and the recognised text fill in the form and are then gone. Neither is ever written to the database.
Check it yourself — Turn on airplane mode and scan a receipt. It works, because none of it needed the network.
How do you know it stays on your phone?
Where your money actually lives
Amounts are stored as whole minor units in an integer column — kobo, cents — never as floating point, because a finance app that stores 0.1 + 0.2 has already lost. How many decimal places a currency has is derived per currency rather than assumed to be two, so the Japanese yen gets none and the Kuwaiti dinar gets three.
The lock on the front door
Fingerprint and Face ID are handled entirely by the operating system; the app receives a success or failure and never sees anything biometric. Auto-lock is a timer you set — immediately, 30 seconds, a minute, five, or never — measured from the moment the app goes to the background.
Backups, and what they cost you
The round count dropped from 100,000 to 10,000 in September 2026, and that is worth defending rather than quietly shipping: the ledger itself sits unencrypted in the app's private storage, protected by the OS sandbox rather than a password, so a backup file was never the weaker link — the ninety thousand extra rounds mostly cost the person unlocking their own phone, not an attacker. The count travels inside each file, so a backup or snapshot written before the change still opens at whichever cost it was saved with.
That cuts both ways, and it is worth being clear about the price: because there is no copy on any server, a forgotten backup password cannot be reset by us or by anyone. The guarantee and the inconvenience are the same fact.
Check it yourself — Open a .plbackup file in a text editor. You will find a salt, an initialisation vector and ciphertext — and nothing readable.
Automatic snapshots, and the bug that shipped with them
What shipped to beta first was broken in the quietest way possible. A snapshot's key was derived straight from the PIN — needed so a wiped device could still open one with just the PIN — but a fingerprint unlock never asks for a PIN, so biometric-only users, which the lock screen defaults to, produced no snapshots at all. No error, no crash: the release notes said five, and some phones quietly had none.
The fix is envelope encryption. A random key, generated once, actually encrypts the ledger and lives in the device's secure hardware storage, so any unlock — PIN or biometric — can use it to write a snapshot. Every snapshot file separately carries that same key, sealed a second time under a key derived from the PIN. Wipe the device and only the hardware-stored copy is deleted; the files remain, still inert without the PIN. Restoring one is still not a way around the lock, which was the entire reason it was tied to the PIN to begin with.
Check it yourself — Turn on biometric unlock, then open Backup & Restore right after your very first unlock. A snapshot is already sitting there.
The one thing that leaves
No transaction, balance, budget, PIN or receipt is ever included, and there is no account or identifier tying any of it to you. It exists so bugs get fixed, and it is declared in the app's Play Store data safety section. Everything else stays where you put it.
The rule underneath all of it
Nothing leaves your device unless you explicitly ask it to. Features get built around that rule rather than the other way round, which is why the statement parser, the receipt scanner and the backup encryption all run on your phone. The full detail of what is and is not collected lives in the privacy policy.