Skip to content

feat(services): recover orphaned Android Keystore keys via on-chain m…#3182

Open
justjoolz wants to merge 1 commit into
onflow:devfrom
justjoolz:feat/recover-orphaned-keystore-keys
Open

feat(services): recover orphaned Android Keystore keys via on-chain m…#3182
justjoolz wants to merge 1 commit into
onflow:devfrom
justjoolz:feat/recover-orphaned-keystore-keys

Conversation

@justjoolz

Copy link
Copy Markdown

Feature: Recover Orphaned Android Keystore Keys via On-Chain Matching

Description

During key rotation, a new key can be written to the Android Keystore and added on-chain while the app fails to persist its local mapping (e.g. the process is interrupted before saving). The key then physically exists in the Keystore but the app has no record of it, so the account can't be used and doesn't appear in the switcher. This addresses the state reported in #2831.

This PR introduces a fail-safe recovery scanner that automatically detects these orphaned keys during app cold start, matches them against the user's on-chain Flow addresses, and writes them back into KeyStorageManager so they become usable again in the Account Switcher.

The Fix

The new KeyStoreMigrationManager.recoverOrphanedKeystoreKeys():

  1. Enumerates all aliases matching the Flow Wallet Kit Keystore prefix (KeyManager.KEYSTORE_ALIAS_PREFIX) physically present in the Android Keystore.
  2. Extracts the raw EC public key (x || y) from the self-signed certificate (which works even when the private key is hardware-backed and non-extractable).
  3. Fetches the on-chain keys for all known Flow addresses associated with the device.
  4. If a Keystore public key matches an on-chain key but has no local mapping, it automatically injects a UserPrefix and Account mapping to the local cache, recovering the account without requiring the user to re-enter their seed phrase.

Integration

To ensure compatibility with upcoming changes, this explicitly complements #2864 by populating the prefix map it reads from. Temporary synthetic accounts are injected to bridge the recovery state, which will integrate seamlessly with the new local account structures.

Verification

  • Constructor calls (Account, UserInfoData, FlowWallet) cross-referenced against their definitions in current dev and confirmed to supply all required parameters.
  • A full build was not completed locally; the Android module's Gradle config halts in the React Native configuration phase (Hermes engine, missing from a hand-assembled node_modules) before Kotlin compilation runs. This is unrelated to the changed files.
  • Developed independently against the public source.

@justjoolz justjoolz requested a review from a team as a code owner June 24, 2026 05:35
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