From 934cd5f7c7ad89a424d682493157351e460b8f54 Mon Sep 17 00:00:00 2001 From: Khizr Reown Date: Tue, 12 May 2026 18:02:06 +0500 Subject: [PATCH] fix(wagmi): respect coinbasePreference when selecting Coinbase connector Routes addThirdPartyConnectors based on coinbasePreference: 'smartWalletOnly' uses the baseAccount connector; 'all' and 'eoaOnly' use coinbaseWallet with the preference forwarded so QR code and EOA flows work correctly. Regression from PR #5269 which hardcoded baseAccount regardless of the option. Co-Authored-By: Claude Sonnet 4.6 --- .changeset/fix-coinbase-preference-ignored.md | 5 ++ packages/adapters/wagmi/src/client.ts | 22 +++++-- .../adapters/wagmi/src/tests/client.test.ts | 65 +++++++++++++++---- packages/adapters/wagmi/src/utils/helpers.ts | 5 +- 4 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 .changeset/fix-coinbase-preference-ignored.md diff --git a/.changeset/fix-coinbase-preference-ignored.md b/.changeset/fix-coinbase-preference-ignored.md new file mode 100644 index 0000000000..470e899f00 --- /dev/null +++ b/.changeset/fix-coinbase-preference-ignored.md @@ -0,0 +1,5 @@ +--- +"@reown/appkit-adapter-wagmi": patch +--- + +Fix `coinbasePreference` option being ignored — `'all'` and `'eoaOnly'` now correctly use the `coinbaseWallet` connector (with QR code support) instead of always using `baseAccount`. `'smartWalletOnly'` uses `baseAccount`. Regression introduced in PR #5269. diff --git a/packages/adapters/wagmi/src/client.ts b/packages/adapters/wagmi/src/client.ts index 745f07a8bd..f1f87e4457 100644 --- a/packages/adapters/wagmi/src/client.ts +++ b/packages/adapters/wagmi/src/client.ts @@ -298,18 +298,26 @@ export class WagmiAdapter extends AdapterBlueprint { private async addThirdPartyConnectors() { const thirdPartyConnectors: CreateConnectorFn[] = [] - const { enableCoinbase: isCoinbaseEnabled, enableBaseAccount: isBaseAccountEnabled } = - OptionsController.state || {} + const { + enableCoinbase: isCoinbaseEnabled, + enableBaseAccount: isBaseAccountEnabled, + coinbasePreference + } = OptionsController.state || {} + + // baseAccount connector is for smart wallet only — use it when preference is smartWalletOnly + const useBaseAccount = + coinbasePreference === 'smartWalletOnly' && isBaseAccountEnabled !== false - if (isBaseAccountEnabled !== false) { + if (useBaseAccount) { const baseAccountConnector = await getBaseAccountConnector(this.wagmiConfig.connectors) if (baseAccountConnector) { thirdPartyConnectors.push(baseAccountConnector) } - } - - if (isCoinbaseEnabled !== false) { - const coinbaseConnector = await getCoinbaseConnector(this.wagmiConfig.connectors) + } else if (isCoinbaseEnabled !== false) { + const coinbaseConnector = await getCoinbaseConnector( + this.wagmiConfig.connectors, + coinbasePreference + ) if (coinbaseConnector) { thirdPartyConnectors.push(coinbaseConnector) } diff --git a/packages/adapters/wagmi/src/tests/client.test.ts b/packages/adapters/wagmi/src/tests/client.test.ts index 3345fd07f6..924e693d85 100644 --- a/packages/adapters/wagmi/src/tests/client.test.ts +++ b/packages/adapters/wagmi/src/tests/client.test.ts @@ -1561,7 +1561,11 @@ describe('WagmiAdapter - addThirdPartyConnectors', () => { vi.restoreAllMocks() }) - it('should add Base Account connector if enableBaseAccount is not false', async () => { + it('should add Base Account connector when coinbasePreference is smartWalletOnly', async () => { + vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({ + ...(OptionsController.state || {}), + coinbasePreference: 'smartWalletOnly' + }) const getBaseAccountConnectorSpy = vi .spyOn(helpers, 'getBaseAccountConnector') .mockResolvedValue(mockBaseAccountConnector() as any) @@ -1569,17 +1573,21 @@ describe('WagmiAdapter - addThirdPartyConnectors', () => { await adapter['addThirdPartyConnectors']() expect(getBaseAccountConnectorSpy).toHaveBeenCalled() expect(adapter.wagmiConfig.connectors.length).toBe(1) + expect(adapter.wagmiConfig.connectors.some(c => c.id === 'baseAccount')).toBe(true) }) it('should not add Base Account connector if enableBaseAccount is false', async () => { vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({ ...(OptionsController.state || {}), + coinbasePreference: 'smartWalletOnly', enableBaseAccount: false }) - vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue(null) - vi.spyOn(helpers, 'getCoinbaseConnector').mockResolvedValue(null) + const getBaseAccountConnectorSpy = vi + .spyOn(helpers, 'getBaseAccountConnector') + .mockResolvedValue(null) + vi.spyOn(helpers, 'getCoinbaseConnector').mockResolvedValue(mockCoinbaseConnector() as any) await adapter['addThirdPartyConnectors']() - expect(adapter.wagmiConfig.connectors.length).toBe(0) + expect(getBaseAccountConnectorSpy).not.toHaveBeenCalled() }) it('should add Coinbase connector if enableCoinbase is not false', async () => { @@ -1603,14 +1611,49 @@ describe('WagmiAdapter - addThirdPartyConnectors', () => { expect(adapter.wagmiConfig.connectors.length).toBe(0) }) - it('should add both Base Account and Coinbase connectors when both are enabled', async () => { - vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue( - mockBaseAccountConnector() as any - ) - vi.spyOn(helpers, 'getCoinbaseConnector').mockResolvedValue(mockCoinbaseConnector() as any) + it('should use coinbaseWallet with preference "all" by default', async () => { + vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({ + ...(OptionsController.state || {}), + coinbasePreference: 'all' + }) + vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue(null) + const getCoinbaseConnectorSpy = vi + .spyOn(helpers, 'getCoinbaseConnector') + .mockResolvedValue(mockCoinbaseConnector() as any) await adapter['addThirdPartyConnectors']() - expect(adapter.wagmiConfig.connectors.length).toBe(2) - expect(adapter.wagmiConfig.connectors.some(c => c.id === 'baseAccount')).toBe(true) + expect(getCoinbaseConnectorSpy).toHaveBeenCalledWith(adapter.wagmiConfig.connectors, 'all') + expect(adapter.wagmiConfig.connectors.some(c => c.id === 'coinbaseWallet')).toBe(true) + }) + + it('should use coinbaseWallet with preference "eoaOnly" when coinbasePreference is eoaOnly', async () => { + vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({ + ...(OptionsController.state || {}), + coinbasePreference: 'eoaOnly' + }) + vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue(null) + const getCoinbaseConnectorSpy = vi + .spyOn(helpers, 'getCoinbaseConnector') + .mockResolvedValue(mockCoinbaseConnector() as any) + await adapter['addThirdPartyConnectors']() + expect(getCoinbaseConnectorSpy).toHaveBeenCalledWith(adapter.wagmiConfig.connectors, 'eoaOnly') + expect(adapter.wagmiConfig.connectors.some(c => c.id === 'coinbaseWallet')).toBe(true) + }) + + it('should fall back to coinbaseWallet when coinbasePreference is smartWalletOnly but enableBaseAccount is false', async () => { + vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({ + ...(OptionsController.state || {}), + coinbasePreference: 'smartWalletOnly', + enableBaseAccount: false + }) + vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue(null) + const getCoinbaseConnectorSpy = vi + .spyOn(helpers, 'getCoinbaseConnector') + .mockResolvedValue(mockCoinbaseConnector() as any) + await adapter['addThirdPartyConnectors']() + expect(getCoinbaseConnectorSpy).toHaveBeenCalledWith( + adapter.wagmiConfig.connectors, + 'smartWalletOnly' + ) expect(adapter.wagmiConfig.connectors.some(c => c.id === 'coinbaseWallet')).toBe(true) }) diff --git a/packages/adapters/wagmi/src/utils/helpers.ts b/packages/adapters/wagmi/src/utils/helpers.ts index 787e12acbc..71b4da55f8 100644 --- a/packages/adapters/wagmi/src/utils/helpers.ts +++ b/packages/adapters/wagmi/src/utils/helpers.ts @@ -86,13 +86,14 @@ export async function getBaseAccountConnector( } export async function getCoinbaseConnector( - connectors: readonly Connector[] + connectors: readonly Connector[], + preference?: 'all' | 'smartWalletOnly' | 'eoaOnly' ): Promise { try { const { coinbaseWallet } = await import('@wagmi/connectors') if (coinbaseWallet && !connectors.some(c => c.id === 'coinbaseWallet')) { - return coinbaseWallet() + return coinbaseWallet({ preference }) } } catch (error) { // eslint-disable-next-line no-console