Skip to content

feat: implement network-specific balance fetching in TransferForm and TransactionDetails#296

Merged
chibie merged 4 commits intomainfrom
fix-bug-fix-for-wrong-network-selection-in-transfer-form
Nov 27, 2025
Merged

feat: implement network-specific balance fetching in TransferForm and TransactionDetails#296
chibie merged 4 commits intomainfrom
fix-bug-fix-for-wrong-network-selection-in-transfer-form

Conversation

@Dprof-in-tech
Copy link
Collaborator

@Dprof-in-tech Dprof-in-tech commented Nov 23, 2025

Description

This pull request updates the transfer form and transaction details components to correctly handle balances and network selection based on the recipient's network, rather than relying on the globally selected network. The changes ensure that token balances and explorer links are accurate for the context of each transaction, and introduce a utility function to fetch balances for a specific network.

Transfer Form improvements:

  • The transfer form now fetches and displays the wallet balance for the selected recipient network, not the global network, ensuring users see accurate balances when transferring across networks. [1] [2] [3]
  • Added a new state variable transferNetworkBalance and loading state to manage and display balances for the selected transfer network. [1] [2] [3] [4]
  • Updated token list and transfer logic to use the recipient's network, improving accuracy for cross-network transfers. [1] [2]

Transaction Details improvements:

  • Transaction explorer links and details now use the network stored with the transaction rather than the global network, ensuring correct context for each transaction. [1] [2]

Utility function addition:

  • Added fetchBalanceForNetwork to app/utils.ts to fetch wallet balances for a specific network, supporting the new balance fetching logic in the transfer form.

Imports update:

  • Imported the new fetchBalanceForNetwork utility in app/components/TransferForm.tsx to enable network-specific balance fetching.

References

This fixes a bug Francis discovered while trying to make transfers.
closes #292

Testing

There was no UI change. Conclusive testing would be done on staging.

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have added documentation and tests for new/changed functionality in this PR
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not main

By submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.

Summary by CodeRabbit

  • Refactor
    • Transfer form now scopes balances to each recipient network, with network-specific loading, error states, Max logic, and transfer behavior.
    • Transaction details use each transaction’s own network for explorer links and receipt network info; receipts reflect the transaction network.
  • New Features
    • Background balance fetching for the selected transfer network, including loading skeletons, visible errors, and balance refresh on success.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 23, 2025

Walkthrough

Replaces global balance usage with per-recipient-network balance fetching and state in TransferForm; TransactionDetails now uses each transaction's own network for explorer links and receipt data.

Changes

Cohort / File(s) Summary
Per-network balance handling
app/components/TransferForm.tsx, app/utils.ts
TransferForm derives transferNetwork from the selected recipient network and maintains transferNetworkBalance, isBalanceLoading, and balanceError. UI (balance display, "Max" logic, skeletons, and transfer invocation) now uses transferNetwork and passes it into useSmartWalletTransfer. fetchBalanceForNetwork was added to app/utils.ts (appears duplicated) to create a network-specific publicClient (BSC RPC special-case) and return wallet balances.
Transaction network localization
app/components/transaction/TransactionDetails.tsx
Replaced use of the global selectedNetwork with transaction.network when building on-chain explorer URLs and when populating orderDetailsData.network for PDF receipts.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TransferForm
    participant Utils as fetchBalanceForNetwork
    participant PublicClient
    participant RPC

    rect rgb(235,244,255)
    Note over TransferForm,Utils: Per-recipient-network balance flow
    User->>TransferForm: open transfer / select recipient
    TransferForm->>TransferForm: derive transferNetwork from recipientNetwork
    TransferForm->>Utils: fetchBalanceForNetwork(transferNetwork, walletAddress)
    Utils->>PublicClient: create publicClient (BSC special-case)
    PublicClient->>RPC: query balances for walletAddress
    RPC-->>PublicClient: raw balance data
    PublicClient-->>Utils: formatted balances
    Utils-->>TransferForm: transferNetworkBalance / error
    TransferForm->>TransferForm: update UI (balance, Max, transfer call)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect app/utils.ts for duplicate fetchBalanceForNetwork definitions and remove the redundant copy.
  • Verify transferNetwork is consistently used for token selection, balance checks, and passed into useSmartWalletTransfer.
  • Review BSC RPC special-case, publicClient creation, and error handling paths.
  • Confirm transaction.network presence/validation in TransactionDetails.tsx to avoid undefined access.

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • chibie
  • jeremy0x

Poem

🐰 I hopped across each wondrous chain,

Fetching carrots where recipients reign,
Balances found on every lane,
Receipts and links now match each train,
A happy thump — transfers in their lane!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the main changes: implementing network-specific balance fetching across TransferForm and TransactionDetails components.
Description check ✅ Passed The PR description provides clear context on the changes, references a closed issue (#292), and includes testing notes and a checklist, though test coverage was not added.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-bug-fix-for-wrong-network-selection-in-transfer-form

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Dprof-in-tech Dprof-in-tech marked this pull request as ready for review November 23, 2025 21:04
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/TransferForm.tsx (1)

246-273: Clarify balance display vs validation when balance data is missing or still loading

Both the dedicated balance bar and the amount header use:

  • isBalanceLoading || transferNetworkBalance === null to decide when to show a skeleton, and
  • tokenBalance = Number(transferNetworkBalance?.balances?.[token]) || 0 as the source of truth for display and as the max validation rule.

This leads to a couple of confusing cases:

  • When the balance fetch hasn’t run yet or has failed, transferNetworkBalance is null, so the UI shows a skeleton, but the effective max is 0. Any positive amount will fail validation with a “Max. amount is 0” style error, without the user ever seeing an explicit “0” or an error message.
  • The “Max” buttons call handleBalanceMaxClick, which uses tokenBalance. If the balance is still loading or missing, that will write 0 into the amount, which feels odd given the UI is still showing a skeleton.

Consider:

  • Using only isBalanceLoading for the skeleton condition, and treating a non-loading, null/empty transferNetworkBalance as a real “0” balance (or an explicit “Balance unavailable” state), and/or
  • Guarding the “Max” button so it’s disabled or hidden while isBalanceLoading is true.

This will make the UX clearer when balances are not yet available, without affecting the core per-network behavior.

Also applies to: 470-482, 495-517

🧹 Nitpick comments (2)
app/utils.ts (1)

529-555: Network-scoped balance helper looks good; consider tightening typing & small ergonomics

This helper correctly encapsulates per-network balance fetching and special-cases BSC RPC, which aligns with the PR goal.

Two small improvements you may want to make:

  • Type safety: instead of network: { chain: any }, use the existing Network type from ../../types (or an explicit interface) so chain is guaranteed and consumers stay consistent.
  • Transport construction: calling http(undefined) is harmless but a bit awkward. You could branch to avoid passing undefined explicitly:
 export async function fetchBalanceForNetwork(
-  network: { chain: any },
+  network: Network,
   walletAddress: string,
 ): Promise<{ total: number; balances: Record<string, number> }> {
   const { createPublicClient, http } = await import("viem");
   const { bsc } = await import("viem/chains");

-  const publicClient = createPublicClient({
-    chain: network.chain,
-    transport: http(
-      network.chain.id === bsc.id
-        ? "https://bsc-dataseed.bnbchain.org/"
-        : undefined,
-    ),
-  });
+  const isBsc = network.chain.id === bsc.id;
+  const publicClient = createPublicClient({
+    chain: network.chain,
+    transport: isBsc
+      ? http("https://bsc-dataseed.bnbchain.org/")
+      : http(),
+  });

These are non-blocking and mainly about maintainability/readability.

app/components/TransferForm.tsx (1)

12-13: Per-recipient transferNetwork wiring and token/balance sourcing look consistent

The refactor to:

  • derive transferNetwork from the chosen recipientNetwork (with selectedNetwork as a sensible fallback),
  • pull fetchedTokens from allTokens[transferNetwork.chain.name], and
  • pass selectedNetwork: transferNetwork plus supportedTokens: fetchedTokens into useSmartWalletTransfer,

ensures both the token list and the actual transfer call are aligned with the recipient’s network rather than the global selection. Computing tokenBalance from transferNetworkBalance.balances[token] is also consistent with how fetchWalletBalance structures its result.

Only very minor polish you might consider later:

  • Consolidate the two ../utils imports into a single import block to avoid duplicating module imports.
  • If Network is a shared type, consider reusing it for transferNetwork and throughout to keep everything strongly typed.

These are non-blocking and the core behavior change looks correct.

Also applies to: 47-48, 56-62, 80-89, 104-118

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a7b351 and 84ec4ac.

📒 Files selected for processing (3)
  • app/components/TransferForm.tsx (9 hunks)
  • app/components/transaction/TransactionDetails.tsx (2 hunks)
  • app/utils.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: jeremy0x
Repo: paycrest/noblocks PR: 177
File: app/utils.ts:179-196
Timestamp: 2025-07-23T07:30:23.720Z
Learning: The `normalizeNetworkName` function in app/utils.ts has been updated to be dynamic and scalable, converting any network identifier to sentence case with hyphens replaced by spaces and proper handling of acronyms like "BNB".
📚 Learning: 2025-07-23T07:30:23.720Z
Learnt from: jeremy0x
Repo: paycrest/noblocks PR: 177
File: app/utils.ts:179-196
Timestamp: 2025-07-23T07:30:23.720Z
Learning: The `normalizeNetworkName` function in app/utils.ts has been updated to be dynamic and scalable, converting any network identifier to sentence case with hyphens replaced by spaces and proper handling of acronyms like "BNB".

Applied to files:

  • app/utils.ts
  • app/components/TransferForm.tsx
  • app/components/transaction/TransactionDetails.tsx
📚 Learning: 2025-10-10T16:44:32.125Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 244
File: app/components/CopyAddressWarningModal.tsx:48-52
Timestamp: 2025-10-10T16:44:32.125Z
Learning: In the CopyAddressWarningModal component (app/components/CopyAddressWarningModal.tsx), selectedNetwork from useNetwork() is always defined and does not require null safety checks when accessing its properties like selectedNetwork.chain.name.

Applied to files:

  • app/utils.ts
  • app/components/TransferForm.tsx
  • app/components/transaction/TransactionDetails.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/components/TransferForm.tsx
🧬 Code graph analysis (1)
app/components/transaction/TransactionDetails.tsx (1)
app/utils.ts (1)
  • getExplorerLink (133-156)
🔇 Additional comments (1)
app/components/transaction/TransactionDetails.tsx (1)

53-57: Using transaction.network for explorer and receipts is correct; verify network name normalization

Switching both the explorer URL and the PDF receipt payload to use transaction.network instead of the global selectedNetwork fixes the original “wrong network” bug and aligns all views with the actual transaction context.

One thing to double‑check: this now relies on transaction.network matching the display names expected by getExplorerLink and getNetworkFromName (e.g., "Base", "Arbitrum One", "BNB Smart Chain"). If the backend sometimes stores identifiers like "base" or "arbitrum-one", consider normalizing once at ingestion (e.g., via normalizeNetworkName) so icons and explorer links don’t silently disappear for those records.

Also applies to: 62-67

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/TransferForm.tsx (1)

247-255: Fix timing of balance refresh after successful transfer.

The global balance is refreshed via refreshBalance(), which updates smartWalletBalance from the BalanceContext. Since transferNetworkBalance is local state and the form closes immediately after transfer (via onClose()), it does not need explicit refresh—the balance will be re-fetched when the form reopens.

However, there's a timing issue at line 250-251: refreshBalance() is called after handleFormClose(), which means it executes on an already-closed/unmounting component. Either:

  1. Swap the order: call refreshBalance() before handleFormClose(), or
  2. Leverage the existing onSuccess callback to handle balance refresh in the parent, avoiding redundant calls.
🧹 Nitpick comments (1)
app/components/TransferForm.tsx (1)

180-180: Optional: Optimize effect dependency to reduce unnecessary re-fetches.

The effect depends on user?.linkedAccounts, which will trigger a re-fetch whenever any linked account changes (e.g., adding/removing an email, wallet, etc.), not just when the smart wallet address changes.

Consider extracting the smart wallet address and depending on that specific value to avoid unnecessary balance fetches:

+  // Extract smart wallet address for more granular dependency tracking
+  const smartWalletAddress = user?.linkedAccounts.find(
+    (account) => account.type === "smart_wallet"
+  )?.address;
+
   // Fetch balance for the selected transfer network
   useEffect(() => {
     const fetchBalance = async () => {
       const smartWalletAccount = user?.linkedAccounts.find(
         (account) => account.type === "smart_wallet",
       );

       // No smart wallet account - set empty balance state (not loading, not error)
       if (!smartWalletAccount?.address) {
         ...
       }
       ...
     };

     fetchBalance();
-  }, [transferNetwork, user?.linkedAccounts]);
+  }, [transferNetwork, smartWalletAddress]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84ec4ac and eb1ba46.

📒 Files selected for processing (1)
  • app/components/TransferForm.tsx (9 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-10T16:44:32.125Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 244
File: app/components/CopyAddressWarningModal.tsx:48-52
Timestamp: 2025-10-10T16:44:32.125Z
Learning: In the CopyAddressWarningModal component (app/components/CopyAddressWarningModal.tsx), selectedNetwork from useNetwork() is always defined and does not require null safety checks when accessing its properties like selectedNetwork.chain.name.

Applied to files:

  • app/components/TransferForm.tsx
📚 Learning: 2025-07-23T07:30:23.720Z
Learnt from: jeremy0x
Repo: paycrest/noblocks PR: 177
File: app/utils.ts:179-196
Timestamp: 2025-07-23T07:30:23.720Z
Learning: The `normalizeNetworkName` function in app/utils.ts has been updated to be dynamic and scalable, converting any network identifier to sentence case with hyphens replaced by spaces and proper handling of acronyms like "BNB".

Applied to files:

  • app/components/TransferForm.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/components/TransferForm.tsx
🧬 Code graph analysis (1)
app/components/TransferForm.tsx (3)
app/mocks.ts (1)
  • networks (43-83)
app/types.ts (1)
  • Token (209-215)
app/utils.ts (1)
  • fetchBalanceForNetwork (537-554)
🔇 Additional comments (5)
app/components/TransferForm.tsx (5)

82-82: LGTM: transferNetwork derivation is correct.

The derivation correctly finds the network object matching the selected recipientNetwork and falls back to selectedNetwork when not found (e.g., during initial render before line 123's effect runs). Since networks is a module-level constant from app/mocks.ts, the find() returns stable object references.


142-180: LGTM: Balance fetch effect addresses past review concerns effectively.

The effect now properly handles all three states:

  1. No smart wallet (lines 149-155): Sets zero balance and stops loading immediately
  2. Success (lines 162-167): Stores fetched balance
  3. Error (lines 168-173): Sets zero balance, stores error message, and shows toast

The finally block (lines 174-176) ensures loading state is always cleared. This resolves the issues raised in the previous review about perpetual skeleton states and missing error feedback.


84-89: LGTM: Token fetching and balance calculation use the correct network.

Lines 84 and 89 correctly use transferNetwork (derived from the recipient's network) instead of the global selectedNetwork. The optional chaining and zero-default for tokenBalance safely handle cases where the token is not present in the fetched balance.


105-119: LGTM: Transfer hook correctly uses recipient's network.

Line 115 correctly passes transferNetwork (the recipient's network) as the selectedNetwork parameter to useSmartWalletTransfer. This is the core change that ensures transfers execute on the recipient's chosen network rather than the global context, directly addressing the PR objective.


12-12: No duplication found—review comment is incorrect.

Verification confirms only one definition of fetchBalanceForNetwork exists at line 537 in app/utils.ts. The AI-generated summary's claim of duplication is unfounded. No action needed.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/components/TransferForm.tsx (1)

142-180: Effect handles balance fetching well; two minor optimizations suggested.

The balance fetch effect correctly:

  • Handles the no-smart-wallet case by setting an empty balance state (lines 149-155)
  • Sets loading and error states appropriately
  • Shows both toast and inline error on failure
  • Uses the recipient's network for fetching

Two optional refinements:

  1. Line 157 guard could set explicit states: The early return when !transferNetwork doesn't set isBalanceLoading or clear states. While line 82's fallback ensures transferNetwork is always defined, adding explicit state updates here would make the code more defensive:
  if (!transferNetwork) {
+   setTransferNetworkBalance({ total: 0, balances: {} });
+   setIsBalanceLoading(false);
+   setBalanceError(null);
    return;
  }
  1. Line 180 dependency optimization: Depending on user?.linkedAccounts (an array) may cause unnecessary re-fetches if the array reference changes frequently. Consider extracting the smart wallet address:
+ const smartWalletAddress = user?.linkedAccounts.find(
+   (account) => account.type === "smart_wallet"
+ )?.address;
  // ... inside effect: use smartWalletAddress directly ...
- }, [transferNetwork, user?.linkedAccounts]);
+ }, [transferNetwork, smartWalletAddress]);

Neither issue is critical, but both would improve robustness and efficiency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28a1725 and cee29fa.

📒 Files selected for processing (1)
  • app/components/TransferForm.tsx (11 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-10T16:44:32.125Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 244
File: app/components/CopyAddressWarningModal.tsx:48-52
Timestamp: 2025-10-10T16:44:32.125Z
Learning: In the CopyAddressWarningModal component (app/components/CopyAddressWarningModal.tsx), selectedNetwork from useNetwork() is always defined and does not require null safety checks when accessing its properties like selectedNetwork.chain.name.

Applied to files:

  • app/components/TransferForm.tsx
📚 Learning: 2025-07-23T07:30:23.720Z
Learnt from: jeremy0x
Repo: paycrest/noblocks PR: 177
File: app/utils.ts:179-196
Timestamp: 2025-07-23T07:30:23.720Z
Learning: The `normalizeNetworkName` function in app/utils.ts has been updated to be dynamic and scalable, converting any network identifier to sentence case with hyphens replaced by spaces and proper handling of acronyms like "BNB".

Applied to files:

  • app/components/TransferForm.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/components/TransferForm.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.

Applied to files:

  • app/components/TransferForm.tsx
🧬 Code graph analysis (1)
app/components/TransferForm.tsx (5)
app/context/index.ts (1)
  • useBalance (3-3)
app/mocks.ts (1)
  • networks (43-83)
app/types.ts (1)
  • Token (209-215)
app/utils.ts (1)
  • fetchBalanceForNetwork (537-554)
app/components/index.ts (2)
  • AnimatedComponent (15-15)
  • slideInOut (19-19)
🔇 Additional comments (7)
app/components/TransferForm.tsx (7)

12-12: LGTM! State and imports correctly support network-specific balance fetching.

The new state variables (transferNetworkBalance, isBalanceLoading, balanceError) and imports (fetchBalanceForNetwork, refreshBalance) are well-structured and properly typed to support the per-recipient-network balance feature.

Also applies to: 47-47, 56-62


81-82: LGTM! Fallback to selectedNetwork ensures robustness.

The lookup-with-fallback pattern ensures transferNetwork is always defined. The fallback is safe because the recipient network dropdown (lines 93-103) uses the same filtered networks array, preventing selection of invalid networks.


84-89: LGTM! Token list and balance correctly scoped to recipient network.

The code properly:

  • Retrieves tokens for the recipient's network (transferNetwork.chain.name)
  • Extracts the selected token's balance from the network-specific balance object
  • Handles null/undefined cases with optional chaining and a safe default of 0

115-115: LGTM! Critical change enables cross-network transfers.

Passing transferNetwork (the recipient's network) instead of the global selectedNetwork correctly implements the cross-network transfer feature described in the PR objectives.


260-287: LGTM! Balance UI correctly uses network-specific states.

Both balance display sections (lines 260-287 and 475-506) consistently:

  • Show skeletons during loading (isBalanceLoading || transferNetworkBalance === null)
  • Display the correct network-specific token balance
  • Enable/disable the "Max" button appropriately
  • Use the same tokenBalance value derived from transferNetworkBalance

Also applies to: 475-506


562-569: LGTM! Inline error display improves user feedback.

The balance error is now displayed inline below the amount field (in addition to the toast notification), providing persistent feedback when balance fetching fails. This addresses the previous review comment and matches the styling of other form errors.


246-256: LGTM! Success flow correctly refreshes balance.

Calling refreshBalance() before closing ensures the global wallet balance is updated after the transfer completes, maintaining consistency between the form's network-specific balance and the main wallet view.

@5ran6 5ran6 self-requested a review November 24, 2025 23:52
Copy link
Contributor

@5ran6 5ran6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chibie chibie merged commit 4c42cc7 into main Nov 27, 2025
1 check passed
@chibie chibie deleted the fix-bug-fix-for-wrong-network-selection-in-transfer-form branch November 27, 2025 17:15
@coderabbitai coderabbitai bot mentioned this pull request Jan 16, 2026
4 tasks
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.

BNB Network Transfers Redirecting to BaseScan

3 participants

Comments