@wagmi/connectors 5.0.0 → 5.0.2
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 +276 -36
- package/dist/esm/coinbaseWallet.js.map +1 -1
- package/dist/esm/metaMask.js +75 -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 +384 -66
- package/src/metaMask.ts +92 -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
|
|
64
|
+
* Preference for the type of wallet to display.
|
|
65
|
+
* @default 'all'
|
|
29
66
|
*/
|
|
30
|
-
|
|
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
|
|
39
|
-
*/
|
|
40
|
-
reloadOnDisconnect?: boolean | undefined
|
|
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,265 @@ 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
|
+
// Unwrapping import for Vite compatibility.
|
|
171
|
+
// See: https://github.com/vitejs/vite/issues/9703
|
|
172
|
+
const { default: CoinbaseSDK_ } = await import('@coinbase/wallet-sdk')
|
|
173
|
+
const CoinbaseSDK = (() => {
|
|
174
|
+
if (
|
|
175
|
+
typeof CoinbaseSDK_ !== 'function' &&
|
|
176
|
+
typeof CoinbaseSDK_.default === 'function'
|
|
177
|
+
)
|
|
178
|
+
return CoinbaseSDK_.default
|
|
179
|
+
return CoinbaseSDK_ as unknown as typeof CoinbaseSDK_.default
|
|
180
|
+
})()
|
|
181
|
+
|
|
182
|
+
sdk = new CoinbaseSDK({
|
|
183
|
+
...parameters,
|
|
184
|
+
appChainIds: config.chains.map((x) => x.id),
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
walletProvider = sdk.makeWeb3Provider({
|
|
188
|
+
...parameters,
|
|
189
|
+
options: parameters.preference ?? 'all',
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return walletProvider
|
|
194
|
+
},
|
|
195
|
+
async isAuthorized() {
|
|
196
|
+
try {
|
|
197
|
+
const accounts = await this.getAccounts()
|
|
198
|
+
return !!accounts.length
|
|
199
|
+
} catch {
|
|
200
|
+
return false
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
async switchChain({ addEthereumChainParameter, chainId }) {
|
|
204
|
+
const chain = config.chains.find((chain) => chain.id === chainId)
|
|
205
|
+
if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
|
|
206
|
+
|
|
207
|
+
const provider = await this.getProvider()
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
await provider.request({
|
|
211
|
+
method: 'wallet_switchEthereumChain',
|
|
212
|
+
params: [{ chainId: numberToHex(chain.id) }],
|
|
213
|
+
})
|
|
214
|
+
return chain
|
|
215
|
+
} catch (error) {
|
|
216
|
+
// Indicates chain is not added to provider
|
|
217
|
+
if ((error as ProviderRpcError).code === 4902) {
|
|
218
|
+
try {
|
|
219
|
+
let blockExplorerUrls
|
|
220
|
+
if (addEthereumChainParameter?.blockExplorerUrls)
|
|
221
|
+
blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls
|
|
222
|
+
else
|
|
223
|
+
blockExplorerUrls = chain.blockExplorers?.default.url
|
|
224
|
+
? [chain.blockExplorers?.default.url]
|
|
225
|
+
: []
|
|
226
|
+
|
|
227
|
+
let rpcUrls
|
|
228
|
+
if (addEthereumChainParameter?.rpcUrls?.length)
|
|
229
|
+
rpcUrls = addEthereumChainParameter.rpcUrls
|
|
230
|
+
else rpcUrls = [chain.rpcUrls.default?.http[0] ?? '']
|
|
231
|
+
|
|
232
|
+
const addEthereumChain = {
|
|
233
|
+
blockExplorerUrls,
|
|
234
|
+
chainId: numberToHex(chainId),
|
|
235
|
+
chainName: addEthereumChainParameter?.chainName ?? chain.name,
|
|
236
|
+
iconUrls: addEthereumChainParameter?.iconUrls,
|
|
237
|
+
nativeCurrency:
|
|
238
|
+
addEthereumChainParameter?.nativeCurrency ??
|
|
239
|
+
chain.nativeCurrency,
|
|
240
|
+
rpcUrls,
|
|
241
|
+
} satisfies AddEthereumChainParameter
|
|
242
|
+
|
|
243
|
+
await provider.request({
|
|
244
|
+
method: 'wallet_addEthereumChain',
|
|
245
|
+
params: [addEthereumChain],
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
return chain
|
|
249
|
+
} catch (error) {
|
|
250
|
+
throw new UserRejectedRequestError(error as Error)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
throw new SwitchChainError(error as Error)
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
onAccountsChanged(accounts) {
|
|
258
|
+
if (accounts.length === 0) this.onDisconnect()
|
|
259
|
+
else
|
|
260
|
+
config.emitter.emit('change', {
|
|
261
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
262
|
+
})
|
|
263
|
+
},
|
|
264
|
+
onChainChanged(chain) {
|
|
265
|
+
const chainId = Number(chain)
|
|
266
|
+
config.emitter.emit('change', { chainId })
|
|
267
|
+
},
|
|
268
|
+
async onDisconnect(_error) {
|
|
269
|
+
config.emitter.emit('disconnect')
|
|
270
|
+
|
|
271
|
+
const provider = await this.getProvider()
|
|
272
|
+
if (accountsChanged) {
|
|
273
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
274
|
+
accountsChanged = undefined
|
|
275
|
+
}
|
|
276
|
+
if (chainChanged) {
|
|
277
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
278
|
+
chainChanged = undefined
|
|
279
|
+
}
|
|
280
|
+
if (disconnect) {
|
|
281
|
+
provider.removeListener('disconnect', disconnect)
|
|
282
|
+
disconnect = undefined
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
}))
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
type Version3Parameters = Mutable<
|
|
289
|
+
Omit<
|
|
290
|
+
ConstructorParameters<typeof CBW_SDK>[0],
|
|
291
|
+
'reloadOnDisconnect' // remove property since TSDoc says default is `true`
|
|
292
|
+
>
|
|
293
|
+
> & {
|
|
294
|
+
/**
|
|
295
|
+
* Fallback Ethereum JSON RPC URL
|
|
296
|
+
* @default ""
|
|
297
|
+
*/
|
|
298
|
+
jsonRpcUrl?: string | undefined
|
|
299
|
+
/**
|
|
300
|
+
* Fallback Ethereum Chain ID
|
|
301
|
+
* @default 1
|
|
302
|
+
*/
|
|
303
|
+
chainId?: number | undefined
|
|
304
|
+
/**
|
|
305
|
+
* Whether or not to reload dapp automatically after disconnect.
|
|
306
|
+
* @default false
|
|
307
|
+
*/
|
|
308
|
+
reloadOnDisconnect?: boolean | undefined
|
|
309
|
+
}
|
|
117
310
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
311
|
+
function version3(parameters: Version3Parameters) {
|
|
312
|
+
const reloadOnDisconnect = false
|
|
313
|
+
|
|
314
|
+
type Provider = CBW_Provider
|
|
315
|
+
type Properties = {}
|
|
316
|
+
|
|
317
|
+
let sdk: CBW_SDK | undefined
|
|
318
|
+
let walletProvider: Provider | undefined
|
|
319
|
+
|
|
320
|
+
let accountsChanged: Connector['onAccountsChanged'] | undefined
|
|
321
|
+
let chainChanged: Connector['onChainChanged'] | undefined
|
|
322
|
+
let disconnect: Connector['onDisconnect'] | undefined
|
|
323
|
+
|
|
324
|
+
return createConnector<Provider, Properties>((config) => ({
|
|
325
|
+
id: 'coinbaseWalletSDK',
|
|
326
|
+
name: 'Coinbase Wallet',
|
|
327
|
+
supportsSimulation: true,
|
|
328
|
+
type: coinbaseWallet.type,
|
|
329
|
+
async connect({ chainId } = {}) {
|
|
330
|
+
try {
|
|
331
|
+
const provider = await this.getProvider()
|
|
332
|
+
const accounts = (
|
|
333
|
+
(await provider.request({
|
|
334
|
+
method: 'eth_requestAccounts',
|
|
335
|
+
})) as string[]
|
|
336
|
+
).map((x) => getAddress(x))
|
|
337
|
+
|
|
338
|
+
if (!accountsChanged) {
|
|
339
|
+
accountsChanged = this.onAccountsChanged.bind(this)
|
|
340
|
+
provider.on('accountsChanged', accountsChanged)
|
|
341
|
+
}
|
|
342
|
+
if (!chainChanged) {
|
|
343
|
+
chainChanged = this.onChainChanged.bind(this)
|
|
344
|
+
provider.on('chainChanged', chainChanged)
|
|
122
345
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
346
|
+
if (!disconnect) {
|
|
347
|
+
disconnect = this.onDisconnect.bind(this)
|
|
348
|
+
provider.on('disconnect', disconnect)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Switch to chain if provided
|
|
352
|
+
let currentChainId = await this.getChainId()
|
|
353
|
+
if (chainId && currentChainId !== chainId) {
|
|
354
|
+
const chain = await this.switchChain!({ chainId }).catch((error) => {
|
|
355
|
+
if (error.code === UserRejectedRequestError.code) throw error
|
|
356
|
+
return { id: currentChainId }
|
|
357
|
+
})
|
|
358
|
+
currentChainId = chain?.id ?? currentChainId
|
|
126
359
|
}
|
|
360
|
+
|
|
361
|
+
return { accounts, chainId: currentChainId }
|
|
362
|
+
} catch (error) {
|
|
363
|
+
if (
|
|
364
|
+
/(user closed modal|accounts received is empty|user denied account)/i.test(
|
|
365
|
+
(error as Error).message,
|
|
366
|
+
)
|
|
367
|
+
)
|
|
368
|
+
throw new UserRejectedRequestError(error as Error)
|
|
369
|
+
throw error
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
async disconnect() {
|
|
373
|
+
const provider = await this.getProvider()
|
|
374
|
+
|
|
375
|
+
if (accountsChanged) {
|
|
376
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
377
|
+
accountsChanged = undefined
|
|
378
|
+
}
|
|
379
|
+
if (chainChanged) {
|
|
380
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
381
|
+
chainChanged = undefined
|
|
382
|
+
}
|
|
383
|
+
if (disconnect) {
|
|
384
|
+
provider.removeListener('disconnect', disconnect)
|
|
385
|
+
disconnect = undefined
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
provider.disconnect()
|
|
389
|
+
provider.close()
|
|
390
|
+
},
|
|
391
|
+
async getAccounts() {
|
|
392
|
+
const provider = await this.getProvider()
|
|
393
|
+
return (
|
|
394
|
+
await provider.request<string[]>({
|
|
395
|
+
method: 'eth_accounts',
|
|
396
|
+
})
|
|
397
|
+
).map((x) => getAddress(x))
|
|
398
|
+
},
|
|
399
|
+
async getChainId() {
|
|
400
|
+
const provider = await this.getProvider()
|
|
401
|
+
const chainId = await provider.request<number>({ method: 'eth_chainId' })
|
|
402
|
+
return Number(chainId)
|
|
403
|
+
},
|
|
404
|
+
async getProvider() {
|
|
405
|
+
if (!walletProvider) {
|
|
406
|
+
const { default: SDK_ } = await import('cbw-sdk')
|
|
407
|
+
let SDK: typeof SDK_.default
|
|
408
|
+
if (typeof SDK_ !== 'function' && typeof SDK_.default === 'function')
|
|
409
|
+
SDK = SDK_.default
|
|
410
|
+
else SDK = SDK_ as unknown as typeof SDK_.default
|
|
411
|
+
sdk = new SDK({ reloadOnDisconnect, ...parameters })
|
|
412
|
+
|
|
413
|
+
// Force types to retrieve private `walletExtension` method from the Coinbase Wallet SDK.
|
|
127
414
|
const walletExtensionChainId = (
|
|
128
|
-
sdk as unknown as
|
|
415
|
+
sdk as unknown as {
|
|
416
|
+
get walletExtension(): { getChainId(): number } | undefined
|
|
417
|
+
}
|
|
129
418
|
).walletExtension?.getChainId()
|
|
130
419
|
|
|
131
420
|
const chain =
|
|
@@ -140,6 +429,7 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
140
429
|
|
|
141
430
|
walletProvider = sdk.makeWeb3Provider(jsonRpcUrl, chainId)
|
|
142
431
|
}
|
|
432
|
+
|
|
143
433
|
return walletProvider
|
|
144
434
|
},
|
|
145
435
|
async isAuthorized() {
|
|
@@ -150,35 +440,51 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
150
440
|
return false
|
|
151
441
|
}
|
|
152
442
|
},
|
|
153
|
-
async switchChain({ chainId }) {
|
|
443
|
+
async switchChain({ addEthereumChainParameter, chainId }) {
|
|
154
444
|
const chain = config.chains.find((chain) => chain.id === chainId)
|
|
155
445
|
if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
|
|
156
446
|
|
|
157
447
|
const provider = await this.getProvider()
|
|
158
|
-
const chainId_ = numberToHex(chain.id)
|
|
159
448
|
|
|
160
449
|
try {
|
|
161
450
|
await provider.request({
|
|
162
451
|
method: 'wallet_switchEthereumChain',
|
|
163
|
-
params: [{ chainId:
|
|
452
|
+
params: [{ chainId: numberToHex(chain.id) }],
|
|
164
453
|
})
|
|
165
454
|
return chain
|
|
166
455
|
} catch (error) {
|
|
167
456
|
// Indicates chain is not added to provider
|
|
168
457
|
if ((error as ProviderRpcError).code === 4902) {
|
|
169
458
|
try {
|
|
459
|
+
let blockExplorerUrls
|
|
460
|
+
if (addEthereumChainParameter?.blockExplorerUrls)
|
|
461
|
+
blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls
|
|
462
|
+
else
|
|
463
|
+
blockExplorerUrls = chain.blockExplorers?.default.url
|
|
464
|
+
? [chain.blockExplorers?.default.url]
|
|
465
|
+
: []
|
|
466
|
+
|
|
467
|
+
let rpcUrls
|
|
468
|
+
if (addEthereumChainParameter?.rpcUrls?.length)
|
|
469
|
+
rpcUrls = addEthereumChainParameter.rpcUrls
|
|
470
|
+
else rpcUrls = [chain.rpcUrls.default?.http[0] ?? '']
|
|
471
|
+
|
|
472
|
+
const addEthereumChain = {
|
|
473
|
+
blockExplorerUrls,
|
|
474
|
+
chainId: numberToHex(chainId),
|
|
475
|
+
chainName: addEthereumChainParameter?.chainName ?? chain.name,
|
|
476
|
+
iconUrls: addEthereumChainParameter?.iconUrls,
|
|
477
|
+
nativeCurrency:
|
|
478
|
+
addEthereumChainParameter?.nativeCurrency ??
|
|
479
|
+
chain.nativeCurrency,
|
|
480
|
+
rpcUrls,
|
|
481
|
+
} satisfies AddEthereumChainParameter
|
|
482
|
+
|
|
170
483
|
await provider.request({
|
|
171
484
|
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
|
-
],
|
|
485
|
+
params: [addEthereumChain],
|
|
181
486
|
})
|
|
487
|
+
|
|
182
488
|
return chain
|
|
183
489
|
} catch (error) {
|
|
184
490
|
throw new UserRejectedRequestError(error as Error)
|
|
@@ -189,20 +495,32 @@ export function coinbaseWallet(parameters: CoinbaseWalletParameters) {
|
|
|
189
495
|
}
|
|
190
496
|
},
|
|
191
497
|
onAccountsChanged(accounts) {
|
|
192
|
-
if (accounts.length === 0)
|
|
193
|
-
else
|
|
498
|
+
if (accounts.length === 0) this.onDisconnect()
|
|
499
|
+
else
|
|
500
|
+
config.emitter.emit('change', {
|
|
501
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
502
|
+
})
|
|
194
503
|
},
|
|
195
504
|
onChainChanged(chain) {
|
|
196
|
-
const chainId =
|
|
505
|
+
const chainId = Number(chain)
|
|
197
506
|
config.emitter.emit('change', { chainId })
|
|
198
507
|
},
|
|
199
508
|
async onDisconnect(_error) {
|
|
200
509
|
config.emitter.emit('disconnect')
|
|
201
510
|
|
|
202
511
|
const provider = await this.getProvider()
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
512
|
+
if (accountsChanged) {
|
|
513
|
+
provider.removeListener('accountsChanged', accountsChanged)
|
|
514
|
+
accountsChanged = undefined
|
|
515
|
+
}
|
|
516
|
+
if (chainChanged) {
|
|
517
|
+
provider.removeListener('chainChanged', chainChanged)
|
|
518
|
+
chainChanged = undefined
|
|
519
|
+
}
|
|
520
|
+
if (disconnect) {
|
|
521
|
+
provider.removeListener('disconnect', disconnect)
|
|
522
|
+
disconnect = undefined
|
|
523
|
+
}
|
|
206
524
|
},
|
|
207
525
|
}))
|
|
208
526
|
}
|