Skip to content

Conversation

@kernelwhisperer
Copy link
Contributor

@kernelwhisperer kernelwhisperer commented Dec 24, 2025

Summary

Fixes #6758

But I think the issue should be fixed on the Safe/WalletConnect side.

Summary by CodeRabbit

  • Bug Fixes
    • Improved wallet capability lookup so capabilities are reliably returned even when a chain-specific entry is missing, reducing cases where wallet features appeared unavailable.

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

@vercel
Copy link

vercel bot commented Dec 24, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
cowfi Ready Ready Preview Dec 29, 2025 9:08am
explorer-dev Ready Ready Preview Dec 29, 2025 9:08am
swap-dev Ready Ready Preview Dec 29, 2025 9:08am
widget-configurator Ready Ready Preview Dec 29, 2025 9:08am
2 Skipped Deployments
Project Deployment Review Updated (UTC)
cosmos Ignored Ignored Dec 29, 2025 9:08am
sdk-tools Ignored Ignored Preview Dec 29, 2025 9:08am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

Walkthrough

The hook useWalletCapabilities now falls back to the first available key in the result object when a chainId-specific capabilities key is missing, ensuring a Safe-wallet-capabilities value is returned instead of undefined; timeout/error handling and chainIdHex computation remain unchanged.

Changes

Cohort / File(s) Summary
Wallet Capabilities Hook
libs/wallet/src/api/hooks/useWalletCapabilities.ts
When chainId-specific key is absent, use the first key from the result (result[Object.keys(result)[0]]) as a Safe fallback; added clarifying comment; SWR key callback param renamed to _chainId to indicate it's ignored for resolution.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

RELEASE

Suggested reviewers

  • elena-zh
  • limitofzero

Poem

I’m a rabbit hopping through keys and light,
I pick the first one that feels just right.
No hex-bound worry, no chainId chase,
Safes find their path — a gentle, shared space. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete. It references the issue but lacks the required 'To Test' and 'Background' sections from the template. Add 'To Test' section with testing steps and checkboxes, and optionally include a 'Background' section explaining the Safe Wallet fallback behavior.
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 (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing batch transaction issues for Safe wallets after network switching.
Linked Issues check ✅ Passed The code change directly addresses issue #6758 by implementing a fallback mechanism in useWalletCapabilities to handle missing chainId-specific keys.
Out of Scope Changes check ✅ Passed The change is focused and scoped to the useWalletCapabilities hook, directly addressing the Safe wallet batch transaction issue.
✨ 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/batch-tx-missing-from-safe-wallets

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc78c6 and 0725ac4.

📒 Files selected for processing (1)
  • libs/wallet/src/api/hooks/useWalletCapabilities.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/wallet/src/api/hooks/useWalletCapabilities.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Setup
  • GitHub Check: Cypress

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

Caution

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

⚠️ Outside diff range comments (1)
libs/wallet/src/api/hooks/useWalletCapabilities.ts (1)

44-48: Clarify the SWR key/fetcher mismatch or remove chainId from the cache key.

The SWR cache key includes chainId (line 46), causing refetches when the chain changes, but the fetcher ignores it entirely (line 48: _chainId). The code always returns result[Object.keys(result)[0]], taking the first available capability regardless of the current chain.

This creates a semantic gap: if wallet_getCapabilities returns capabilities for multiple chains (per EIP-5792), the returned capabilities may not match the current chainId. In useSendBatchTransactions, these capabilities are then used with the current chainId for wallet_sendCalls, which could cause incorrect behavior or failures.

Either:

  1. Remove chainId from the SWR key if it's not needed for the lookup
  2. Use chainId properly to select the correct entry from the result: result[chainIdHex] where chainIdHex = '0x' + (+chainId).toString(16)
  3. Add a comment explaining why this mismatch is necessary (e.g., Safe wallet workaround) and document the assumptions about which chain's capabilities are returned
🧹 Nitpick comments (1)
libs/wallet/src/api/hooks/useWalletCapabilities.ts (1)

54-65: Consider a more explicit fallback when provider returns multiple chains.

The wallet_getCapabilities RPC call is made with only the account parameter (no chainId), so the provider's response can contain capabilities for multiple chains. The current approach of selecting the first key works as a practical workaround for Safe wallet, but it has minor robustness concerns:

  1. Unclear selection: If the provider returns multiple chains, which chain's capabilities are actually used is undefined.
  2. Object.keys() ordering: While deterministic in modern JavaScript (insertion order), the order is not guaranteed to be the intended chain.

The _chainId parameter is available and could be used to prefer the current chain's capabilities if present. A simple improvement:

-            resolve(result[Object.keys(result)[0]])
+            const currentChainHex = `0x${_chainId.toString(16)}`
+            resolve(result[currentChainHex] ?? result[Object.keys(result)[0]])

This prefers the current chain when available while maintaining the Safe wallet fallback.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02e6844 and 4dc78c6.

📒 Files selected for processing (1)
  • libs/wallet/src/api/hooks/useWalletCapabilities.ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: alfetopito
Repo: cowprotocol/cowswap PR: 5992
File: libs/wallet/src/web3-react/utils/switchChain.ts:36-38
Timestamp: 2025-08-05T14:27:05.023Z
Learning: In libs/wallet/src/web3-react/utils/switchChain.ts, the team prefers using Record<SupportedChainId, string | null> over Partial<Record<SupportedChainId, string>> for WALLET_RPC_SUGGESTION to enforce that all supported chain IDs have explicit values set, even if some might be null. This ensures compile-time completeness checking.
📚 Learning: 2025-08-05T14:27:05.023Z
Learnt from: alfetopito
Repo: cowprotocol/cowswap PR: 5992
File: libs/wallet/src/web3-react/utils/switchChain.ts:36-38
Timestamp: 2025-08-05T14:27:05.023Z
Learning: In libs/wallet/src/web3-react/utils/switchChain.ts, the team prefers using Record<SupportedChainId, string | null> over Partial<Record<SupportedChainId, string>> for WALLET_RPC_SUGGESTION to enforce that all supported chain IDs have explicit values set, even if some might be null. This ensures compile-time completeness checking.

Applied to files:

  • libs/wallet/src/api/hooks/useWalletCapabilities.ts
📚 Learning: 2025-10-13T19:41:31.440Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6351
File: apps/cowswap-frontend/src/modules/erc20Approve/containers/TradeApproveModal/useTradeApproveCallback.ts:87-121
Timestamp: 2025-10-13T19:41:31.440Z
Learning: In apps/cowswap-frontend/src/modules/erc20Approve, useApproveCallback returns Promise<TransactionResponse | undefined> and is distinct from useApproveCurrency, which can return Promise<TransactionReceipt | SafeMultisigTransactionResponse>. When reviewing approval flows, verify which hook is actually being used before flagging Safe wallet concerns.

Applied to files:

  • libs/wallet/src/api/hooks/useWalletCapabilities.ts
📚 Learning: 2025-08-12T05:57:08.021Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6138
File: libs/hook-dapp-lib/src/hookDappsRegistry.ts:1-1
Timestamp: 2025-08-12T05:57:08.021Z
Learning: The matchHooksToDapps function in libs/hook-dapp-lib/src/utils.ts provides backward compatibility for permit hooks through function selector detection (EIP_2612_PERMIT_SELECTOR and DAI_PERMIT_SELECTOR) rather than dappId matching, making it robust against dappId changes.

Applied to files:

  • libs/wallet/src/api/hooks/useWalletCapabilities.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test
  • GitHub Check: Lint
  • GitHub Check: Build

Copy link
Contributor

@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

Works good, thank you

@kernelwhisperer kernelwhisperer merged commit fdcbea7 into develop Dec 29, 2025
17 checks passed
@kernelwhisperer kernelwhisperer deleted the fix/batch-tx-missing-from-safe-wallets branch December 29, 2025 11:20
@github-actions github-actions bot locked and limited conversation to collaborators Dec 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TXs are not bundled when connected to Safe+WC

4 participants