* feat(auth): multi-step login with relay resolution UI
Replace the single-shot login API with a multi-step flow that gracefully
handles missing relay lists instead of crashing. When relay lists aren't
found on the network, users are now presented with a relay resolution
screen offering two paths: provide a custom relay URL to search, or
publish default relay lists.
- Update whitenoise-rs to multi-step login PR (3435fd9)
- Add LoginResult/LoginStatus/LoginError types to Rust API bridge
- Add login_start, login_publish_default_relays, login_with_custom_relay,
login_cancel bridge functions (nsec + external signer variants)
- Refactor AuthNotifier, hooks, and AndroidSignerService for multi-step flow
- Add RelayResolutionScreen with relay URL input and default relays option
- Add structured login error messages (invalid key, timeout, no connections)
- Remove obsolete AccountSettings bridge (removed upstream)
Closesmarmot-protocol/whitenoise#46, marmot-protocol/whitenoise#143
* fix(auth): standardize error keys, add translations, maximize test coverage
- Standardize all login hook errors to l10n keys instead of raw English
strings (paste errors, all 5 LoginError variants)
- Remove redundant useEffect cleanup from hooks (useTextEditingController
handles its own disposal)
- Wrap fire-and-forget userMetadata call with unawaited() for clarity
- Simplify relay resolution error resolver to two-branch switch
- Translate all 15 new l10n keys into DE, ES, FR, IT, PT, RU, TR
- Add 4 new l10n keys: loginErrorNoLoginInProgress, loginErrorInternal,
loginPasteNothingToPaste, loginPasteFailed
- Add tests for all uncovered provider, screen, hook, and service paths
Coverage: 99.43% overall, 100% on all changed files
* fix(auth): remove unused hook param, disable buttons during loading, assert loginCancel
- Remove unused isExternalSigner parameter from useRelayResolution hook
(the screen uses it to select callbacks, not the hook itself)
- Disable both relay resolution buttons while loading to prevent
concurrent requests
- Add assertion to loginCancel test verifying the Rust API receives
the correct pubkey
* fix(auth): restore nsec cleanup on dispose, use consistent error key
- Restore useEffect cleanup that clears nsec from TextEditingController
on widget dispose (security fix from defb482 accidentally removed)
- Replace orphaned 'relayResolutionPublishFailed' error key with
'loginErrorGeneric' for consistency with tryCustomRelay error handling
- Regenerate flutter_rust_bridge code after rebase onto master
* fix(auth): independent button loading, relay URL prefill and validation
- Split isLoading into isPublishingDefaults and isSearchingRelay so each
button shows its own loading indicator while the other is just disabled
- Prefill relay URL input with wss:// matching the network settings pattern
- Add debounced relay URL validation (shared utility extracted from
use_add_relay) with inline error display via WnInput.errorText
- Wrap fire-and-forget userMetadata call with error handling in
_completeLogin to prevent unhandled async exceptions
- Replace map-iteration-order-dependent testNpubToHex.values.first with
explicit testPubkeyA constant in mock
- Add mounted guard (useRef<bool>) to skip state updates after unmount
- Map caught ApiError variants to structured l10n keys instead of
hardcoding loginErrorGeneric; expand _resolveError to match
* test: add coverage for metadata fetch failure, validation reset, and external signer method routing
- Test that login completes even when fire-and-forget userMetadata fails
- Test that clearing relay URL back to wss:// prefix resets validation state
- Add invocation flags to mock auth notifier and assert external signer
tests call the correct methods (not the regular login methods)