Skip to content

fix(accounts): restore persisted id in AndroidNativeAccount.fromJSON#87

Merged
hzrd149 merged 2 commits into
hzrd149:masterfrom
Besao21:patch-1
Jul 22, 2026
Merged

fix(accounts): restore persisted id in AndroidNativeAccount.fromJSON#87
hzrd149 merged 2 commits into
hzrd149:masterfrom
Besao21:patch-1

Conversation

@Besao21

@Besao21 Besao21 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

AndroidNativeAccount.fromJSON creates a new account but never restores the
persisted id, so every reload mints a fresh nanoid(8). This breaks the
serialize/restore round-trip: a caller that persists the active account's id
(e.g. localStorage['active'] = account.idmanager.setActive(storedId) on
startup) hits getAccount() miss → throw new Error("Cant find account with that ID") because the rehydrated account's id no longer matches the stored one.

In practice this means a native Android signer (Amber / NIP-55) login cannot
survive an app restart — the app throws during restore and blank-screens.

It's the only account type that omits the restore: every sibling
(ReadonlyAccount, PrivateKeyAccount, ExtensionAccount, NostrConnectAccount,
PasswordAccount, AmberClipboardAccount, SerialPortAccount) calls
super.loadCommonFields(account, json). This mirrors that pattern.

Repro: create an AndroidNativeAccount via fromApp(), persist with
toJSON() + manager.setActive(account.id), reload, call
manager.fromJSON(json) + manager.setActive(storedId) → throws.

Fix: 2-line change matching the sibling idiom.

   `AndroidNativeAccount.fromJSON` creates a new account but never restores the
   persisted `id`, so every reload mints a fresh `nanoid(8)`. This breaks the
   serialize/restore round-trip: a caller that persists the active account's id
   (e.g. `localStorage['active'] = account.id` → `manager.setActive(storedId)` on
   startup) hits `getAccount()` miss → `throw new Error("Cant find account with
   that ID")` because the rehydrated account's id no longer matches the stored one.

   In practice this means a native Android signer (Amber / NIP-55) login cannot
   survive an app restart — the app throws during restore and blank-screens.

   It's the only account type that omits the restore: every sibling
   (`ReadonlyAccount`, `PrivateKeyAccount`, `ExtensionAccount`, `NostrConnectAccount`,
   `PasswordAccount`, `AmberClipboardAccount`, `SerialPortAccount`) calls
   `super.loadCommonFields(account, json)`. This mirrors that pattern.

   **Repro:** create an `AndroidNativeAccount` via `fromApp()`, persist with
   `toJSON()` + `manager.setActive(account.id)`, reload, call
   `manager.fromJSON(json)` + `manager.setActive(storedId)` → throws.

   **Fix:** 2-line change matching the sibling idiom.
@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4441639

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
applesauce-accounts Patch
applesauce-signers Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Allow AndroidNativeSigner to receive an existing pubkey via constructor,
avoiding a redundant call to NostrSignerPlugin.getPublicKey on connect.
This improves performance when restoring accounts from serialized state.
@hzrd149
hzrd149 merged commit 3e9424a into hzrd149:master Jul 22, 2026
1 check passed
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.

2 participants