Skip to content

Seed cold-start UI and transaction list from widget cache - #1

Open
n1gh7e0us wants to merge 5 commits into
bwgh0:mainfrom
n1gh7e0us:main
Open

Seed cold-start UI and transaction list from widget cache#1
n1gh7e0us wants to merge 5 commits into
bwgh0:mainfrom
n1gh7e0us:main

Conversation

@n1gh7e0us

Copy link
Copy Markdown

The addition was done because at the moment the current app was rendering the default WalletState while it waited for isLocked to complete its sync. This would make the user think that... they lost funds but then suddenly it would work.

Leading to mini heart attacks.

The PR kinda avoids that.

(also please squash and merge to avoid cluttering the commits, I was lazy to install JVM so ended up using foojay but realised we won't need that so nuked it out)

Airpods69 added 5 commits July 5, 2026 19:00
On unlock, WalletViewModel.init now reads last-known balance,
unlocked balance, and price from WidgetDataStore (the prefs file
already written unconditionally on every kit emission for the home-
screen widget) and seeds _walletState and _currentPrice synchronously,
before the async kit init runs.

Previously isLocked flipped synchronously on verifyPin, MainScreen
composed off the default WalletState (balance 0, transactions [],
NotSynced), and the real values only arrived once
initializeWalletIfNeeded()'s coroutine completed and the kit emitted.
Now the first frame shows the cached balance/price with a Connecting
sync state (spinner instead of the wrong "No transactions yet"
card), and the kit's live emissions overwrite them on reconnect.

Transactions are not seeded: the widget cache stores them as
dir|amount|timestamp with no hash/confirmations, so reconstructing
them would break tx detail navigation. The Connecting seed makes
the empty card show the spinner instead.

No widget required — the saves were already unconditional; only the
reads are new.
Extends the widget tx cache format from dir|amount|timestamp to
dir|amount|timestamp|hash and bumps the stored count from 4 to 50
(the widget still reads only 4 via parseTxData.take(4); the extra
entries seed the in-app transaction list during cold start).

seedFromWidgetCache now parses the cache back into TransactionInfo
and seeds _walletState.transactions, so WalletScreen's recent
activity and TransactionListScreen show last-known txs immediately
on unlock instead of the empty spinner. The kit's live emissions
overwrite them on reconnect.

confirmations forced to 10 (Confirmed) — cached txs are virtually
always old & confirmed; a genuinely pending tx self-corrects when
the kit emits. fee/blockheight default to 0, so the detail screen
shows "Fee 0 / Pending" briefly if a tx is tapped before the kit
loads (the accepted tradeoff for not marshalling every field).

Parser extracted to a top-level internal fun parseCachedTxs and
covered by TxCacheParserTest (3 cases: 4-field parse + legacy
3-field skip, garbage/blank dropping, empty cache). 3-field legacy
entries are skipped, not synthesized — the cache fills with 4-field
entries after the next kit emit.
Add foojay-resolver-convention plugin and the generated
gradle-daemon-jvm.properties so builds fetch a JDK 21 (JetBrains)
toolchain automatically instead of relying on a local install.
The widget tx-cache previously stored only dir|amount|timestamp|hash, so
parseCachedTxs fabricated confirmations=10 (Confirmed), fee=0, blockheight=0
for the cold-start seed. The detail screen then showed status Confirmed next
to Block Height "Pending" — a visible contradiction.

Extend the cache format to dir|amount|timestamp|hash|fee|blockheight|confirmations
and restore all three fields faithfully. blockheight=0 marks a genuinely pending
tx (isPending) instead of forcing Confirmed. Legacy 4-field entries are skipped,
not fabricated; the list stays empty only until the next kit emit rewrites the
cache with all seven fields.

Demote the balance/price seed ponytail tag — caching last-known values is
correct, not a shortcut.

TxCacheParserTest now round-trips the writer format and asserts the
pending/confirmed split instead of the old forced-confirmations contract.
Drop foojay-resolver-convention plugin and gradle-daemon-jvm.properties.
Builds now require a locally installed JDK 17+ (AGP requirement).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant