forceResyncUnshielded

suspend fun forceResyncUnshielded()

Force-rebuild the unshielded UTXO cache from genesis to self-heal a stale NIGHT balance.

What it fixes (roadmap #52). The unshielded UTXO cache is event-driven — it applies created / spent deltas from the indexer's tx subscription with no reconcile against the indexer's current set. If a spent-event is ever missed — a sibling app on the same shared wallet spent a coin while this app was backgrounded, or a subscription gap — the spent UTXO lingers as a ghost AVAILABLE coin and the balance over-counts (e.g. shows 20k NIGHT while the real spendable is 10k). Replaying the whole tx history from genesis rebuilds the UTXO set from the indexer's truth, so the ghosts drop out.

Cancels + re-launches the long-lived subscription with a one-shot genesis wipe (com.midnight.kuira.core.indexer.sync.SubscriptionManager.startSubscription forceFullResync = true): the cache is cleared, then re-populated as the indexer replays. So the unshielded NIGHT balance momentarily drops toward 0, then climbs back as events arrive — the balanceFlow emits the rebuild live, so a UI bound to it shows the correction without a second action.

UTXO-cache only — does NOT touch the dust checkpoint or shielded state. Those are separate replay models; wiping them would force a heavy dust genesis replay (fatal on PreProd). This is deliberately narrower than a full chain-reset wipe — it heals exactly the unshielded ledger and nothing else.

A deliberate, user-triggered recovery action (a "Re-sync balance" affordance), NOT something to run on every refresh — the routine refresh / live subscription already keep NIGHT current. No-op when no subscription controller is wired (e.g. unit tests building the wallet directly).