Successfully implemented wallet network sync detection to prevent fund payments from being built for the wrong network when users change networks in their wallet extensions after connecting.
- Added
walletNetworkfield toWalletStateinterface - This tracks the actual network state from the wallet extension (separate from provider network)
New Features:
refreshWalletNetwork(): Async function to query and refresh the wallet's current network stateisNetworkMismatch: Computed boolean that returnstruewhen provider network doesn't match wallet networkwalletNetwork: New state field exposing the wallet's actual network
Implementation Details:
- Modified
connectFreighter()to capture and return wallet network during connection - Added
getFreighterNetwork()helper that maps network passphrases to network identifiers refreshWalletNetwork()safely handles errors and won't throw, just sets error stateisNetworkMismatchautomatically computes based onwallet.networkvswallet.walletNetwork
Network Mismatch Check:
if (wallet.walletNetwork && wallet.network !== wallet.walletNetwork) {
throw new Error(
`Network mismatch: Provider is on ${wallet.network} but wallet is on ${wallet.walletNetwork}. ` +
`Switch your wallet to ${wallet.network} or call refreshWalletNetwork() to update.`
)
}- Prevents transaction submission when networks don't match
- Provides clear error message with actionable guidance
- Only checks if
walletNetworkis set (backward compatible with existing state)
- Updated DEFAULT_WALLET to include
walletNetwork: null - Ensures all new wallet connections start with proper state
New Display Features:
- Shows both "Provider Network" and "Wallet Network" separately
- Color-coded network status (green for match, red for mismatch)
- Visual "Network mismatch!" warning when networks don't align
- "Refresh Network" button to manually check wallet network state
Updated Hook Usage:
const {
connect,
disconnect,
connected,
address,
connecting,
error,
network: walletProviderNetwork,
walletNetwork,
refreshWalletNetwork,
isNetworkMismatch,
} = useWallet()
const { network: providerNetwork } = useNetwork()useWallet.test.tsx - 6 test suites covering:
- ✅ Wallet network capture on connection
- ✅ Network mismatch detection on connection attempt
- ✅ Manual wallet network refresh
- ✅ Network state updates after refresh
- ✅ No-op when wallet not connected
- ✅ Error handling during refresh
- ✅
isNetworkMismatchcomputation (matching & mismatched cases) - ✅ State cleanup on disconnect
useSendPayment.test.tsx - 5 test suites covering:
- ✅ Error when wallet not connected
- ✅ Error when networks mismatch
- ✅ Success when networks match
- ✅ Success with null walletNetwork (legacy state)
- ✅ Helpful error messages for network mismatch
All tests passing: 28 tests total across 3 test files
{
// Existing fields...
walletNetwork: StellarNetwork | null // NEW: Actual wallet network
refreshWalletNetwork: () => Promise<void> // NEW: Refresh wallet network
isNetworkMismatch: boolean // NEW: Network mismatch indicator
}const { connect, walletNetwork, refreshWalletNetwork, isNetworkMismatch } = useWallet()
// Connect wallet
await connect("freighter")
// Later, user might change network in Freighter
// Developer can refresh to detect this
await refreshWalletNetwork()
// Check for mismatch
if (isNetworkMismatch) {
alert("Please switch your wallet to the correct network!")
}✅ Wallet network state can be refreshed after connection
refreshWalletNetwork()function implemented and tested
✅ Mismatched wallet/provider network is visible to developers
isNetworkMismatchboolean exposedwalletNetworkfield shows actual wallet network- Demo page visually indicates mismatch
✅ Payment hooks block unsafe submission on network mismatch
useSendPaymentchecks network before building transaction- Clear error message thrown when mismatch detected
✅ Demo page clearly shows network status
- Displays both Provider Network and Wallet Network
- Color-coded visual indicators (green/red)
- "Network mismatch!" warning message
- Refresh Network button
✅ Tests cover mismatch handling
- 11 tests specifically for network sync features
- Tests cover connection, refresh, mismatch detection, and error scenarios
- Tests verify payment blocking on mismatch
Since Freighter doesn't expose network change events, we implemented:
- Capture on connection: Store wallet network during initial connection
- Manual refresh:
refreshWalletNetwork()for polling when needed - Automatic validation: Payment hooks check mismatch before submission
walletNetworkcan benullfor old state or wallets that don't support detection- Network mismatch check only runs if
walletNetworkis populated - Existing integrations work without changes
- Prevents cross-network transaction submission
- Clear error messages guide users to fix misconfiguration
- No automatic network switching (user must explicitly fix mismatch)
packages/core/src/types/index.tspackages/core/src/context/StellarProvider.tsxpackages/core/src/hooks/useWallet.tspackages/core/src/hooks/useSendPayment.tspackages/demo/app/demo/wallet/page.tsx
packages/core/src/hooks/useWallet.test.tsx(268 lines)packages/core/src/hooks/useSendPayment.test.tsx(195 lines)
- ✅ TypeScript compilation successful
- ✅ All tests passing (28/28)
- ✅ Build artifacts generated successfully
- ✅ No linting errors
Branch: fix/wallet-network-sync
Commit: fix(wallet): sync wallet network state
Files changed: 8 files changed, 655 insertions(+), 37 deletions(-)
- The changes are committed to the
fix/wallet-network-syncbranch - Push the branch:
git push -u origin fix/wallet-network-sync - Create a PR to merge into
main - Demo the feature by:
- Connecting Freighter wallet
- Changing network in Freighter extension
- Clicking "Refresh Network" button
- Observing the network mismatch warning