feat(wallet): derive default wallet from nsec during onboarding
The new-user onboarding flow was still generating a random BIP39 mnemonic in startDiscovery before connecting Spark, so the wallet for a brand-new account could not be restored by signing in with the same nsec on another device. Switch to generateDefaultFromPrivkey so the default wallet is deterministic from the user's key. Also drop the NIP-78 relay backup for default wallets: the mnemonic is recoverable from the nsec, and Breez retains the lightning address registration server-side, so there is nothing extra to persist. Manual backup of non-default (random) wallets is unchanged.
This commit is contained in:
@@ -160,7 +160,8 @@ class OnboardingViewModel(app: Application) : AndroidViewModel(app) {
|
||||
_error.value = null
|
||||
|
||||
// Use real keypair if available, otherwise generate a throwaway for probing
|
||||
val keypair = keyRepo.getKeypair() ?: Keys.generate()
|
||||
val realKeypair = keyRepo.getKeypair()
|
||||
val keypair = realKeypair ?: Keys.generate()
|
||||
val pubHex = keyRepo.getPubkeyHex() ?: keypair.pubkey.toHex()
|
||||
keyRepo.reloadPrefs(pubHex)
|
||||
blossomRepo.reload(pubHex)
|
||||
@@ -168,14 +169,15 @@ class OnboardingViewModel(app: Application) : AndroidViewModel(app) {
|
||||
// Reload wallet repos so mnemonic + mode are stored under the correct pubkey prefs
|
||||
walletModeRepo?.reload(pubHex)
|
||||
|
||||
// Pre-generate mnemonic (CPU only, no network contention with relay probing)
|
||||
if (sparkRepo != null) {
|
||||
// Derive the default Spark wallet deterministically from the user's nsec
|
||||
// so it is recoverable on any device by signing in with the same key.
|
||||
// Skip if no real keypair yet (we're only probing relays with a throwaway).
|
||||
if (sparkRepo != null && realKeypair != null) {
|
||||
sparkRepo.reload(pubHex)
|
||||
try {
|
||||
val mnemonic = sparkRepo.newMnemonic()
|
||||
sparkRepo.saveMnemonic(mnemonic)
|
||||
sparkRepo.generateDefaultFromPrivkey(realKeypair.privkey)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Mnemonic generation failed: ${e.message}")
|
||||
Log.w(TAG, "Default wallet derivation failed: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,8 +284,11 @@ class OnboardingViewModel(app: Application) : AndroidViewModel(app) {
|
||||
}
|
||||
}
|
||||
|
||||
// Backup mnemonic to relays via NIP-78
|
||||
if (sparkRepo != null && lightningAddress != null) {
|
||||
// NIP-78 relay backup is only useful for non-default wallets — the
|
||||
// default wallet's mnemonic is derived from the nsec, and Breez
|
||||
// remembers its lightning address registration server-side, so
|
||||
// there's nothing extra to persist on relays.
|
||||
if (sparkRepo != null && !sparkRepo.isDefaultWallet()) {
|
||||
val mnemonic = sparkRepo.getMnemonic()
|
||||
if (mnemonic != null) {
|
||||
viewModelScope.launch {
|
||||
|
||||
Reference in New Issue
Block a user