DEV Community

Sasmitha Ashinsana
Sasmitha Ashinsana

Posted on

Salli: my bank SMS became a budget while I did nothing ๐Ÿฆฅ

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission ๐Ÿฆฅ

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

In Sri Lanka, every card swipe, bill payment, salary credit and wallet top-up already sends you an SMS. My phone has years of them. It's a complete record of where my money went and I've never once read it.

Every budgeting app I tried wanted one of two things: type every expense in by hand or hand my bank login to a cloud service. I'm too lazy for the first and too paranoid for the second.

So I built Salli (เทƒเถฝเทŠเถฝเท’, Sinhala for money). It reads the money SMS already on my Android phone and turns them into a spending dashboard on my laptop. A local Gemma model does the reading. There's no account and no server and nothing leaves my WiFi.

The whole effort on your side:

  1. Open Salli on your laptop and scan the QR code with the phone app.
  2. Tap Send now.
  3. Go back to being a sloth.

What you get back:

  • Spent, income and what's left for the month, with transfers between your own accounts kept out of the totals
  • A daily spend chart with a forecast to the end of the month
  • Where it went: categories and top shops
  • Recurring charges found from repeat SMS, with a warning when one goes up
  • A roast. Gemma writes one cheeky line about your month from your real numbers. It's the feature everyone asks about first.

Salli dashboard with the Gemma roast

Daily spend, categories and recurring charges

Transactions with categories you can fix once

The phone app does one job: pair, then send.

Phone: pair with your laptop

Phone: send money SMS

Phone: sent to your laptop

Screenshots use generated demo SMS. My real spending stays on my laptop, which is the whole point.

Demo

Code

Salli, a sleepy sloth hugging a coin

Salli

Your bank SMS become a budget. You do nothing.

Salli reads the money SMS on your Android phone and turns them into a spending dashboard on your laptop using Gemma running locally. No account, no cloud, nothing leaves your WiFi

Demo video ยท DEV post ยท Download


Salli (เทƒเถฝเทŠเถฝเท’) means money in Sinhala. The mascot is a sloth because the whole point is that you stay lazy.

In Sri Lanka every card swipe, bill payment and salary credit already sends you an SMS. Budgeting apps want you to type all of that in again or hand your bank login to a cloud service. Salli just reads the SMS you already have.

Salli dashboard

How it works

Android phone                          Your laptop (same WiFi)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   QR pair    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Salli app        โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚ Salli desktop (Tauri + Rust)         โ”‚
โ”‚ reads SMS inbox  โ”‚              โ”‚                                      โ”‚
โ”‚ keeps bank SMS,  โ”‚  local
โ€ฆ

Windows installer and Android APK are on the v1.0.0 release.

How I Built It

Salli is two apps that talk only to each other:

Android phone                          Your laptop (same WiFi)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   QR pair    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Salli app        โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚ Salli desktop (Tauri + Rust)         โ”‚
โ”‚ reads SMS inbox  โ”‚              โ”‚                                      โ”‚
โ”‚ keeps bank SMS,  โ”‚  local HTTP  โ”‚  1. rules     regex for amounts      โ”‚
โ”‚ drops OTPs       โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚  2. memory    shops it already knows โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚  3. Gemma 3   only for new shops     โ”‚
                                  โ”‚                                      โ”‚
                                  โ”‚  dashboard ยท roast ยท forecast        โ”‚
                                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Enter fullscreen mode Exit fullscreen mode

The phone is an Expo (React Native) app with a small Kotlin module that reads the SMS inbox. It keeps messages that look like money and drops OTPs on the phone, so they never travel anywhere. Then it posts the rest to the laptop over local HTTP.

Pairing with a QR code and a rotating 6-digit code

The laptop is a Tauri 2 app. A Rust server (axum) listens on port 7777. The UI is React with Tailwind and shadcn/ui.

Gemma does the reading, but only when it has to

I could have sent every SMS to Gemma. On a laptop CPU that would take forever and the slow part of this challenge is supposed to be me, not the app. So reading happens in three layers:

  1. Rules. Regex pulls out the amount and whether it's a debit or a credit. Known formats from Sri Lankan banks get fully parsed here.
  2. Memory. Once Salli knows a shop, it remembers the shop's name and category. If you fix a wrong category, it remembers that too, for every future payment there.
  3. Gemma 3 4B through Ollama, only for SMS the first two layers can't place. One SMS per call, with a strict JSON schema, so the output is always {amount, kind, merchant, category} and never a paragraph.

The first sync of a big inbox is slow, because Gemma meets every shop for the first time. After that, almost everything comes from rules and memory and new SMS show up instantly.

Gemma also writes the roast. It gets a summary of the month (total, top categories, top shops with counts) and a sloth persona prompt with a high temperature. That gives you lines like "Machan, seriously, six times ordering KFC?"

TabPFN for the forecast

The "where your month is heading" number started as a simple average. I swapped in TabPFN, Prior Labs' open tabular foundation model, as an optional upgrade.

Each past day becomes a row: weekday, weekend or not, day of the month and days since the last salary. The target is what I spent that day. TabPFN regresses on that history and predicts the rest of the month, with no training step and no tuning. It picks up that I spend more on weekends and right after payday, which a flat average can't.

It runs as a small Python sidecar that the Rust app calls. On my laptop's CPU, a forecast takes about 8 seconds. If Python or TabPFN isn't installed or there's less than 14 days of history, Salli quietly falls back to the average. Nobody has to install a 900 MB model just to try the app.

Things that went wrong

  • One payment, three SMS. A single LKR 560 phone bill sent me an alert from my bank, a receipt from the biller and a note from my wallet. That's three "payments". Salli now merges SMS with the same amount within an hour when at least one sender isn't a bank and keeps the bank's row as the main one.
  • Transfers looked like spending. Moving money to my own savings made my month look terrible. Transfers are now left out of spent and income.
  • The QR scanner. The Expo camera scanner never focused on my budget Samsung. The Google code scanner crashed on the same phone. I ended up writing a small native module around ZXing and now it scans instantly. It has a red laser line, which I've decided is a feature.
  • Play Protect blocks sideloaded apps that read SMS. That's fair, honestly. The README explains how to install anyway.

Benchmark

tools/bench.ts generates realistic Sri Lankan bank SMS with known answers and scores what Salli extracts. On that set, amount, direction, shop and category were all correct and every promo and OTP was skipped. Gemma 3 4B takes about 0.6 to 0.7 seconds per new SMS on CPU.

Honest note: some test shops also appear as examples in the Gemma prompt, so real-world accuracy is lower. On my own inbox of about 1,400 SMS, the misses were mostly biller receipts read as income. The duplicate merge now handles those.

Why Does Open Innovation Matter?

Bank SMS might be the most private data on my phone. They show where I eat, what I earn, who I send money to and when I'm broke.

With a closed model API, Salli would have to upload all of that to someone's server just to work out that "KEELLS SUPER" means groceries. I wouldn't use that app, so I wasn't going to build it.

Open weights flip that. Gemma runs on my laptop through Ollama and TabPFN runs there too. The phone talks only to the laptop, over WiFi I own. There's no account to make, no API key to leak, no usage bill and no company that can shut the feature off or change the price later. The AI is just part of the app, like the database.

Open source matters for the other half. Salli only knows Sri Lankan banks and billers today. Because the rules, the prompt and the benchmark are all in the repo, anyone can add their own bank's format and test it, without waiting for me.

The Lazy Payoff

I pointed Salli at my real inbox: about 1,400 SMS going back years. I had never once added up my spending and the first time I saw it all in one place was a little uncomfortable. The roast didn't help.

Before, figuring out where my money went meant scrolling through SMS and adding numbers in my head, which in practice meant never. Now it's one tap on the phone. The rest happens while I'm doing something else or nothing at all, which is the sloth way.

Prize Categories

  • Gemma: Gemma 3 4B runs locally through Ollama to read new bank SMS into structured transactions with a JSON schema and to write the monthly spending roast.
  • TabPFN: TabPFN regression forecasts daily spending for the rest of the month from past days, running locally as an optional sidecar.

Top comments (0)