Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions packages/adapters/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { HelpersUtil } from '@reown/appkit-utils'
import {
type Address,
BaseProvider,
CoinbaseWalletProvider,
EthersHelpersUtil,
InjectedProvider,
type ProviderType,
Expand Down Expand Up @@ -62,7 +63,8 @@ export class EthersAdapter extends AdapterBlueprint {
}

private async createEthersConfig() {
const { metadata, enableCoinbase, enableInjected, enableEIP6963 } = OptionsController.state
const { metadata, enableBaseAccount, enableCoinbase, enableInjected, enableEIP6963 } =
OptionsController.state

if (!metadata) {
return undefined
Expand All @@ -74,11 +76,16 @@ export class EthersAdapter extends AdapterBlueprint {
this.ethersProviders.injected = injectedProvider
}

if (enableCoinbase !== false) {
if (enableBaseAccount !== false) {
// Do not initialize provider to prevent unnecessary api calls- lazy load
this.ethersProviders.baseAccount = new BaseProvider()
}

if (enableCoinbase !== false) {
// Do not initialize provider to prevent unnecessary api calls- lazy load
this.ethersProviders.coinbaseWallet = new CoinbaseWalletProvider()
}

if (CoreHelperUtil.isSafeApp()) {
const safeProvider = new SafeProvider()
// Initialize the safe provider during intialization
Expand Down
4 changes: 2 additions & 2 deletions packages/adapters/ethers/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1298,10 +1298,10 @@ describe('EthersAdapter', () => {
expect(providers?.baseAccount).toBeDefined()
})

it('should create Ethers config without coinbase provider if disabled', async () => {
it('should create Ethers config without base account provider if disabled', async () => {
vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({
...OptionsController.state,
enableCoinbase: false
enableBaseAccount: false
})
const providers = await adapter['createEthersConfig']()

Expand Down
11 changes: 9 additions & 2 deletions packages/adapters/ethers5/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { HelpersUtil } from '@reown/appkit-utils'
import {
type Address,
BaseProvider,
CoinbaseWalletProvider,
EthersHelpersUtil,
InjectedProvider,
type ProviderType,
Expand Down Expand Up @@ -61,7 +62,8 @@ export class Ethers5Adapter extends AdapterBlueprint {
}

private async createEthersConfig() {
const { metadata, enableCoinbase, enableInjected, enableEIP6963 } = OptionsController.state
const { metadata, enableBaseAccount, enableCoinbase, enableInjected, enableEIP6963 } =
OptionsController.state
if (!metadata) {
return undefined
}
Expand All @@ -72,11 +74,16 @@ export class Ethers5Adapter extends AdapterBlueprint {
this.ethersProviders.injected = injectedProvider
}

if (enableCoinbase !== false) {
if (enableBaseAccount !== false) {
// Do not initialize provider to prevent unnecessary api calls- lazy load
this.ethersProviders.baseAccount = new BaseProvider()
}

if (enableCoinbase !== false) {
// Do not initialize provider to prevent unnecessary api calls- lazy load
this.ethersProviders.coinbaseWallet = new CoinbaseWalletProvider()
}

if (CoreHelperUtil.isSafeApp()) {
const safeProvider = new SafeProvider()
await safeProvider.initialize()
Expand Down
23 changes: 19 additions & 4 deletions packages/adapters/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@
import { authConnector } from './connectors/AuthConnector.js'
import { walletConnect } from './connectors/WalletConnectConnector.js'
import { LimitterUtil } from './utils/LimitterUtil.js'
import { getBaseAccountConnector, getSafeConnector } from './utils/helpers.js'
import {
getBaseAccountConnector,
getCoinbaseWalletConnector,
getSafeConnector
} from './utils/helpers.js'

interface PendingTransactionsFilter {
enable: boolean
Expand Down Expand Up @@ -289,14 +293,22 @@

private async addThirdPartyConnectors() {
const thirdPartyConnectors: CreateConnectorFn[] = []
const { enableCoinbase: isCoinbaseEnabled } = OptionsController.state || {}
if (isCoinbaseEnabled !== false) {
const { enableCoinbase, enableBaseAccount } = OptionsController.state || {}

Check warning on line 296 in packages/adapters/wagmi/src/client.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Variable name `enableBaseAccount` must have one of the following prefixes: is, has, can, should, will, did

Check warning on line 296 in packages/adapters/wagmi/src/client.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Variable name `enableCoinbase` must have one of the following prefixes: is, has, can, should, will, did

if (enableBaseAccount !== false) {
const baseAccountConnector = await getBaseAccountConnector(this.wagmiConfig.connectors)
if (baseAccountConnector) {
thirdPartyConnectors.push(baseAccountConnector)
}
}

if (enableCoinbase !== false) {
const coinbaseWalletConnector = await getCoinbaseWalletConnector(this.wagmiConfig.connectors)
if (coinbaseWalletConnector) {
thirdPartyConnectors.push(coinbaseWalletConnector)
}
}

const safeConnector = await getSafeConnector(this.wagmiConfig.connectors)
if (safeConnector) {
thirdPartyConnectors.push(safeConnector)
Expand Down Expand Up @@ -500,7 +512,10 @@
}

let provider: Provider | undefined = undefined
if (connector.id !== CommonConstantsUtil.CONNECTOR_ID.BASE_ACCOUNT) {
if (
connector.id !== CommonConstantsUtil.CONNECTOR_ID.BASE_ACCOUNT &&
connector.id !== CommonConstantsUtil.CONNECTOR_ID.COINBASE_SDK
) {
provider = (await connector.getProvider().catch(() => undefined)) as Provider | undefined
}

Expand Down
19 changes: 14 additions & 5 deletions packages/adapters/wagmi/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ describe('WagmiAdapter', () => {
vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue(
mockBaseAccountConnector() as any
)
vi.spyOn(helpers, 'getCoinbaseWalletConnector').mockResolvedValue(null)
vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({
...OptionsController.state
})
Expand Down Expand Up @@ -1520,6 +1521,9 @@ describe('WagmiAdapter - addThirdPartyConnectors', () => {
vi.spyOn(CoreHelperUtil, 'isClient').mockReturnValue(true)
}

// Mock getCoinbaseWalletConnector to return null by default
vi.spyOn(helpers, 'getCoinbaseWalletConnector').mockResolvedValue(null)

adapter = new WagmiAdapter({
networks: mockNetworks,
projectId: mockProjectId
Expand Down Expand Up @@ -1548,18 +1552,20 @@ describe('WagmiAdapter - addThirdPartyConnectors', () => {
vi.restoreAllMocks()
})

it('should add Coinbase connector if enableCoinbase is not false', async () => {
const getCoinbaseConnectorSpy = vi
it('should add Base Account connector if enableBaseAccount is not false', async () => {
vi.spyOn(helpers, 'getCoinbaseWalletConnector').mockResolvedValue(null)
const getBaseAccountConnectorSpy = vi
.spyOn(helpers, 'getBaseAccountConnector')
.mockResolvedValue(mockBaseAccountConnector() as any)
await adapter['addThirdPartyConnectors']()
expect(getCoinbaseConnectorSpy).toHaveBeenCalled()
expect(adapter.wagmiConfig.connectors.length).toBe(1)
expect(getBaseAccountConnectorSpy).toHaveBeenCalled()
expect(adapter.wagmiConfig.connectors.length).toBeGreaterThanOrEqual(1)
})

it('should not add Coinbase connector if enableCoinbase is false', async () => {
it('should not add Base Account connector if enableBaseAccount is false', async () => {
vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({
...(OptionsController.state || {}),
enableBaseAccount: false,
enableCoinbase: false
})
await adapter['addThirdPartyConnectors']()
Expand Down Expand Up @@ -1636,6 +1642,8 @@ describe('WagmiAdapter - BaseAccount lazy initialization', () => {
vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({
...OptionsController.state
})
// Mock getCoinbaseWalletConnector to return null
vi.spyOn(helpers, 'getCoinbaseWalletConnector').mockResolvedValue(null)

adapter = new WagmiAdapter({
networks: [mainnet],
Expand All @@ -1656,6 +1664,7 @@ describe('WagmiAdapter - BaseAccount lazy initialization', () => {
.mockResolvedValue({ connect: vi.fn(), request: vi.fn() })

vi.spyOn(helpers, 'getBaseAccountConnector').mockResolvedValue(baseConnector as any)
vi.spyOn(helpers, 'getCoinbaseWalletConnector').mockResolvedValue(null)

await adapter.syncConnectors()

Expand Down
19 changes: 18 additions & 1 deletion packages/adapters/wagmi/src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,24 @@ export async function getBaseAccountConnector(
}
} catch (error) {
// eslint-disable-next-line no-console
console.error('Failed to import Coinbase Wallet SDK:', error)
console.error('Failed to import Base Account SDK:', error)
}

return null
}

export async function getCoinbaseWalletConnector(
connectors: readonly Connector[]
): Promise<CreateConnectorFn | null> {
try {
const { coinbaseWallet } = await import('@wagmi/connectors')

if (coinbaseWallet && !connectors.some(c => c.id === 'coinbaseWalletSDK')) {
return coinbaseWallet({ version: '4', preference: 'all' })
}
} catch (error) {
// eslint-disable-next-line no-console
console.error('Failed to import Coinbase Wallet connector:', error)
}

return null
Expand Down
1 change: 1 addition & 0 deletions packages/appkit-utils/exports/ethers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from '../src/ethers/EthersHelpersUtil.js'
export * from '../src/ethers/BaseProvider.js'
export * from '../src/ethers/CoinbaseWalletProvider.js'
export * from '../src/ethers/SafeProvider.js'
export * from '../src/ethers/InjectedProvider.js'
export * from '../src/ethers/EthersProvider.js'
Expand Down
1 change: 1 addition & 0 deletions packages/appkit-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
},
"optionalDependencies": {
"@base-org/account": "2.4.0",
"@coinbase/wallet-sdk": "4.3.3",
"@safe-global/safe-apps-provider": "0.18.6",
"@safe-global/safe-apps-sdk": "9.1.0"
},
Expand Down
38 changes: 38 additions & 0 deletions packages/appkit-utils/src/ethers/CoinbaseWalletProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { ProviderInterface } from '@coinbase/wallet-sdk'

import { ChainController, OptionsController } from '@reown/appkit-controllers'

import { EthersProvider } from './EthersProvider.js'

export class CoinbaseWalletProvider extends EthersProvider<ProviderInterface> {
async initialize(): Promise<void> {
const caipNetworks = ChainController.getCaipNetworks()
const { metadata } = OptionsController.state
try {
const { CoinbaseWalletSDK } = await import('@coinbase/wallet-sdk')
if (typeof window === 'undefined') {
return Promise.resolve()
}

const sdk = new CoinbaseWalletSDK({
appName: metadata?.name ?? '',
appLogoUrl: metadata?.icons[0] ?? null,
appChainIds: caipNetworks?.map(caipNetwork => caipNetwork.id as number) || [1, 84532]
})

this.provider = sdk.makeWeb3Provider({ options: 'all' })
this.initialized = true

return Promise.resolve()
} catch (error) {
// eslint-disable-next-line no-console
console.error('Failed to import Coinbase Wallet SDK:', error)

return Promise.resolve()
}
}

override async getProvider(): Promise<ProviderInterface | undefined> {
return Promise.resolve(this.provider)
}
}
2 changes: 2 additions & 0 deletions packages/appkit-utils/src/ethers/EthersTypesUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type UniversalProvider from '@walletconnect/universal-provider'
import type { W3mFrameProvider } from '@reown/appkit-wallet'

import type { BaseProvider } from './BaseProvider.js'
import type { CoinbaseWalletProvider } from './CoinbaseWalletProvider.js'
import type { InjectedProvider } from './InjectedProvider.js'
import type { SafeProvider } from './SafeProvider.js'

Expand All @@ -11,6 +12,7 @@ export type Address = `0x${string}`
export type ProviderType = {
injected?: InjectedProvider
baseAccount?: BaseProvider
coinbaseWallet?: CoinbaseWalletProvider
safe?: SafeProvider
EIP6963?: boolean
metadata: Metadata
Expand Down
1 change: 1 addition & 0 deletions packages/appkit/src/client/appkit-base-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@
OptionsController.setEnableWallets(options.enableWallets !== false)
OptionsController.setEIP6963Enabled(options.enableEIP6963 !== false)
OptionsController.setEnableCoinbase(options.enableCoinbase !== false)
OptionsController.setEnableBaseAccount(options.enableBaseAccount !== false)
OptionsController.setEnableNetworkSwitch(options.enableNetworkSwitch !== false)
OptionsController.setEnableReconnect(options.enableReconnect !== false)
OptionsController.setEnableMobileFullScreen(options.enableMobileFullScreen === true)
Expand Down Expand Up @@ -640,7 +641,7 @@
await this.disconnectConnector(params.namespace, params.id)
},
disconnect: async params => {
const { id: connectorIdParam, chainNamespace, initialDisconnect } = params || {}

Check warning on line 644 in packages/appkit/src/client/appkit-base-client.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Variable name `initialDisconnect` must have one of the following prefixes: is, has, can, should, will, did

const namespace = chainNamespace || ChainController.state.activeChain
const namespaceConnectorId = ConnectorController.getConnectorId(namespace)
Expand Down
11 changes: 10 additions & 1 deletion packages/controllers/src/controllers/OptionsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,15 @@ export interface OptionsControllerStatePublic {
*/
enableEIP6963?: boolean
/**
* Enable or disable the Coinbase wallet.
* Enable or disable the Coinbase Wallet SDK connector (@coinbase/wallet-sdk).
* @default true
*/
enableCoinbase?: boolean
/**
* Enable or disable the Base Account SDK connector (@base-org/account).
* @default true
*/
enableBaseAccount?: boolean
/**
* Enable or disable the Injected wallet.
* @default true
Expand Down Expand Up @@ -347,6 +352,10 @@ export const OptionsController = {
state.enableCoinbase = enableCoinbase
},

setEnableBaseAccount(enableBaseAccount: OptionsControllerState['enableBaseAccount']) {
state.enableBaseAccount = enableBaseAccount
},

setDebug(debug: OptionsControllerState['debug']) {
state.debug = debug
},
Expand Down
14 changes: 14 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading