Feature/519 freighter wallet auth - #661
Open
vincentchimene wants to merge 5 commits into
Open
Conversation
- Integrates @stellar/freighter-api isConnected, getAddress, requestAccess, getNetwork - WatchWalletChanges polling (3s) detects account switches and network changes - Persists public key + network in encrypted localStorage via storage util - Raises sessionExpired flag on external account switch - Exposes connect, disconnect, refresh, clearSessionExpired actions - SSR-safe: all browser APIs guarded with typeof window checks Closes part of StellarFlow-Network#519
- Wraps FreighterWalletContext state + actions into a flat ergonomic API - Computed helpers: isConnected, isLoading, shortAddress, networkLabel - Re-exports stable action references to prevent unnecessary re-renders - Full TypeScript types via UseWalletReturn interface Closes part of StellarFlow-Network#519
- requireAuth() fast-path returns immediately when session is valid - On session expiry or account switch, triggers Freighter requestAccess() - Deduplicates concurrent calls via inflightRef (single popup guarantee) - Toast notifications on success (confirmed) and failure (failed) - Exposes isReAuthing loading flag and clearReAuthError Closes part of StellarFlow-Network#519
- Add FreighterWalletBoundary client component to satisfy Next.js App Router requirement that Context providers be Client Components - Nest FreighterWalletBoundary inside ToastProvider in layout.tsx so useReAuth can access addToast - Keeps layout.tsx as a Server Component Closes StellarFlow-Network#519
… auth implementation - Install jest@29, jest-environment-jsdom, @testing-library/react, @testing-library/jest-dom, babel-jest + babel presets - Add jest.config.js with jsdom env, @/ alias mapping, babel transform - Add babel.test.config.js (separate from Next.js build config) - Add npm scripts: test:wallet, test:jest 18 tests covering all 3 requirements from issue StellarFlow-Network#519: Requirement 1 — Freighter connection state listener: ✓ idle→disconnected when extension not connected ✓ idle→connected when extension returns valid address ✓ WatchWalletChanges starts on mount, stops on unmount ✓ Account switch detected via watcher → sessionExpired raised ✓ connect() triggers requestAccess when getAddress returns empty ✓ disconnect() clears publicKey, network, storage Requirement 2 — Session persistence across reloads: ✓ Persists public key to encrypted localStorage on connect ✓ Hydrates publicKey from storage on initial render ✓ Removes key from storage on disconnect Requirement 3 — Graceful re-authentication on session expiry: ✓ requireAuth() fast-path when session is valid ✓ requireAuth() triggers re-auth on sessionExpired ✓ requireAuth() throws + error toast on user cancel ✓ Concurrent calls deduplicated (single Freighter popup) ✓ clearSessionExpired() clears the flag Computed helpers: ✓ shortAddress: first4…last4 format ✓ networkLabel: TESTNET→Testnet, PUBLIC→Mainnet ✓ isLoading true during idle/checking states Closes StellarFlow-Network#519
Contributor
|
Hello @vincentchimene, Please do attend to these conflicts so I can merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(wallet): Implement Freighter Wallet Connect & Re-authentication Hook
Closes #519
Overview
This PR delivers the complete Freighter wallet integration for the StellarFlow frontend, addressing all three technical requirements outlined in issue #519. It introduces a dedicated context
layer built on
@stellar/freighter-api, a primary consumer hook, and a re-authentication hook that gracefully handles session expiry — without disrupting the existingWalletProviderinfrastructure.
Changes
src/context/FreighterWalletContext.tsx(new)Core context layer providing Freighter-native connection state management:
isConnected()andgetAddress()on mount and after every user interactionWatchWalletChangespoller (3s interval) to detect external account switches and network changes without requiring a page reloadlocalStorageusing the existingstorageutility, enabling session continuity across reloadssessionExpiredflag when the live extension key diverges from the persisted key, signalling downstream hooks to prompt re-authenticationwindowaccess is guarded; the provider renders cleanly during server-side renderingsrc/hooks/useWallet.ts(new)Primary consumer hook exposing a flat, ergonomic API for all wallet-aware components:
publicKey,network,status,sessionExpired, anderrorfrom context stateisConnected,isLoading,shortAddress(G...WXYZ format),networkLabel(e.g. "Testnet", "Mainnet")useCallbackaction references to prevent unnecessary child re-renderssrc/hooks/useReAuth.ts(new)Re-authentication hook for graceful session expiry handling:
requireAuth()resolves immediately when the session is valid (zero overhead on the happy path)requestAccess()and resolves with the newly confirmed public keyrequireAuth()simultaneouslyconfirmed, auto-dismisses after 5s) and failure (failed, persists until dismissed)isReAuthingfor disabling UI controls during the re-auth flowsrc/app/components/providers/FreighterWalletBoundary.tsx(new)Thin
"use client"boundary component that satisfies Next.js App Router's requirement for Context providers to be Client Components, while keepinglayout.tsxa Server Component.src/app/layout.tsx(modified)Registers
<FreighterWalletBoundary>in the provider tree, nested inside<ToastProvider>to ensureuseReAuthhas access toaddToast.Testing
18 tests — all passing (
npm run test:wallet)connect()viarequestAccess,disconnect()clearSessionExpired()shortAddressformat,networkLabelmapping,isLoadingstateUsage