isFullyAuthed() keyed the "server confirmed this session" check on
currentUser.pubkey. Every account has an id; a pubkey is optional, so
Lightning-only accounts were locked out of every strict-guard app:
login succeeded, isAuthenticated flipped true, pubkey stayed empty,
isFullyAuthed returned false, and the guard redirected back to /login --
a loop with no way out. Observed on atio, where 9 of 58 accounts have a
Nostr identity and the other 49 do not.
The pubkey was only ever a proxy for "getCurrentUser() came back", added
for issue #36 to stop a bare localStorage token counting as a session.
Keying on id preserves that protection exactly and drops the incidental
identity requirement.
Also gates the genuine requirement where it belongs: chat is Nostr
end-to-end and now opts in via installStrictAuthGuard(router,
{ requirePubkey: true }). Wallet and accounting are payment/ledger
surfaces -- per ADR-0001 (aiolabs/lnbits) LNbits is a liquidity service,
not an identity provider, so core payment flows must not be gated on
having an identity. Verified the wallet module never reads the user's
pubkey; its only nostr-tools import is nip19.encodeBytes for LNURL
bech32 in the receive QR, unrelated to identity.
Known gap, not addressed here: a pubkey-less user opening chat still
loops at /login rather than seeing an "identity required" screen. The
loop is now correct behaviour instead of a bug, but it deserves a real
message.
vue-tsc -b passes; all three call sites typecheck (the new parameter is
optional, so wallet and accounting are unchanged).