Problem
Android tracks wallet import post-sync with an in-memory MutableStateFlow<Set<WalletId>> named importingWalletIds in ImportWalletService.
This is the wrong approach for import lifecycle state. It creates a separate transient state machine for import progress, keyed by wallet ID, instead of making initial wallet setup/discovery state part of the same wallet lifecycle used by the rest of the app.
Relevant Android code:
android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/wallet_import/services/ImportWalletService.kt
android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/asset/GetImportInProgressImpl.kt
Why this is wrong
importingWalletIds only exists in memory. It is lost on process death and is not tied to durable wallet setup state. It also couples unrelated consumers to a special import-only progress flow, even though the work being tracked is really initial wallet setup and initial asset/transaction/NFT discovery.
The Android import path currently does wallet creation, then starts background sync work and exposes ImportWalletState from the temporary set. That makes the import lifecycle harder to reason about and different from the rest of the wallet loading model.
Reference: iOS architecture
iOS has a better split:
- The import screen owns only the active submit/loading state.
- Wallet creation/import activates the wallet and completes the import flow.
- Initial setup/discovery is handled by wallet lifecycle services after the current wallet changes.
- Initial load completion is tracked through wallet preferences such as asset/transaction/NFT initial-load flags, not an import-only in-memory wallet-ID set.
Relevant iOS code:
ios/Features/Onboarding/Sources/ViewModels/ImportWalletSceneViewModel.swift
ios/Gem/ViewModels/RootSceneViewModel.swift
ios/Packages/FeatureServices/DiscoverAssetsService/AssetDiscoveryService.swift
ios/Packages/Preferences/Sources/WalletPreferences.swift
Proposed direction
Refactor Android to follow the iOS model:
- Remove
importingWalletIds and the import-only ImportWalletState flow.
- Keep import UI loading local to the import screen/view model.
- Move post-import wallet setup/discovery into the normal wallet lifecycle path after the imported wallet becomes current.
- Track initial asset/transaction/NFT/configuration completion with durable wallet-scoped preferences or existing persistent state.
- Make consumers such as
GetImportInProgressImpl depend on initial-load state instead of import-specific transient state.
Acceptance criteria
- Android no longer uses
importingWalletIds for wallet import progress.
- Import progress is not stored as an in-memory set of wallet IDs.
- Initial wallet setup/discovery survives process restart and is derived from durable wallet-scoped state.
- Import screen loading remains local to the import action.
- Existing behavior for subscription sync, wallet configuration sync, asset discovery, transaction sync, and NFT sync is preserved.
- Add or update tests covering the new lifecycle behavior.
Problem
Android tracks wallet import post-sync with an in-memory
MutableStateFlow<Set<WalletId>>namedimportingWalletIdsinImportWalletService.This is the wrong approach for import lifecycle state. It creates a separate transient state machine for import progress, keyed by wallet ID, instead of making initial wallet setup/discovery state part of the same wallet lifecycle used by the rest of the app.
Relevant Android code:
android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/wallet_import/services/ImportWalletService.ktandroid/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/asset/GetImportInProgressImpl.ktWhy this is wrong
importingWalletIdsonly exists in memory. It is lost on process death and is not tied to durable wallet setup state. It also couples unrelated consumers to a special import-only progress flow, even though the work being tracked is really initial wallet setup and initial asset/transaction/NFT discovery.The Android import path currently does wallet creation, then starts background sync work and exposes
ImportWalletStatefrom the temporary set. That makes the import lifecycle harder to reason about and different from the rest of the wallet loading model.Reference: iOS architecture
iOS has a better split:
Relevant iOS code:
ios/Features/Onboarding/Sources/ViewModels/ImportWalletSceneViewModel.swiftios/Gem/ViewModels/RootSceneViewModel.swiftios/Packages/FeatureServices/DiscoverAssetsService/AssetDiscoveryService.swiftios/Packages/Preferences/Sources/WalletPreferences.swiftProposed direction
Refactor Android to follow the iOS model:
importingWalletIdsand the import-onlyImportWalletStateflow.GetImportInProgressImpldepend on initial-load state instead of import-specific transient state.Acceptance criteria
importingWalletIdsfor wallet import progress.