Skip to content

fix: handle wallet-network mismatch before signing - #938

Open
Calebstack wants to merge 21 commits into
Predictify-org:mainfrom
Calebstack:security/issue-891-quality-2-medium-handle-wallet-network-mismatch
Open

fix: handle wallet-network mismatch before signing#938
Calebstack wants to merge 21 commits into
Predictify-org:mainfrom
Calebstack:security/issue-891-quality-2-medium-handle-wallet-network-mismatch

Conversation

@Calebstack

Copy link
Copy Markdown
Contributor

Overview

This PR adds a deterministic wallet-network mismatch guard that prevents signing any Stellar transaction when the connected wallet is on the wrong network. The expected network is resolved from validated walletPrefs/environment configuration and checked at every signing entry point: wallet connection, bet submission, claim submission, and wallet reconnection. When a mismatch is detected, the sign flow is blocked and the user is shown a single actionable Switch network path instead of a confusing signing failure.

The implementation follows least-privilege and authorization-boundary principles: the guard only reads network state and blocks signing when the precondition fails; it never grants new wallet permissions, weakens validation, or exposes sensitive account data.

Related Issue

Changes

🛡️ Network Mismatch Guard

  • [MODIFY] components/connect-wallet-modal.tsx

    • Compares the connected wallet network against the expected network immediately after connection.
    • Displays a mismatch banner with current and expected network names while keeping the connect/sign CTA disabled.
    • Provides a Switch network action that calls the wallet’s native network-switch method and re-validates after completion or rejection.
  • [MODIFY] components/BetForm.tsx

    • Adds a network precondition before building or signing a bet transaction.
    • Re-checks immediately before signAndSend to close the race between initial render and wallet network changes.
    • Throws a user-visible WalletNetworkMismatchError instead of opening the sign flow when the wallet is on the wrong network.
  • [MODIFY] app/(dashboard)/claims/page.tsx

    • Applies the same network precondition before claim signing.
    • Shows an inline mismatch warning with current/expected networks and a recovery link to NetworkSwitcher.
    • Prevents claim submission from mutating state or creating a pending transaction while mismatched.
  • [MODIFY] components/navbar/NetworkSwitcher.tsx

    • Adds an expected-network badge and a one-click Switch to action for injected wallets.
    • On rejection or timeout, preserves the previous network state and surfaces a diagnosable error without logging private keys or addresses.
  • [MODIFY] components/WalletReconnectBanner.tsx

    • Verifies the wallet network after reconnect before restoring any previous signing session.
    • If a mismatch is found, asks the user to switch before proceeding; no silent signing on a different network is allowed.
  • [MODIFY] app/state/walletPrefs.ts

    • Validates persisted expected-network values on load; invalid or malformed values fall back to the default network and are migrated safely.
    • Exposes a single assertNetworkMatches() helper used by all sign paths so checks cannot diverge.
    • Preserves existing caller interfaces and local-storage keys for full backward compatibility.
  • [ADD] src/lib/__tests__/walletNetworkMismatch.test.ts

    • Covers successful network match, mismatch-before-sign rejection, retry after rejected switch, duplicate checks, invalid persisted prefs, and regression scenarios.

Verification Results

npm test -- src/lib/__tests__/walletNetworkMismatch.test.ts
✅ 14/14 passed

Live acceptance check:
✅ mismatch detected before sign on BetForm and Claims
✅ switch-network flow works for injected wallets and WalletConnect
✅ rejected switch keeps state consistent and retryable
✅ walletPrefs migration recovers from invalid stored values
✅ no addresses, keys, or sensitive data in logs or user-visible errors
Acceptance Criteria Status
Deterministic behavior for valid, invalid, duplicate, and boundary-case inputs ✅ Unit + integration tests cover valid match, mismatch, duplicate mismatch, and malformed persisted prefs
Authorization, validation, and state-transition invariants remain enforced ✅ Signing is gated by assertNetworkMatches(); no new wallet permissions or weakened validation
Retries, partial failure, and concurrent execution cannot produce unsafe/inconsistent result ✅ Switch-reject/retry tests and prefs validation prevent unsafe state transitions
Focused tests cover success, rejection, boundary, and regression scenarios ✅ 14 tests across guard, modal, BetForm, Claims, reconnect banner, and walletPrefs
Existing callers remain compatible, or a tested migration path is included ✅ Public interfaces unchanged; walletPrefs migration is backward-compatible and tested
Failures are diagnosable without exposing sensitive data ✅ User-visible errors show network names only; logs use sanitized network IDs and omit wallet addresses/keys

Closes #891

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Calebstack is attempting to deploy a commit to the Jagadeesh B's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Calebstack Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

[Quality-2][Medium] Handle wallet-network mismatch before signing

1 participant