# Artha

> Pulls transactions from Bank Jago, Shopee, Gojek, and Grab into one timeline on Android.

- **Year**: 2026
- **Platforms**: android
- **Tools**: [Kotlin](https://kotlinlang.org), [Jetpack Compose](https://developer.android.com/jetpack/compose), [SQLite](https://wastu.net/experiments/artha/tools/sqlite)
- **Links**: [GitHub](https://github.com/bgwastu/artha)

# The problem

I used to track my spending with [YNAB](https://www.ynab.com), [Actual Budget](https://actualbudget.org), and later [Beancount](https://beancount.github.io).

The real problem was laziness. I just couldn't keep up with manual reconciling every few days.

Writing down every single expense in real time is annoying. If I forget for a few days, the ledger doesn't balance anymore. When that happens, I lose track of things and end up with no idea what my actual spending habits look like.

I liked Beancount because it's text-based and portable, so AI agents can work with it easily. But I only had data from Bank Jago. Apps like Gojek, Grab, and Shopee make it really hard or impossible to get clean statement exports.

# Why root

People always suggest parsing email receipts or SMS alerts. In Indonesia, that doesn't work.

Email receipts aren't reliable and they don't give you a 1:1 match. Shopee and GoPay don't send emails or notifications for every transaction.

Also, Indonesian apps are all connected. I pay for Shopee with my Jago card. I pay for Gojek rides using a linked Jago pocket or QRIS. When two apps log the same payment under different names, scrapers get confused and count it twice.

Root was the only way to get the real raw data straight from the phone.

# How it works

Artha uses root access to extract raw data directly from each app:

Bank Jago is built with [Flutter](https://flutter.dev). Artha reads its `FlutterSharedPreferences.xml` to get `flutter.jago.sharedpref.hivekey`, decrypts the [Hive](https://pub.dev/packages/hive) master key with AES-CBC, and reads `pot.hive` and `list_transaction_history.hive` directly on disk.

Gojek is trickier because it does not keep an unencrypted database. Artha spawns a headless virtual display in Android 13, opens Gojek's internal history deep link (`gojek://home/history`), and walks the view hierarchy in the background without touching your active screen.

Grab and Shopee keep saved session tokens and cookies on the device. Artha derives Grab's session key using PBKDF2 with client salt bytes, extracts Shopee's `SPC_EC` cookie, and queries their order history APIs directly.

Then the reconciler connects everything. For example, when I order lunch on GoFood for Rp 45.000, Bank Jago only logs a vague debit to GoPay with no line items. Gojek knows I bought Bakmi Pak Haji, but doesn't track my bank balance. Artha pairs the two records: the bank debit gets enriched with the merchant name and items, and any wallet top-up in between is marked as a transfer instead of a double expense.

# How I use it

Now I never log a receipt by hand. When I want to check my spending, I just glance at the Android homescreen widget or open the app. The ledger stays 1:1 with reality, and I finally know where my money actually went at the end of the month.

# An API for my agents

I wanted my AI agents to have access to the whole ledger.

When turned on, Artha opens a temporary Cloudflare Quick Tunnel with an OpenAPI endpoint. I can ask my AI agents to check my balance, see recent transactions, or break down my spending whenever I want.

# What's next

As I wrote in [everything has an API if you're willing to prompt](/blog/everything-is-an-api), root turns closed mobile apps into usable data sources for AI agents.

In the future, I might set up an older secondary phone as a dedicated transaction exporter. With exploits like [GhostLock](https://github.com/YuKongA/ghostlock-app), older devices can get root without even unlocking the bootloader.

Artha needs root, so it's definitely not for everyone. It's just a personal tool built for me.

#### Why I used SQLite in Artha

Artha stores transactions in a local SQLite database on the phone to deduplicate payments and keep category mappings offline without an external database.
