Skip to content

Commit ecf1794

Browse files
authored
chore: lazy load coinbase (#5336)
1 parent 0115324 commit ecf1794

File tree

16 files changed

+315
-326
lines changed

16 files changed

+315
-326
lines changed

.changeset/lovely-pets-join.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@reown/appkit-adapter-ethers5': patch
3+
'@reown/appkit-adapter-ethers': patch
4+
'@reown/appkit-utils': patch
5+
'@reown/appkit': patch
6+
---
7+
8+
Defers Coinbase SDK in ethers adapters to connection step

packages/adapters/ethers/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@
2929
"@walletconnect/universal-provider": "2.23.0",
3030
"valtio": "2.1.7"
3131
},
32-
"optionalDependencies": {
33-
"@base-org/account": "2.4.0",
34-
"@safe-global/safe-apps-provider": "0.18.6",
35-
"@safe-global/safe-apps-sdk": "9.1.0"
36-
},
3732
"peerDependencies": {
3833
"@ethersproject/sha2": "5.8.0",
3934
"ethers": ">=6"

packages/adapters/ethers/src/client.ts

Lines changed: 39 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,14 @@ import {
3030
} from '@reown/appkit-controllers'
3131
import { ConnectorUtil } from '@reown/appkit-scaffold-ui/utils'
3232
import { ConstantsUtil, HelpersUtil, PresetsUtil } from '@reown/appkit-utils'
33-
import { type Address, EthersHelpersUtil, type ProviderType } from '@reown/appkit-utils/ethers'
33+
import {
34+
type Address,
35+
BaseProvider,
36+
EthersHelpersUtil,
37+
InjectedProvider,
38+
type ProviderType,
39+
SafeProvider
40+
} from '@reown/appkit-utils/ethers'
3441
import type { W3mFrameProvider } from '@reown/appkit-wallet'
3542

3643
import { EthersMethods } from './utils/EthersMethods.js'
@@ -44,6 +51,7 @@ export class EthersAdapter extends AdapterBlueprint {
4451
private ethersConfig?: ProviderType
4552
private balancePromises: Record<string, Promise<AdapterBlueprint.GetBalanceResult>> = {}
4653
private universalProvider?: UniversalProvider
54+
private ethersProviders: Omit<ProviderType, 'metadata' | 'EIP6963'> = {}
4755

4856
constructor() {
4957
super({
@@ -53,99 +61,35 @@ export class EthersAdapter extends AdapterBlueprint {
5361
}
5462

5563
private async createEthersConfig() {
56-
const { metadata, coinbasePreference, enableCoinbase, enableInjected, enableEIP6963 } =
57-
OptionsController.state
64+
const { metadata, enableCoinbase, enableInjected, enableEIP6963 } = OptionsController.state
5865

5966
if (!metadata) {
6067
return undefined
6168
}
6269

63-
let injectedProvider: Provider | undefined = undefined
64-
65-
function getInjectedProvider() {
66-
if (injectedProvider) {
67-
return injectedProvider
68-
}
69-
70-
if (typeof window === 'undefined') {
71-
return undefined
72-
}
73-
74-
if (!window.ethereum) {
75-
return undefined
76-
}
77-
78-
// @ts-expect-error window.ethereum satisfies Provider
79-
injectedProvider = window.ethereum
80-
81-
return injectedProvider
82-
}
83-
84-
async function getSafeProvider() {
85-
const { SafeProvider } = await import('./utils/SafeProvider.js')
86-
const { default: SafeAppsSDK } = await import('@safe-global/safe-apps-sdk')
87-
const appsSdk = new SafeAppsSDK()
88-
const info = await appsSdk.safe.getInfo()
89-
90-
const provider = new SafeProvider(info, appsSdk)
91-
await provider.connect().catch(error => {
92-
// eslint-disable-next-line no-console
93-
console.info('Failed to auto-connect to Safe:', error)
94-
})
95-
96-
return provider
97-
}
98-
99-
async function getBaseAccountProvider() {
100-
const caipNetworks = ChainController.getCaipNetworks()
101-
try {
102-
const { createBaseAccountSDK } = await import('@base-org/account')
103-
if (typeof window === 'undefined') {
104-
return undefined
105-
}
106-
107-
const baseAccountSdk = createBaseAccountSDK({
108-
appName: metadata?.name,
109-
appLogoUrl: metadata?.icons[0],
110-
appChainIds: caipNetworks?.map(caipNetwork => caipNetwork.id as number) || [1, 84532],
111-
preference: {
112-
options: coinbasePreference ?? 'all'
113-
}
114-
})
115-
116-
return baseAccountSdk.getProvider()
117-
} catch (error) {
118-
// eslint-disable-next-line no-console
119-
console.error('Failed to import Coinbase Wallet SDK:', error)
120-
121-
return undefined
122-
}
123-
}
124-
125-
const providers: ProviderType = { metadata: metadata ?? {} }
126-
12770
if (enableInjected !== false) {
128-
providers.injected = getInjectedProvider()
71+
const injectedProvider = new InjectedProvider()
72+
await injectedProvider.initialize()
73+
this.ethersProviders.injected = injectedProvider
12974
}
13075

13176
if (enableCoinbase !== false) {
132-
const baseAccountProvider = await getBaseAccountProvider()
133-
134-
if (baseAccountProvider) {
135-
providers[CommonConstantsUtil.CONNECTOR_ID.BASE_ACCOUNT] = baseAccountProvider
136-
}
77+
// Do not initialize provider to prevent unnecessary api calls- lazy load
78+
this.ethersProviders.baseAccount = new BaseProvider()
13779
}
13880

13981
if (CoreHelperUtil.isSafeApp()) {
140-
const safeProvider = await getSafeProvider()
141-
if (safeProvider) {
142-
providers.safe = safeProvider
143-
}
82+
const safeProvider = new SafeProvider()
83+
// Initialize the safe provider during intialization
84+
await safeProvider.initialize()
85+
this.ethersProviders.safe = safeProvider
14486
}
14587

146-
providers.EIP6963 = enableEIP6963 !== false
147-
148-
return providers
88+
return {
89+
...this.ethersProviders,
90+
EIP6963: enableEIP6963 !== false,
91+
metadata
92+
}
14993
}
15094

15195
public async signMessage(
@@ -299,10 +243,12 @@ export class EthersAdapter extends AdapterBlueprint {
299243
key => key !== 'metadata' && key !== 'EIP6963'
300244
)
301245

302-
connectors.forEach(connector => {
246+
const connectorPromises = connectors.map(async connector => {
303247
const isInjectedConnector = connector === CommonConstantsUtil.CONNECTOR_ID.INJECTED
304248

305249
if (this.namespace) {
250+
const provider =
251+
this.ethersProviders[connector as keyof Omit<ProviderType, 'metadata' | 'EIP6963'>]
306252
this.addConnector({
307253
id: connector,
308254
explorerId: PresetsUtil.ConnectorExplorerIds[connector],
@@ -313,10 +259,12 @@ export class EthersAdapter extends AdapterBlueprint {
313259
info: isInjectedConnector ? undefined : { rdns: connector },
314260
chain: this.namespace,
315261
chains: [],
316-
provider: this.ethersConfig?.[connector as keyof ProviderType] as Provider
262+
provider: (await provider?.getProvider()) as Provider
317263
})
318264
}
319265
})
266+
267+
await Promise.all(connectorPromises)
320268
}
321269

322270
private async disconnectAll() {
@@ -511,12 +459,20 @@ export class EthersAdapter extends AdapterBlueprint {
511459
}
512460
}
513461

514-
const selectedProvider = connector?.provider as Provider
462+
let selectedProvider = connector?.provider as Provider | undefined
463+
const ethersProvider =
464+
this.ethersProviders[connector.id as keyof Omit<ProviderType, 'metadata' | 'EIP6963'>]
465+
if (ethersProvider) {
466+
await ethersProvider.initialize()
467+
selectedProvider = (await ethersProvider.getProvider()) as Provider | undefined
468+
}
515469

516470
if (!selectedProvider) {
517471
throw new Error('Provider not found')
518472
}
519473

474+
connector.provider = selectedProvider
475+
520476
let accounts: string[] = []
521477

522478
let requestChainId: string | undefined = undefined

packages/adapters/ethers/src/tests/client.test.ts

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -111,33 +111,6 @@ describe('EthersAdapter', () => {
111111
ancestorOrigins: ['https://app.safe.global']
112112
}
113113
})
114-
vi.mock('@base-org/account', async () => {
115-
const actual = await import('@base-org/account')
116-
return {
117-
...actual,
118-
createBaseAccountSDK: vi.fn(() => ({
119-
getProvider: vi.fn(() => {
120-
return {
121-
request: vi.fn(),
122-
connect: vi.fn()
123-
}
124-
})
125-
}))
126-
}
127-
})
128-
vi.mock('@safe-global/safe-apps-sdk', () => ({
129-
default: vi.fn(() => ({
130-
safe: {
131-
getInfo: vi.fn(),
132-
getProvider: vi.fn(() => {
133-
return {
134-
request: vi.fn(),
135-
connect: vi.fn()
136-
}
137-
})
138-
}
139-
}))
140-
}))
141114

142115
adapter = new EthersAdapter()
143116
ChainController.initialize([adapter], mockCaipNetworks, {
@@ -1261,7 +1234,28 @@ describe('EthersAdapter', () => {
12611234
...OptionsController.state,
12621235
metadata: mockEthersConfig.metadata
12631236
})
1237+
1238+
vi.mock('@reown/appkit-utils/ethers', async () => {
1239+
const actual = await import('@reown/appkit-utils/ethers')
1240+
return {
1241+
...actual,
1242+
SafeProvider: vi.fn(() => ({
1243+
initialize: vi.fn()
1244+
})),
1245+
BaseProvider: vi.fn(() => ({
1246+
initialize: vi.fn()
1247+
})),
1248+
InjectedProvider: vi.fn(() => ({
1249+
initialize: vi.fn()
1250+
}))
1251+
}
1252+
})
12641253
})
1254+
1255+
beforeEach(() => {
1256+
vi.clearAllMocks()
1257+
})
1258+
12651259
it('should create Ethers config with coinbase provider if not disabled', async () => {
12661260
const ethersAdapter = new EthersAdapter()
12671261
const providers = await ethersAdapter['createEthersConfig']()

packages/adapters/ethers/src/utils/SafeProvider.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

packages/adapters/ethers5/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@
2929
"@walletconnect/universal-provider": "2.23.0",
3030
"valtio": "2.1.7"
3131
},
32-
"optionalDependencies": {
33-
"@base-org/account": "2.4.0",
34-
"@safe-global/safe-apps-provider": "0.18.6",
35-
"@safe-global/safe-apps-sdk": "9.1.0"
36-
},
3732
"peerDependencies": {
3833
"@ethersproject/sha2": "5.8.0",
3934
"ethers": ">=4.1 <6.0.0"

0 commit comments

Comments
 (0)