Skip to content

bug: Coinbase connector disconnects on second page refresh #4970

@feyyazcigim

Description

@feyyazcigim

Check existing issues

Describe the bug

Description

Coinbase Wallet disconnects on the second page refresh despite having valid session data in localStorage. First refresh works correctly, but second refresh consistently fails.

Environment

  • React: 18.3.1

Steps to Reproduce

  1. Connect with Coinbase Wallet (extension or smart wallet)
  2. Refresh the page → Connection persists ✅
  3. Refresh the page again → Connection lost ❌
  4. Check localStorage → Both wagmi.store and cbwsdk.store contain valid session data

Expected Behavior

Wallet should remain connected on every page refresh as long as session data exists in localStorage.

Actual Behavior

  • First refresh: Connection restored successfully
  • Second refresh: Wallet disconnects despite valid localStorage data
  • Pattern: Only happens on second+ refresh, first refresh always works

Root Cause Analysis

After extensive debugging, we identified the issue:

  1. First refresh:

    • Wagmi hydrates from localStorage → isConnected: true
    • Privy SDK is still initializing
    • No conflict occurs
  2. Second refresh:

    • Wagmi hydrates from localStorage → isConnected: true
    • Privy's Base Account SDK fully initializes
    • Privy SDK detects existing Coinbase connection
    • Privy attempts to validate/interact with the session
    • Conflict: Both Privy's Base Account SDK and Coinbase Wallet SDK try to manage the same session
    • Coinbase SDK invalidates the session
    • Wagmi receives disconnect event

Key observation: The issue only occurs when Privy is loaded alongside wagmi. Without Privy, reconnection works perfectly on all refreshes.

Our Workaround

We implemented conditional Privy loading to avoid SDK conflicts:

// Check if external wallet is connected on app load
function hasActiveExternalWalletConnection(): boolean {
  const wagmiStore = localStorage.getItem("wagmi.pinto.store");
  // Check for non-Privy connections
  // ...
}

// Skip Privy when external wallet is connected
const skipPrivy = hasActiveExternalWalletConnection();

// Render appropriate provider
{skipPrivy ? (
  <WagmiProviderOnly>{children}</WagmiProviderOnly>
) : (
  <PrivyProvider>
    <WagmiProvider>{children}</WagmiProvider>
  </PrivyProvider>
)}

This prevents Privy's SDK from interfering with Coinbase Wallet sessions.

Configuration

// wagmi config
export const buildBaseConfigParams = () => ({
  chains: getChainConfig(),
  transports: getTransportsConfig(),
  connectors: [
    injected(),
    walletConnect(),
    coinbaseWallet({
      appName: "Pinto",
      appLogoUrl: "https://pinto.money/pinto-logo.png",
    }),
    privyConnector(), // Custom connector for Privy embedded wallets
  ],
  storage: createStorage({
    storage: window.localStorage,
    key: "wagmi.pinto",
  }),
  reconnectOnMount: false, // We handle reconnection manually
});

Proposed Solution

We believe this is a broader issue with SDK interoperability. Possible solutions:

  1. Wagmi-level isolation: Add a config option to prevent external SDKs from interfering with wagmi's connection state
  2. Connector lifecycle hooks: Expose hooks like onBeforeReconnect / onAfterReconnect to allow apps to coordinate between multiple wallet SDKs
  3. Session ownership: Implement a locking mechanism where only one SDK can "own" a wallet session at a time
  4. Documentation: Add guidance on using wagmi with other wallet SDKs (Privy, Dynamic, etc.) to prevent conflicts

Additional Context

  • This affects any app using both Privy (for email/social login) and wagmi (for external wallets)
  • The conflict is specifically with Privy's Base Account SDK, which is used for smart account functionality
  • Other external wallets (MetaMask, WalletConnect) work fine because they don't have the same SDK overlap

Link to Minimal Reproducible Example

pinto-org/interface#375

Steps To Reproduce

Steps to Reproduce

  1. Clone our repository and checkout the specific commit:

    git clone https://github.com/pinto-org/interface.git
    cd interface
    git checkout fix/coinbase-wallet-implementation
    git checkout fe9dc4dda6f6f0acd90fed502518f01b73f81b52
  2. Install dependencies and run:

    yarn install
    yarn dev
  3. Connect with Coinbase Wallet:

    • Open http://localhost:5173 in browser
    • Click "Connect Wallet"
    • Select Coinbase Wallet (smart wallet)
    • Complete connection
  4. First page refresh:

    • Refresh the page (F5)
    • ✅ Wallet reconnects successfully
  5. Second page refresh:

    • Refresh the page again (F5)
    • ❌ Wallet disconnects unexpectedly
    • localStorage still contains valid session data
  6. Verify the cause:

    • Remove <PrivyProvider> from src/Web3Provider.tsx
    • Repeat steps 3-5
    • ✅ Wallet reconnects correctly on all refreshes

What Wagmi package(s) are you using?

wagmi, @wagmi/cli, @wagmi/connectors, @wagmi/core

Wagmi Package(s) Version(s)

2.16.0

Viem Version

2.33.1

TypeScript Version

5.5.3

Anything else?

An issue was previously opened as #4375 , but it was closed because the developer didn’t provide reproducible code. Also, using two providers might not be healthy, but what I’m mainly wondering is why the conflict happens only with Coinbase Wallet. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions