@wagmi/connectors 5.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/coinbaseWallet.js +274 -36
- package/dist/esm/coinbaseWallet.js.map +1 -1
- package/dist/esm/metaMask.js +67 -96
- package/dist/esm/metaMask.js.map +1 -1
- package/dist/esm/safe.js +20 -13
- package/dist/esm/safe.js.map +1 -1
- package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/walletConnect.js +147 -77
- package/dist/esm/walletConnect.js.map +1 -1
- package/dist/types/coinbaseWallet.d.ts +38 -7
- package/dist/types/coinbaseWallet.d.ts.map +1 -1
- package/dist/types/metaMask.d.ts +3 -10
- package/dist/types/metaMask.d.ts.map +1 -1
- package/dist/types/safe.d.ts +2 -2
- package/dist/types/safe.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/walletConnect.d.ts +5 -9
- package/dist/types/walletConnect.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/coinbaseWallet.ts +378 -66
- package/src/metaMask.ts +81 -110
- package/src/safe.ts +29 -14
- package/src/version.ts +1 -1
- package/src/walletConnect.ts +173 -99
- package/dist/esm/exports/index.test-d.js +0 -4
- package/dist/esm/exports/index.test-d.js.map +0 -1
- package/dist/types/exports/index.test-d.d.ts +0 -2
- package/dist/types/exports/index.test-d.d.ts.map +0 -1
package/src/coinbaseWallet.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type CoinbaseWalletProvider,
|
|
3
|
-
CoinbaseWalletSDK,
|
|
4
|
-
} from '@coinbase/wallet-sdk'
|
|
1
|
+
import type { CoinbaseWalletSDK, ProviderInterface } from '@coinbase/wallet-sdk'
|
|
5
2
|
import {
|
|
6
3
|
ChainNotConfiguredError,
|
|
4
|
+
type Connector,
|
|
7
5
|
createConnector,
|
|
8
|
-
normalizeChainId,
|
|
9
6
|
} from '@wagmi/core'
|
|
10
7
|
import type { Evaluate, Mutable, Omit } from '@wagmi/core/internal'
|
|
8
|
+
import type {
|
|
9
|
+
CoinbaseWalletProvider as CBW_Provider,
|
|
10
|
+
CoinbaseWalletSDK as CBW_SDK,
|
|
11
|
+
} from 'cbw-sdk'
|
|
11
12
|
import {
|
|
13
|
+
type AddEthereumChainParameter,
|
|
12
14
|
type ProviderRpcError,
|
|
13
15
|
SwitchChainError,
|
|
14
16
|
UserRejectedRequestError,
|
|
@@ -16,44 +18,75 @@ import {
|
|
|
16
18
|
numberToHex,
|
|
17
19
|
} from 'viem'
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
type Version = '3' | '4'
|
|
22
|
+
|
|
23
|
+
export type CoinbaseWalletParameters<version extends Version = '3'> =
|
|
24
|
+
version extends '4'
|
|
25
|
+
? Evaluate<
|
|
26
|
+
{
|
|
27
|
+
headlessMode?: false | undefined
|
|
28
|
+
/** Coinbase Wallet SDK version */
|
|
29
|
+
version?: version | '3' | undefined
|
|
30
|
+
} & Version4Parameters
|
|
31
|
+
>
|
|
32
|
+
: Evaluate<
|
|
33
|
+
{
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated `headlessMode` will be removed in the next major version. Upgrade to `version: '4'`.
|
|
36
|
+
*/
|
|
37
|
+
headlessMode?: true | undefined
|
|
38
|
+
/**
|
|
39
|
+
* Coinbase Wallet SDK version
|
|
40
|
+
* @deprecated Version 3 will be removed in the next major version. Upgrade to `version: '4'`.
|
|
41
|
+
* @default '4'
|
|
42
|
+
*/
|
|
43
|
+
version?: version | '4' | undefined
|
|
44
|
+
} & Version3Parameters
|
|
45
|
+
>
|
|
46
|
+
|
|
47
|
+
coinbaseWallet.type = 'coinbaseWallet' as const
|
|
48
|
+
export function coinbaseWallet<version extends Version>(
|
|
49
|
+
parameters: CoinbaseWalletParameters<version> = {} as any,
|
|
50
|
+
): version extends '4'
|
|
51
|
+
? ReturnType<typeof version4>
|
|
52
|
+
: ReturnType<typeof version3> {
|
|
53
|
+
if (parameters.version === '3' || parameters.headlessMode)
|
|
54
|
+
return version3(parameters as Version3Parameters) as any
|
|
55
|
+
return version4(parameters as Version4Parameters) as any
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
type Version4Parameters = Mutable<
|
|
59
|
+
Omit<
|
|
60
|
+
ConstructorParameters<typeof CoinbaseWalletSDK>[0],
|
|
61
|
+
'appChainIds' // set via wagmi config
|
|
25
62
|
> & {
|
|
26
63
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @default
|
|
29
|
-
*/
|
|
30
|
-
jsonRpcUrl?: string | undefined
|
|
31
|
-
/**
|
|
32
|
-
* Fallback Ethereum Chain ID
|
|
33
|
-
* @default 1
|
|
34
|
-
*/
|
|
35
|
-
chainId?: number | undefined
|
|
36
|
-
/**
|
|
37
|
-
* Whether or not to reload dapp automatically after disconnect.
|
|
38
|
-
* @default false
|
|
64
|
+
* Preference for the type of wallet to display.
|
|
65
|
+
* @default 'all'
|
|
39
66
|
*/
|
|
40
|
-
|
|
67
|
+
preference?: 'all' | 'smartWalletOnly' | 'eoaOnly' | undefined
|
|
68
|
+
keysUrl?: string | undefined
|
|
41
69
|
}
|
|
42
70
|
>
|
|
43
71
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
function version4(parameters: Version4Parameters) {
|
|
73
|
+
type Provider = ProviderInterface & {
|
|
74
|
+
// for backwards compatibility
|
|
75
|
+
close?(): void
|
|
76
|
+
}
|
|
49
77
|
type Properties = {}
|
|
50
78
|
|
|
51
79
|
let sdk: CoinbaseWalletSDK | undefined
|
|
52
80
|
let walletProvider: Provider | undefined
|
|
53
81
|
|
|
82
|
+
let accountsChanged: Connector['onAccountsChanged'] | undefined
|
|
83
|
+
let chainChanged: Connector['onChainChanged'] | undefined
|
|
84
|
+
let disconnect: Connector['onDisconnect'] | undefined
|
|
85
|
+
|
|
54
86
|
return createConnector<Provider, Properties>((config) => ({
|
|
55
87
|
id: 'coinbaseWalletSDK',
|
|
56
88
|
name: 'Coinbase Wallet',
|
|
89
|
+
supportsSimulation: true,
|
|
57
90
|
type: coinbaseWallet.type,
|
|
58
91
|
async connect({ chainId } = {}) {
|
|
59
92
|
try {
|
|
@@ -62,11 +95,20 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
62
95
|
(await provider.request({
|
|
63
96
|
method: 'eth_requestAccounts',
|
|
64
97
|
})) as string[]
|
|
65
|
-
).map(getAddress)
|
|
98
|
+
).map((x) => getAddress(x))
|
|
66
99
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
100
|
+
if (!accountsChanged) {
|
|
101
|
+
accountsChanged = this.onAccountsChanged.bind(this)
|
|
102
|
+
provider.on('accountsChanged', accountsChanged)
|
|
103
|
+
}
|
|
104
|
+
if (!chainChanged) {
|
|
105
|
+
chainChanged = this.onChainChanged.bind(this)
|
|
106
|
+
provider.on('chainChanged', chainChanged)
|
|
107
|
+
}
|
|
108
|
+
if (!disconnect) {
|
|
109
|
+
disconnect = this.onDisconnect.bind(this)
|
|
110
|
+
provider.on('disconnect', disconnect)
|
|
111
|
+
}
|
|
70
112
|
|
|
71
113
|
// Switch to chain if provided
|
|
72
114
|
let currentChainId = await this.getChainId()
|
|
@@ -92,12 +134,21 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
92
134
|
async disconnect() {
|
|
93
135
|
const provider = await this.getProvider()
|
|
94
136
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
137
|
+
if (accountsChanged) {
|
|
138
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
139
|
+
accountsChanged = undefined
|
|
140
|
+
}
|
|
141
|
+
if (chainChanged) {
|
|
142
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
143
|
+
chainChanged = undefined
|
|
144
|
+
}
|
|
145
|
+
if (disconnect) {
|
|
146
|
+
provider.removeListener('disconnect', disconnect)
|
|
147
|
+
disconnect = undefined
|
|
148
|
+
}
|
|
98
149
|
|
|
99
150
|
provider.disconnect()
|
|
100
|
-
provider.close()
|
|
151
|
+
provider.close?.()
|
|
101
152
|
},
|
|
102
153
|
async getAccounts() {
|
|
103
154
|
const provider = await this.getProvider()
|
|
@@ -105,27 +156,259 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
105
156
|
await provider.request<string[]>({
|
|
106
157
|
method: 'eth_accounts',
|
|
107
158
|
})
|
|
108
|
-
).map(getAddress)
|
|
159
|
+
).map((x) => getAddress(x))
|
|
109
160
|
},
|
|
110
161
|
async getChainId() {
|
|
111
162
|
const provider = await this.getProvider()
|
|
112
|
-
|
|
163
|
+
const chainId = await provider.request<number>({
|
|
164
|
+
method: 'eth_chainId',
|
|
165
|
+
})
|
|
166
|
+
return Number(chainId)
|
|
113
167
|
},
|
|
114
168
|
async getProvider() {
|
|
115
169
|
if (!walletProvider) {
|
|
116
|
-
|
|
170
|
+
// Unwrap import
|
|
171
|
+
const { default: SDK_ } = await import('@coinbase/wallet-sdk')
|
|
172
|
+
let SDK: typeof SDK_.default
|
|
173
|
+
if (typeof SDK_ !== 'function' && typeof SDK_.default === 'function')
|
|
174
|
+
SDK = SDK_.default
|
|
175
|
+
else SDK = SDK_ as unknown as typeof SDK_.default
|
|
176
|
+
sdk = new SDK({
|
|
177
|
+
...parameters,
|
|
178
|
+
appChainIds: config.chains.map((x) => x.id),
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
walletProvider = sdk.makeWeb3Provider({
|
|
182
|
+
...parameters,
|
|
183
|
+
options: parameters.preference ?? 'all',
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return walletProvider
|
|
188
|
+
},
|
|
189
|
+
async isAuthorized() {
|
|
190
|
+
try {
|
|
191
|
+
const accounts = await this.getAccounts()
|
|
192
|
+
return !!accounts.length
|
|
193
|
+
} catch {
|
|
194
|
+
return false
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
async switchChain({ addEthereumChainParameter, chainId }) {
|
|
198
|
+
const chain = config.chains.find((chain) => chain.id === chainId)
|
|
199
|
+
if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
|
|
200
|
+
|
|
201
|
+
const provider = await this.getProvider()
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
await provider.request({
|
|
205
|
+
method: 'wallet_switchEthereumChain',
|
|
206
|
+
params: [{ chainId: numberToHex(chain.id) }],
|
|
207
|
+
})
|
|
208
|
+
return chain
|
|
209
|
+
} catch (error) {
|
|
210
|
+
// Indicates chain is not added to provider
|
|
211
|
+
if ((error as ProviderRpcError).code === 4902) {
|
|
212
|
+
try {
|
|
213
|
+
let blockExplorerUrls
|
|
214
|
+
if (addEthereumChainParameter?.blockExplorerUrls)
|
|
215
|
+
blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls
|
|
216
|
+
else
|
|
217
|
+
blockExplorerUrls = chain.blockExplorers?.default.url
|
|
218
|
+
? [chain.blockExplorers?.default.url]
|
|
219
|
+
: []
|
|
220
|
+
|
|
221
|
+
let rpcUrls
|
|
222
|
+
if (addEthereumChainParameter?.rpcUrls?.length)
|
|
223
|
+
rpcUrls = addEthereumChainParameter.rpcUrls
|
|
224
|
+
else rpcUrls = [chain.rpcUrls.default?.http[0] ?? '']
|
|
225
|
+
|
|
226
|
+
const addEthereumChain = {
|
|
227
|
+
blockExplorerUrls,
|
|
228
|
+
chainId: numberToHex(chainId),
|
|
229
|
+
chainName: addEthereumChainParameter?.chainName ?? chain.name,
|
|
230
|
+
iconUrls: addEthereumChainParameter?.iconUrls,
|
|
231
|
+
nativeCurrency:
|
|
232
|
+
addEthereumChainParameter?.nativeCurrency ??
|
|
233
|
+
chain.nativeCurrency,
|
|
234
|
+
rpcUrls,
|
|
235
|
+
} satisfies AddEthereumChainParameter
|
|
236
|
+
|
|
237
|
+
await provider.request({
|
|
238
|
+
method: 'wallet_addEthereumChain',
|
|
239
|
+
params: [addEthereumChain],
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
return chain
|
|
243
|
+
} catch (error) {
|
|
244
|
+
throw new UserRejectedRequestError(error as Error)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
throw new SwitchChainError(error as Error)
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
onAccountsChanged(accounts) {
|
|
252
|
+
if (accounts.length === 0) this.onDisconnect()
|
|
253
|
+
else
|
|
254
|
+
config.emitter.emit('change', {
|
|
255
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
256
|
+
})
|
|
257
|
+
},
|
|
258
|
+
onChainChanged(chain) {
|
|
259
|
+
const chainId = Number(chain)
|
|
260
|
+
config.emitter.emit('change', { chainId })
|
|
261
|
+
},
|
|
262
|
+
async onDisconnect(_error) {
|
|
263
|
+
config.emitter.emit('disconnect')
|
|
264
|
+
|
|
265
|
+
const provider = await this.getProvider()
|
|
266
|
+
if (accountsChanged) {
|
|
267
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
268
|
+
accountsChanged = undefined
|
|
269
|
+
}
|
|
270
|
+
if (chainChanged) {
|
|
271
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
272
|
+
chainChanged = undefined
|
|
273
|
+
}
|
|
274
|
+
if (disconnect) {
|
|
275
|
+
provider.removeListener('disconnect', disconnect)
|
|
276
|
+
disconnect = undefined
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
}))
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
type Version3Parameters = Mutable<
|
|
283
|
+
Omit<
|
|
284
|
+
ConstructorParameters<typeof CBW_SDK>[0],
|
|
285
|
+
'reloadOnDisconnect' // remove property since TSDoc says default is `true`
|
|
286
|
+
>
|
|
287
|
+
> & {
|
|
288
|
+
/**
|
|
289
|
+
* Fallback Ethereum JSON RPC URL
|
|
290
|
+
* @default ""
|
|
291
|
+
*/
|
|
292
|
+
jsonRpcUrl?: string | undefined
|
|
293
|
+
/**
|
|
294
|
+
* Fallback Ethereum Chain ID
|
|
295
|
+
* @default 1
|
|
296
|
+
*/
|
|
297
|
+
chainId?: number | undefined
|
|
298
|
+
/**
|
|
299
|
+
* Whether or not to reload dapp automatically after disconnect.
|
|
300
|
+
* @default false
|
|
301
|
+
*/
|
|
302
|
+
reloadOnDisconnect?: boolean | undefined
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function version3(parameters: Version3Parameters) {
|
|
306
|
+
const reloadOnDisconnect = false
|
|
307
|
+
|
|
308
|
+
type Provider = CBW_Provider
|
|
309
|
+
type Properties = {}
|
|
310
|
+
|
|
311
|
+
let sdk: CBW_SDK | undefined
|
|
312
|
+
let walletProvider: Provider | undefined
|
|
313
|
+
|
|
314
|
+
let accountsChanged: Connector['onAccountsChanged'] | undefined
|
|
315
|
+
let chainChanged: Connector['onChainChanged'] | undefined
|
|
316
|
+
let disconnect: Connector['onDisconnect'] | undefined
|
|
317
|
+
|
|
318
|
+
return createConnector<Provider, Properties>((config) => ({
|
|
319
|
+
id: 'coinbaseWalletSDK',
|
|
320
|
+
name: 'Coinbase Wallet',
|
|
321
|
+
supportsSimulation: true,
|
|
322
|
+
type: coinbaseWallet.type,
|
|
323
|
+
async connect({ chainId } = {}) {
|
|
324
|
+
try {
|
|
325
|
+
const provider = await this.getProvider()
|
|
326
|
+
const accounts = (
|
|
327
|
+
(await provider.request({
|
|
328
|
+
method: 'eth_requestAccounts',
|
|
329
|
+
})) as string[]
|
|
330
|
+
).map((x) => getAddress(x))
|
|
117
331
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
332
|
+
if (!accountsChanged) {
|
|
333
|
+
accountsChanged = this.onAccountsChanged.bind(this)
|
|
334
|
+
provider.on('accountsChanged', accountsChanged)
|
|
335
|
+
}
|
|
336
|
+
if (!chainChanged) {
|
|
337
|
+
chainChanged = this.onChainChanged.bind(this)
|
|
338
|
+
provider.on('chainChanged', chainChanged)
|
|
122
339
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
340
|
+
if (!disconnect) {
|
|
341
|
+
disconnect = this.onDisconnect.bind(this)
|
|
342
|
+
provider.on('disconnect', disconnect)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Switch to chain if provided
|
|
346
|
+
let currentChainId = await this.getChainId()
|
|
347
|
+
if (chainId && currentChainId !== chainId) {
|
|
348
|
+
const chain = await this.switchChain!({ chainId }).catch((error) => {
|
|
349
|
+
if (error.code === UserRejectedRequestError.code) throw error
|
|
350
|
+
return { id: currentChainId }
|
|
351
|
+
})
|
|
352
|
+
currentChainId = chain?.id ?? currentChainId
|
|
126
353
|
}
|
|
354
|
+
|
|
355
|
+
return { accounts, chainId: currentChainId }
|
|
356
|
+
} catch (error) {
|
|
357
|
+
if (
|
|
358
|
+
/(user closed modal|accounts received is empty|user denied account)/i.test(
|
|
359
|
+
(error as Error).message,
|
|
360
|
+
)
|
|
361
|
+
)
|
|
362
|
+
throw new UserRejectedRequestError(error as Error)
|
|
363
|
+
throw error
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
async disconnect() {
|
|
367
|
+
const provider = await this.getProvider()
|
|
368
|
+
|
|
369
|
+
if (accountsChanged) {
|
|
370
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
371
|
+
accountsChanged = undefined
|
|
372
|
+
}
|
|
373
|
+
if (chainChanged) {
|
|
374
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
375
|
+
chainChanged = undefined
|
|
376
|
+
}
|
|
377
|
+
if (disconnect) {
|
|
378
|
+
provider.removeListener('disconnect', disconnect)
|
|
379
|
+
disconnect = undefined
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
provider.disconnect()
|
|
383
|
+
provider.close()
|
|
384
|
+
},
|
|
385
|
+
async getAccounts() {
|
|
386
|
+
const provider = await this.getProvider()
|
|
387
|
+
return (
|
|
388
|
+
await provider.request<string[]>({
|
|
389
|
+
method: 'eth_accounts',
|
|
390
|
+
})
|
|
391
|
+
).map((x) => getAddress(x))
|
|
392
|
+
},
|
|
393
|
+
async getChainId() {
|
|
394
|
+
const provider = await this.getProvider()
|
|
395
|
+
const chainId = await provider.request<number>({ method: 'eth_chainId' })
|
|
396
|
+
return Number(chainId)
|
|
397
|
+
},
|
|
398
|
+
async getProvider() {
|
|
399
|
+
if (!walletProvider) {
|
|
400
|
+
const { default: SDK_ } = await import('cbw-sdk')
|
|
401
|
+
let SDK: typeof SDK_.default
|
|
402
|
+
if (typeof SDK_ !== 'function' && typeof SDK_.default === 'function')
|
|
403
|
+
SDK = SDK_.default
|
|
404
|
+
else SDK = SDK_ as unknown as typeof SDK_.default
|
|
405
|
+
sdk = new SDK({ reloadOnDisconnect, ...parameters })
|
|
406
|
+
|
|
407
|
+
// Force types to retrieve private `walletExtension` method from the Coinbase Wallet SDK.
|
|
127
408
|
const walletExtensionChainId = (
|
|
128
|
-
sdk as unknown as
|
|
409
|
+
sdk as unknown as {
|
|
410
|
+
get walletExtension(): { getChainId(): number } | undefined
|
|
411
|
+
}
|
|
129
412
|
).walletExtension?.getChainId()
|
|
130
413
|
|
|
131
414
|
const chain =
|
|
@@ -140,6 +423,7 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
140
423
|
|
|
141
424
|
walletProvider = sdk.makeWeb3Provider(jsonRpcUrl, chainId)
|
|
142
425
|
}
|
|
426
|
+
|
|
143
427
|
return walletProvider
|
|
144
428
|
},
|
|
145
429
|
async isAuthorized() {
|
|
@@ -150,35 +434,51 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
150
434
|
return false
|
|
151
435
|
}
|
|
152
436
|
},
|
|
153
|
-
async switchChain({ chainId }) {
|
|
437
|
+
async switchChain({ addEthereumChainParameter, chainId }) {
|
|
154
438
|
const chain = config.chains.find((chain) => chain.id === chainId)
|
|
155
439
|
if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
|
|
156
440
|
|
|
157
441
|
const provider = await this.getProvider()
|
|
158
|
-
const chainId_ = numberToHex(chain.id)
|
|
159
442
|
|
|
160
443
|
try {
|
|
161
444
|
await provider.request({
|
|
162
445
|
method: 'wallet_switchEthereumChain',
|
|
163
|
-
params: [{ chainId:
|
|
446
|
+
params: [{ chainId: numberToHex(chain.id) }],
|
|
164
447
|
})
|
|
165
448
|
return chain
|
|
166
449
|
} catch (error) {
|
|
167
450
|
// Indicates chain is not added to provider
|
|
168
451
|
if ((error as ProviderRpcError).code === 4902) {
|
|
169
452
|
try {
|
|
453
|
+
let blockExplorerUrls
|
|
454
|
+
if (addEthereumChainParameter?.blockExplorerUrls)
|
|
455
|
+
blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls
|
|
456
|
+
else
|
|
457
|
+
blockExplorerUrls = chain.blockExplorers?.default.url
|
|
458
|
+
? [chain.blockExplorers?.default.url]
|
|
459
|
+
: []
|
|
460
|
+
|
|
461
|
+
let rpcUrls
|
|
462
|
+
if (addEthereumChainParameter?.rpcUrls?.length)
|
|
463
|
+
rpcUrls = addEthereumChainParameter.rpcUrls
|
|
464
|
+
else rpcUrls = [chain.rpcUrls.default?.http[0] ?? '']
|
|
465
|
+
|
|
466
|
+
const addEthereumChain = {
|
|
467
|
+
blockExplorerUrls,
|
|
468
|
+
chainId: numberToHex(chainId),
|
|
469
|
+
chainName: addEthereumChainParameter?.chainName ?? chain.name,
|
|
470
|
+
iconUrls: addEthereumChainParameter?.iconUrls,
|
|
471
|
+
nativeCurrency:
|
|
472
|
+
addEthereumChainParameter?.nativeCurrency ??
|
|
473
|
+
chain.nativeCurrency,
|
|
474
|
+
rpcUrls,
|
|
475
|
+
} satisfies AddEthereumChainParameter
|
|
476
|
+
|
|
170
477
|
await provider.request({
|
|
171
478
|
method: 'wallet_addEthereumChain',
|
|
172
|
-
params: [
|
|
173
|
-
{
|
|
174
|
-
chainId: chainId_,
|
|
175
|
-
chainName: chain.name,
|
|
176
|
-
nativeCurrency: chain.nativeCurrency,
|
|
177
|
-
rpcUrls: [chain.rpcUrls.default?.http[0] ?? ''],
|
|
178
|
-
blockExplorerUrls: [chain.blockExplorers?.default.url],
|
|
179
|
-
},
|
|
180
|
-
],
|
|
479
|
+
params: [addEthereumChain],
|
|
181
480
|
})
|
|
481
|
+
|
|
182
482
|
return chain
|
|
183
483
|
} catch (error) {
|
|
184
484
|
throw new UserRejectedRequestError(error as Error)
|
|
@@ -189,20 +489,32 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
189
489
|
}
|
|
190
490
|
},
|
|
191
491
|
onAccountsChanged(accounts) {
|
|
192
|
-
if (accounts.length === 0)
|
|
193
|
-
else
|
|
492
|
+
if (accounts.length === 0) this.onDisconnect()
|
|
493
|
+
else
|
|
494
|
+
config.emitter.emit('change', {
|
|
495
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
496
|
+
})
|
|
194
497
|
},
|
|
195
498
|
onChainChanged(chain) {
|
|
196
|
-
const chainId =
|
|
499
|
+
const chainId = Number(chain)
|
|
197
500
|
config.emitter.emit('change', { chainId })
|
|
198
501
|
},
|
|
199
502
|
async onDisconnect(_error) {
|
|
200
503
|
config.emitter.emit('disconnect')
|
|
201
504
|
|
|
202
505
|
const provider = await this.getProvider()
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
506
|
+
if (accountsChanged) {
|
|
507
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
508
|
+
accountsChanged = undefined
|
|
509
|
+
}
|
|
510
|
+
if (chainChanged) {
|
|
511
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
512
|
+
chainChanged = undefined
|
|
513
|
+
}
|
|
514
|
+
if (disconnect) {
|
|
515
|
+
provider.removeListener('disconnect', disconnect)
|
|
516
|
+
disconnect = undefined
|
|
517
|
+
}
|
|
206
518
|
},
|
|
207
519
|
}))
|
|
208
520
|
}
|