Skip to content

Conversation

@xerion12
Copy link

@xerion12 xerion12 commented Dec 9, 2025

Implements automatic wallet balance refresh after successful transactions and adds manual refresh button to wallet icon.

  • Adds automatic balance query invalidation in StatusSidebar and handleContractWrite after successful transactions
  • Adds manual refresh button with loading state next to wallet balance display
  • Fixes issue where wallet balance remained stale until manual page refresh

@vercel
Copy link

vercel bot commented Dec 9, 2025

@xerion12 is attempting to deploy a commit to the Warden Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

📝 Walkthrough

Walkthrough

The changes add automatic wallet balance refresh functionality across the application. A new refresh button is introduced in the ConnectWallet component that invalidates and refetches balance queries. Balance query invalidation is simultaneously integrated into transaction success paths in StatusSidebar and the contract write handler to ensure wallet balance reflects post-transaction state.

Changes

Cohort / File(s) Summary
Balance refresh UI
spaceward/src/components/ConnectWallet.tsx
Adds RefreshCw icon import, React Query integration, and a new refresh button with tooltip. Introduces isRefreshing state and handleRefresh function that invalidates and refetches the balance query with error handling and loading indicators.
Post-transaction balance invalidation
spaceward/src/features/actions/StatusSidebar.tsx
Extends cache invalidation with balance query invalidation after successful transactions. Adds identical invalidation logic in three separate code paths where transaction completion is recognized, conditioned on address and chainId availability.
Contract write balance invalidation
spaceward/src/utils/contract.tsx
Extends handleContractWrite options with queryClient, address, and chainId fields. Adds balance query invalidation after successful transaction receipt when all required options are provided.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify query key structures (["balance", { address, chainId }]) are consistent across all three invalidation locations
  • Confirm address and chainId matching conditions are applied uniformly in StatusSidebar's three invalidation code paths
  • Review RefreshCw button behavior and disabled state conditions in ConnectWallet
  • Validate that balance invalidation fires for both manual refresh and post-transaction flows

Suggested labels

spaceward

Suggested reviewers

  • jjheywood

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 The title clearly and concisely summarizes the main change: auto-refreshing wallet balance after transactions, which aligns with all three modified files' primary purpose.
Description check ✅ Passed The description is well-related to the changeset, providing specific details about automatic balance invalidation, manual refresh button, and the problem being solved.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

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

♻️ Duplicate comments (2)
spaceward/src/features/actions/StatusSidebar.tsx (1)

457-476: Duplicate invalidation logic.

This is identical to the invalidation at lines 349-368. As noted above, extract to a shared helper.

spaceward/src/utils/contract.tsx (1)

111-130: Same predicate duplication applies here.

This is the same invalidation predicate used in StatusSidebar.tsx. Consider using the shared helper suggested in that file's review.

🧹 Nitpick comments (2)
spaceward/src/components/ConnectWallet.tsx (1)

41-53: Consider simplifying the refresh logic.

Calling invalidateQueries already marks the query as stale and triggers a background refetch. The subsequent explicit refetch() call is redundant and may cause a double network request.

 const handleRefresh = async () => {
   if (!address || isRefreshing) return;
   setIsRefreshing(true);
   try {
     // Invalidate and refetch balance query
-    await queryClient.invalidateQueries({ queryKey: balance.queryKey });
-    await balance.refetch();
+    await balance.refetch();
   } catch (error) {
     console.error("Error refreshing balance:", error);
   } finally {
     setIsRefreshing(false);
   }
 };

Alternatively, if you want to ensure cache invalidation across any shared queries, keep only invalidateQueries and remove refetch().

spaceward/src/features/actions/StatusSidebar.tsx (1)

349-368: Extract duplicated balance invalidation predicate into a shared helper.

This predicate logic is duplicated here, at lines 459-475, and in contract.tsx. Extracting it to a shared utility would improve maintainability and reduce the risk of inconsistencies.

Consider creating a helper function:

// e.g., in src/utils/queryKeys.ts
export const createBalanceQueryPredicate = (address: string, chainId: number) => 
  (query: Query) => {
    const key = query.queryKey;
    if (!Array.isArray(key) || key[0] !== "balance") return false;
    const params = key[1];
    return (
      typeof params === "object" &&
      params !== null &&
      "address" in params &&
      (params as any).address === address &&
      "chainId" in params &&
      (params as any).chainId === chainId
    );
  };

Then use it in all three locations:

-queryClient.invalidateQueries({
-  predicate: (query) => {
-    const key = query.queryKey;
-    if (!Array.isArray(key) || key[0] !== "balance") {
-      return false;
-    }
-    const params = key[1];
-    return (
-      typeof params === "object" &&
-      params !== null &&
-      "address" in params &&
-      (params as any).address === address &&
-      "chainId" in params &&
-      (params as any).chainId === env.evmChainId
-    );
-  },
-});
+queryClient.invalidateQueries({
+  predicate: createBalanceQueryPredicate(address, env.evmChainId),
+});
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ce0c4f and 456afb7.

📒 Files selected for processing (3)
  • spaceward/src/components/ConnectWallet.tsx (3 hunks)
  • spaceward/src/features/actions/StatusSidebar.tsx (2 hunks)
  • spaceward/src/utils/contract.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
spaceward/src/features/actions/StatusSidebar.tsx (1)
spaceward/src/env.ts (1)
  • env (37-57)
🔇 Additional comments (2)
spaceward/src/components/ConnectWallet.tsx (1)

196-217: LGTM!

The refresh button implementation is well-structured with proper accessibility (tooltip), loading state (spinning icon), and disabled state handling.

spaceward/src/utils/contract.tsx (1)

70-78: LGTM on API extension.

The optional parameters are well-designed, maintaining backward compatibility with existing callers while enabling balance invalidation when the new options are provided. Verify that callers of handleContractWrite are updated to pass the new options (queryClient, address, chainId) where balance refresh is needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant